yoti_sandbox 1.0.0 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +1 -1
  3. data/README.md +8 -1
  4. data/lib/yoti_sandbox.rb +1 -0
  5. data/lib/yoti_sandbox/doc_scan.rb +25 -0
  6. data/lib/yoti_sandbox/doc_scan/client.rb +59 -0
  7. data/lib/yoti_sandbox/doc_scan/errors.rb +83 -0
  8. data/lib/yoti_sandbox/doc_scan/request/check/check.rb +115 -0
  9. data/lib/yoti_sandbox/doc_scan/request/check/document_authenticity_check.rb +29 -0
  10. data/lib/yoti_sandbox/doc_scan/request/check/document_check.rb +48 -0
  11. data/lib/yoti_sandbox/doc_scan/request/check/document_face_match_check.rb +29 -0
  12. data/lib/yoti_sandbox/doc_scan/request/check/document_text_data_check.rb +78 -0
  13. data/lib/yoti_sandbox/doc_scan/request/check/id_document_comparison_check.rb +56 -0
  14. data/lib/yoti_sandbox/doc_scan/request/check/liveness_check.rb +34 -0
  15. data/lib/yoti_sandbox/doc_scan/request/check/report/breakdown.rb +97 -0
  16. data/lib/yoti_sandbox/doc_scan/request/check/report/detail.rb +34 -0
  17. data/lib/yoti_sandbox/doc_scan/request/check/report/recommendation.rb +88 -0
  18. data/lib/yoti_sandbox/doc_scan/request/check/supplementary_document_text_data_check.rb +78 -0
  19. data/lib/yoti_sandbox/doc_scan/request/check/zoom_liveness_check.rb +36 -0
  20. data/lib/yoti_sandbox/doc_scan/request/check_reports.rb +182 -0
  21. data/lib/yoti_sandbox/doc_scan/request/document_filter.rb +77 -0
  22. data/lib/yoti_sandbox/doc_scan/request/response_config.rb +75 -0
  23. data/lib/yoti_sandbox/doc_scan/request/task/document_id_photo.rb +35 -0
  24. data/lib/yoti_sandbox/doc_scan/request/task/document_text_data_extraction_task.rb +170 -0
  25. data/lib/yoti_sandbox/doc_scan/request/task/supplementary_document_text_data_extraction_task.rb +152 -0
  26. data/lib/yoti_sandbox/doc_scan/request/task/text_data_extraction_reason.rb +78 -0
  27. data/lib/yoti_sandbox/doc_scan/request/task/text_data_extraction_recommendation.rb +86 -0
  28. data/lib/yoti_sandbox/doc_scan/request/task_results.rb +96 -0
  29. data/lib/yoti_sandbox/profile.rb +5 -0
  30. data/lib/yoti_sandbox/profile/age_verification.rb +7 -0
  31. data/lib/yoti_sandbox/profile/client.rb +8 -26
  32. data/lib/yoti_sandbox/profile/document_images.rb +69 -0
  33. data/lib/yoti_sandbox/profile/extra_data.rb +92 -0
  34. data/lib/yoti_sandbox/profile/third_party.rb +158 -0
  35. data/lib/yoti_sandbox/profile/token_request.rb +47 -6
  36. data/yoti_sandbox.gemspec +18 -5
  37. metadata +38 -18
  38. data/.github/ISSUE_TEMPLATE.md +0 -17
  39. data/.gitignore +0 -56
  40. data/CONTRIBUTING.md +0 -30
  41. data/Guardfile +0 -11
  42. data/Rakefile +0 -41
  43. data/rubocop.yml +0 -44
  44. data/yardstick.yml +0 -9
@@ -0,0 +1,78 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'json'
4
+
5
+ module Yoti
6
+ module Sandbox
7
+ module DocScan
8
+ module Request
9
+ class TextDataExtractionReason
10
+ #
11
+ # @param [String] value
12
+ # @param [String] detail
13
+ #
14
+ def initialize(value, detail)
15
+ Validation.assert_is_a(String, value, 'value')
16
+ @value = value
17
+
18
+ Validation.assert_is_a(String, detail, 'detail', true)
19
+ @detail = detail
20
+ end
21
+
22
+ def to_json(*_args)
23
+ as_json.to_json
24
+ end
25
+
26
+ def as_json(*_args)
27
+ {
28
+ value: @value,
29
+ detail: @detail
30
+ }.compact
31
+ end
32
+
33
+ #
34
+ # @return [TextDataExtractionReasonBuilder]
35
+ #
36
+ def self.builder
37
+ TextDataExtractionReasonBuilder.new
38
+ end
39
+ end
40
+
41
+ class TextDataExtractionReasonBuilder
42
+ #
43
+ # @return [self]
44
+ #
45
+ def for_quality
46
+ @value = 'QUALITY'
47
+ self
48
+ end
49
+
50
+ #
51
+ # @return [self]
52
+ #
53
+ def for_user_error
54
+ @value = 'USER_ERROR'
55
+ self
56
+ end
57
+
58
+ #
59
+ # @param [String] detail
60
+ #
61
+ # @return [self]
62
+ #
63
+ def with_detail(detail)
64
+ @detail = detail
65
+ self
66
+ end
67
+
68
+ #
69
+ # @return [TextDataExtractionReason]
70
+ #
71
+ def build
72
+ TextDataExtractionReason.new(@value, @detail)
73
+ end
74
+ end
75
+ end
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,86 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'json'
4
+
5
+ module Yoti
6
+ module Sandbox
7
+ module DocScan
8
+ module Request
9
+ class TextDataExtractionRecommendation
10
+ #
11
+ # @param [String] value
12
+ # @param [TextDataExtractionReason] reason
13
+ #
14
+ def initialize(value, reason)
15
+ Validation.assert_is_a(String, value, 'value')
16
+ @value = value
17
+
18
+ Validation.assert_is_a(TextDataExtractionReason, reason, 'reason', true)
19
+ @reason = reason
20
+ end
21
+
22
+ def to_json(*_args)
23
+ as_json.to_json
24
+ end
25
+
26
+ def as_json(*_args)
27
+ {
28
+ value: @value,
29
+ reason: @reason
30
+ }.compact
31
+ end
32
+
33
+ #
34
+ # @return [TextDataExtractionRecommendationBuilder]
35
+ #
36
+ def self.builder
37
+ TextDataExtractionRecommendationBuilder.new
38
+ end
39
+ end
40
+
41
+ class TextDataExtractionRecommendationBuilder
42
+ #
43
+ # @return [self]
44
+ #
45
+ def for_progress
46
+ @value = 'PROGRESS'
47
+ self
48
+ end
49
+
50
+ #
51
+ # @return [self]
52
+ #
53
+ def for_should_try_again
54
+ @value = 'SHOULD_TRY_AGAIN'
55
+ self
56
+ end
57
+
58
+ #
59
+ # @return [self]
60
+ #
61
+ def for_must_try_again
62
+ @value = 'MUST_TRY_AGAIN'
63
+ self
64
+ end
65
+
66
+ #
67
+ # @param [TextDataExtractionReason] reason
68
+ #
69
+ # @return [self]
70
+ #
71
+ def with_reason(reason)
72
+ @reason = reason
73
+ self
74
+ end
75
+
76
+ #
77
+ # @return [TextDataExtractionRecommendation]
78
+ #
79
+ def build
80
+ TextDataExtractionRecommendation.new(@value, @reason)
81
+ end
82
+ end
83
+ end
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,96 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Yoti
4
+ module Sandbox
5
+ module DocScan
6
+ module Request
7
+ class TaskResults
8
+ #
9
+ # @param [Array<DocumentTextDataExtractionTask>] document_text_data_extraction_tasks
10
+ # @param [Array<SupplementaryDocumentTextDataExtractionTask>] supplementary_document_text_data_extraction_tasks
11
+ #
12
+ def initialize(
13
+ document_text_data_extraction_tasks,
14
+ supplementary_document_text_data_extraction_tasks
15
+ )
16
+ Validation.assert_is_a(
17
+ Array,
18
+ document_text_data_extraction_tasks,
19
+ 'document_text_data_extraction_tasks'
20
+ )
21
+ @document_text_data_extraction_tasks = document_text_data_extraction_tasks
22
+
23
+ Validation.assert_is_a(
24
+ Array,
25
+ supplementary_document_text_data_extraction_tasks,
26
+ 'supplementary_document_text_data_extraction_tasks'
27
+ )
28
+ @supplementary_document_text_data_extraction_tasks = supplementary_document_text_data_extraction_tasks
29
+ end
30
+
31
+ def self.builder
32
+ TaskResultsBuilder.new
33
+ end
34
+
35
+ def to_json(*_args)
36
+ as_json.to_json
37
+ end
38
+
39
+ def as_json(*_args)
40
+ {
41
+ ID_DOCUMENT_TEXT_DATA_EXTRACTION: @document_text_data_extraction_tasks,
42
+ SUPPLEMENTARY_DOCUMENT_TEXT_DATA_EXTRACTION: @supplementary_document_text_data_extraction_tasks
43
+ }
44
+ end
45
+ end
46
+
47
+ class TaskResultsBuilder
48
+ def initialize
49
+ @document_text_data_extraction_tasks = []
50
+ @supplementary_document_text_data_extraction_tasks = []
51
+ end
52
+
53
+ #
54
+ # @param [DocumentTextDataExtractionTask] document_text_data_extraction_task
55
+ #
56
+ # @return [self]
57
+ #
58
+ def with_document_text_data_extraction_task(document_text_data_extraction_task)
59
+ Validation.assert_is_a(
60
+ DocumentTextDataExtractionTask,
61
+ document_text_data_extraction_task,
62
+ 'document_text_data_extraction_task'
63
+ )
64
+ @document_text_data_extraction_tasks << document_text_data_extraction_task
65
+ self
66
+ end
67
+
68
+ #
69
+ # @param [SupplementaryDocumentTextDataExtractionTask] supplementary_document_text_data_extraction_task
70
+ #
71
+ # @return [self]
72
+ #
73
+ def with_supplementary_document_text_data_extraction_task(supplementary_document_text_data_extraction_task)
74
+ Validation.assert_is_a(
75
+ SupplementaryDocumentTextDataExtractionTask,
76
+ supplementary_document_text_data_extraction_task,
77
+ 'supplementary_document_text_data_extraction_task'
78
+ )
79
+ @supplementary_document_text_data_extraction_tasks << supplementary_document_text_data_extraction_task
80
+ self
81
+ end
82
+
83
+ #
84
+ # @return [TaskResults]
85
+ #
86
+ def build
87
+ TaskResults.new(
88
+ @document_text_data_extraction_tasks,
89
+ @supplementary_document_text_data_extraction_tasks
90
+ )
91
+ end
92
+ end
93
+ end
94
+ end
95
+ end
96
+ end
@@ -1,5 +1,10 @@
1
+ require 'yoti'
2
+
1
3
  require_relative 'profile/age_verification'
2
4
  require_relative 'profile/anchor'
3
5
  require_relative 'profile/attribute'
4
6
  require_relative 'profile/client'
5
7
  require_relative 'profile/token_request'
8
+ require_relative 'profile/extra_data'
9
+ require_relative 'profile/third_party'
10
+ require_relative 'profile/document_images'
@@ -25,6 +25,13 @@ module Yoti
25
25
  @anchors = anchors
26
26
  end
27
27
 
28
+ #
29
+ # @return [AgeVerificationBuilder]
30
+ #
31
+ def self.builder
32
+ AgeVerificationBuilder.new
33
+ end
34
+
28
35
  #
29
36
  # @return [Attribute]
30
37
  #
@@ -1,8 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'yoti'
4
- require 'securerandom'
5
-
6
3
  module Yoti
7
4
  module Sandbox
8
5
  module Profile
@@ -23,30 +20,15 @@ module Yoti
23
20
  # @return [String]
24
21
  #
25
22
  def setup_sharing_profile(token_request)
26
- endpoint = "/apps/#{Yoti.configuration.client_sdk_id}/tokens?\
27
- nonce=#{SecureRandom.uuid}&timestamp=#{Time.now.to_i}"
28
- uri = URI(
29
- "#{@base_url}#{endpoint}"
30
- )
31
-
32
- response = Net::HTTP.start(
33
- uri.hostname,
34
- uri.port,
35
- use_ssl: true
36
- ) do |http|
37
- unsigned = Net::HTTP::Post.new uri
38
- unsigned.body = token_request.to_json
39
- signed_request = Yoti::SignedRequest.new(
40
- unsigned,
41
- endpoint,
42
- token_request
43
- ).sign
44
- http.request signed_request
45
- end
46
-
47
- raise "Failed to share profile #{response.code}: #{response.body}" unless response.code == '201'
23
+ request = Yoti::Request
24
+ .builder
25
+ .with_base_url(@base_url)
26
+ .with_endpoint("apps/#{Yoti.configuration.client_sdk_id}/tokens")
27
+ .with_http_method('POST')
28
+ .with_payload(token_request)
29
+ .build
48
30
 
49
- JSON.parse(response.body)['token']
31
+ JSON.parse(request.execute.body)['token']
50
32
  end
51
33
  end
52
34
  end
@@ -0,0 +1,69 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Yoti
4
+ module Sandbox
5
+ module Profile
6
+ class DocumentImages
7
+ #
8
+ # @param [Array<Image>] images
9
+ #
10
+ def initialize(images)
11
+ Validation.assert_is_a(Array, images, 'images')
12
+ @images = images
13
+ end
14
+
15
+ #
16
+ # @return [DocumentImagesBuilder]
17
+ #
18
+ def self.builder
19
+ DocumentImagesBuilder.new
20
+ end
21
+
22
+ #
23
+ # @return [String]
24
+ #
25
+ def value
26
+ @images
27
+ .map(&:base64_content)
28
+ .join('&')
29
+ end
30
+ end
31
+
32
+ #
33
+ # Builder for {DocumentImages}
34
+ #
35
+ class DocumentImagesBuilder
36
+ def initialize
37
+ @images = []
38
+ end
39
+
40
+ #
41
+ # @param [bin] content
42
+ #
43
+ # @return [self]
44
+ #
45
+ def with_jpeg_content(content)
46
+ @images << Yoti::ImageJpeg.new(content)
47
+ self
48
+ end
49
+
50
+ #
51
+ # @param [bin] content
52
+ #
53
+ # @return [self]
54
+ #
55
+ def with_png_content(content)
56
+ @images << Yoti::ImagePng.new(content)
57
+ self
58
+ end
59
+
60
+ #
61
+ # @return [DocumentImages]
62
+ #
63
+ def build
64
+ DocumentImages.new(@images)
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,92 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Yoti
4
+ module Sandbox
5
+ module Profile
6
+ class ExtraData
7
+ def initialize(data_entries)
8
+ @data_entries = data_entries
9
+ end
10
+
11
+ #
12
+ # @return [Hash]
13
+ #
14
+ def as_json(*_args)
15
+ {
16
+ data_entry: @data_entries
17
+ }
18
+ end
19
+
20
+ #
21
+ # @return [String]
22
+ #
23
+ def to_json(*args)
24
+ as_json.to_json(*args)
25
+ end
26
+
27
+ #
28
+ # @return [ExtraDataBuilder]
29
+ #
30
+ def self.builder
31
+ ExtraDataBuilder.new
32
+ end
33
+ end
34
+
35
+ #
36
+ # Base DataEntry
37
+ #
38
+ class DataEntry
39
+ #
40
+ # @param [String] type
41
+ # @param [#as_json] value
42
+ #
43
+ def initialize(type, value)
44
+ raise(TypeError, "#{self.class} cannot be instantiated") if instance_of?(DataEntry)
45
+
46
+ Validation.assert_is_a(String, type, 'type')
47
+ @type = type
48
+
49
+ Validation.assert_respond_to(:as_json, value, 'value')
50
+ @value = value
51
+ end
52
+
53
+ def to_json(*_args)
54
+ as_json.to_json
55
+ end
56
+
57
+ def as_json(*_args)
58
+ {
59
+ type: @type,
60
+ value: @value.as_json
61
+ }
62
+ end
63
+ end
64
+
65
+ #
66
+ # Builder for ExtraData
67
+ #
68
+ class ExtraDataBuilder
69
+ def initialize
70
+ @data_entries = []
71
+ end
72
+
73
+ #
74
+ # @param [DataEntry] data_entry
75
+ #
76
+ # @return [self]
77
+ #
78
+ def with_data_entry(data_entry)
79
+ @data_entries << data_entry
80
+ self
81
+ end
82
+
83
+ #
84
+ # @return [ExtraData]
85
+ #
86
+ def build
87
+ ExtraData.new(@data_entries)
88
+ end
89
+ end
90
+ end
91
+ end
92
+ end