yoti 1.6.4 → 1.10.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 (105) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +1 -1
  3. data/README.md +22 -224
  4. data/lib/yoti.rb +63 -1
  5. data/lib/yoti/activity_details.rb +3 -5
  6. data/lib/yoti/client.rb +13 -4
  7. data/lib/yoti/configuration.rb +8 -3
  8. data/lib/yoti/data_type/age_verification.rb +1 -1
  9. data/lib/yoti/data_type/base_profile.rb +1 -1
  10. data/lib/yoti/data_type/document_details.rb +1 -1
  11. data/lib/yoti/data_type/image.rb +4 -12
  12. data/lib/yoti/data_type/image_jpeg.rb +2 -0
  13. data/lib/yoti/data_type/image_png.rb +2 -0
  14. data/lib/yoti/data_type/media.rb +22 -0
  15. data/lib/yoti/data_type/signed_time_stamp.rb +1 -1
  16. data/lib/yoti/doc_scan/client.rb +191 -0
  17. data/lib/yoti/doc_scan/constants.rb +35 -0
  18. data/lib/yoti/doc_scan/errors.rb +81 -0
  19. data/lib/yoti/doc_scan/session/create/create_session_result.rb +50 -0
  20. data/lib/yoti/doc_scan/session/create/document_filter.rb +31 -0
  21. data/lib/yoti/doc_scan/session/create/document_restrictions_filter.rb +140 -0
  22. data/lib/yoti/doc_scan/session/create/notification_config.rb +142 -0
  23. data/lib/yoti/doc_scan/session/create/objective/objective.rb +31 -0
  24. data/lib/yoti/doc_scan/session/create/objective/proof_of_address_objective.rb +31 -0
  25. data/lib/yoti/doc_scan/session/create/orthogonal_restrictions_filter.rb +150 -0
  26. data/lib/yoti/doc_scan/session/create/requested_check.rb +39 -0
  27. data/lib/yoti/doc_scan/session/create/requested_document_authenticity_check.rb +95 -0
  28. data/lib/yoti/doc_scan/session/create/requested_face_match_check.rb +95 -0
  29. data/lib/yoti/doc_scan/session/create/requested_id_document_comparison_check.rb +53 -0
  30. data/lib/yoti/doc_scan/session/create/requested_liveness_check.rb +108 -0
  31. data/lib/yoti/doc_scan/session/create/requested_supplementary_doc_text_extraction_task.rb +94 -0
  32. data/lib/yoti/doc_scan/session/create/requested_task.rb +39 -0
  33. data/lib/yoti/doc_scan/session/create/requested_text_extraction_task.rb +116 -0
  34. data/lib/yoti/doc_scan/session/create/required_document.rb +31 -0
  35. data/lib/yoti/doc_scan/session/create/required_id_document.rb +53 -0
  36. data/lib/yoti/doc_scan/session/create/required_supplementary_document.rb +90 -0
  37. data/lib/yoti/doc_scan/session/create/sdk_config.rb +221 -0
  38. data/lib/yoti/doc_scan/session/create/session_specification.rb +221 -0
  39. data/lib/yoti/doc_scan/session/retrieve/authenticity_check_response.rb +12 -0
  40. data/lib/yoti/doc_scan/session/retrieve/breakdown_response.rb +38 -0
  41. data/lib/yoti/doc_scan/session/retrieve/check_response.rb +63 -0
  42. data/lib/yoti/doc_scan/session/retrieve/details_response.rb +28 -0
  43. data/lib/yoti/doc_scan/session/retrieve/document_fields_response.rb +21 -0
  44. data/lib/yoti/doc_scan/session/retrieve/document_id_photo_response.rb +21 -0
  45. data/lib/yoti/doc_scan/session/retrieve/face_map_response.rb +21 -0
  46. data/lib/yoti/doc_scan/session/retrieve/face_match_check_response.rb +12 -0
  47. data/lib/yoti/doc_scan/session/retrieve/file_response.rb +21 -0
  48. data/lib/yoti/doc_scan/session/retrieve/frame_response.rb +21 -0
  49. data/lib/yoti/doc_scan/session/retrieve/generated_check_response.rb +28 -0
  50. data/lib/yoti/doc_scan/session/retrieve/generated_media.rb +28 -0
  51. data/lib/yoti/doc_scan/session/retrieve/generated_supplementary_document_text_data_check_response.rb +12 -0
  52. data/lib/yoti/doc_scan/session/retrieve/generated_text_data_check_response.rb +12 -0
  53. data/lib/yoti/doc_scan/session/retrieve/get_session_result.rb +145 -0
  54. data/lib/yoti/doc_scan/session/retrieve/id_document_comparison_check_response.rb +12 -0
  55. data/lib/yoti/doc_scan/session/retrieve/id_document_resource_response.rb +57 -0
  56. data/lib/yoti/doc_scan/session/retrieve/liveness_check_response.rb +12 -0
  57. data/lib/yoti/doc_scan/session/retrieve/liveness_resource_response.rb +24 -0
  58. data/lib/yoti/doc_scan/session/retrieve/media_response.rb +38 -0
  59. data/lib/yoti/doc_scan/session/retrieve/page_response.rb +37 -0
  60. data/lib/yoti/doc_scan/session/retrieve/recommendation_response.rb +34 -0
  61. data/lib/yoti/doc_scan/session/retrieve/report_response.rb +31 -0
  62. data/lib/yoti/doc_scan/session/retrieve/resource_container.rb +69 -0
  63. data/lib/yoti/doc_scan/session/retrieve/resource_response.rb +41 -0
  64. data/lib/yoti/doc_scan/session/retrieve/supplementary_document_resource_response.rb +57 -0
  65. data/lib/yoti/doc_scan/session/retrieve/supplementary_document_text_data_check_response.rb +12 -0
  66. data/lib/yoti/doc_scan/session/retrieve/supplementary_document_text_extraction_task_response.rb +18 -0
  67. data/lib/yoti/doc_scan/session/retrieve/task_response.rb +89 -0
  68. data/lib/yoti/doc_scan/session/retrieve/text_data_check_response.rb +12 -0
  69. data/lib/yoti/doc_scan/session/retrieve/text_extraction_task_response.rb +18 -0
  70. data/lib/yoti/doc_scan/session/retrieve/zoom_liveness_resource_response.rb +33 -0
  71. data/lib/yoti/doc_scan/support/supported_documents.rb +60 -0
  72. data/lib/yoti/dynamic_share_service/dynamic_scenario.rb +5 -0
  73. data/lib/yoti/dynamic_share_service/extension/extension.rb +3 -0
  74. data/lib/yoti/dynamic_share_service/extension/location_constraint_extension.rb +3 -0
  75. data/lib/yoti/dynamic_share_service/extension/thirdparty_attribute_extension.rb +1 -1
  76. data/lib/yoti/dynamic_share_service/extension/transactional_flow_extension.rb +4 -0
  77. data/lib/yoti/dynamic_share_service/policy/dynamic_policy.rb +74 -9
  78. data/lib/yoti/dynamic_share_service/policy/wanted_anchor.rb +3 -0
  79. data/lib/yoti/dynamic_share_service/policy/wanted_attribute.rb +5 -0
  80. data/lib/yoti/dynamic_share_service/share_url.rb +26 -33
  81. data/lib/yoti/errors.rb +15 -2
  82. data/lib/yoti/http/aml_check_request.rb +12 -6
  83. data/lib/yoti/http/payloads/aml_address.rb +4 -0
  84. data/lib/yoti/http/payloads/aml_profile.rb +7 -1
  85. data/lib/yoti/http/profile_request.rb +11 -6
  86. data/lib/yoti/http/request.rb +219 -18
  87. data/lib/yoti/http/signed_request.rb +13 -4
  88. data/lib/yoti/protobuf/main.rb +8 -8
  89. data/lib/yoti/share/attribute_issuance_details.rb +6 -0
  90. data/lib/yoti/ssl.rb +4 -4
  91. data/lib/yoti/util/age_processor.rb +1 -1
  92. data/lib/yoti/util/anchor_processor.rb +2 -2
  93. data/lib/yoti/util/log.rb +1 -1
  94. data/lib/yoti/util/validation.rb +41 -0
  95. data/lib/yoti/version.rb +1 -1
  96. data/yoti.gemspec +18 -6
  97. metadata +69 -33
  98. data/.github/ISSUE_TEMPLATE.md +0 -17
  99. data/.gitignore +0 -39
  100. data/CONTRIBUTING.md +0 -98
  101. data/Guardfile +0 -11
  102. data/Rakefile +0 -54
  103. data/login_flow.png +0 -0
  104. data/rubocop.yml +0 -57
  105. data/yardstick.yml +0 -9
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Yoti
4
+ module DocScan
5
+ module Session
6
+ module Retrieve
7
+ class RecommendationResponse
8
+ # @return [String]
9
+ attr_reader :value
10
+
11
+ # @return [String]
12
+ attr_reader :reason
13
+
14
+ # @return [String]
15
+ attr_reader :recovery_suggestion
16
+
17
+ #
18
+ # @param [Hash] recommendation
19
+ #
20
+ def initialize(recommendation)
21
+ Validation.assert_is_a(String, recommendation['value'], 'value', true)
22
+ @value = recommendation['value']
23
+
24
+ Validation.assert_is_a(String, recommendation['reason'], 'reason', true)
25
+ @reason = recommendation['reason']
26
+
27
+ Validation.assert_is_a(String, recommendation['recovery_suggestion'], 'recovery_suggestion', true)
28
+ @recovery_suggestion = recommendation['recovery_suggestion']
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Yoti
4
+ module DocScan
5
+ module Session
6
+ module Retrieve
7
+ class ReportResponse
8
+ # @return [RecommendationResponse]
9
+ attr_reader :recommendation
10
+
11
+ # @return [Array<BreakdownResponse>]
12
+ attr_reader :breakdown
13
+
14
+ #
15
+ # @param [Hash] report
16
+ #
17
+ def initialize(report)
18
+ @recommendation = RecommendationResponse.new(report['recommendation']) unless report['recommendation'].nil?
19
+
20
+ if report['breakdown'].nil?
21
+ @breakdown = []
22
+ else
23
+ Validation.assert_is_a(Array, report['breakdown'], 'breakdown')
24
+ @breakdown = report['breakdown'].map { |breakdown| BreakdownResponse.new(breakdown) }
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,69 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Yoti
4
+ module DocScan
5
+ module Session
6
+ module Retrieve
7
+ class ResourceContainer
8
+ # @return [Array<IdDocumentResourceResponse>]
9
+ attr_reader :id_documents
10
+
11
+ # @return [Array<SupplementaryDocumentResourceResponse>]
12
+ attr_reader :supplementary_documents
13
+
14
+ # @return [Array<LivenessResourceResponse>]
15
+ attr_reader :liveness_capture
16
+
17
+ #
18
+ # @param [Hash] resources
19
+ #
20
+ def initialize(resources)
21
+ @id_documents = parse_id_documents(resources)
22
+ @supplementary_documents = parse_supplementary_documents(resources)
23
+
24
+ if resources['liveness_capture'].nil?
25
+ @liveness_capture = []
26
+ else
27
+ Validation.assert_is_a(Array, resources['liveness_capture'], 'liveness_capture')
28
+ @liveness_capture = resources['liveness_capture'].map do |resource|
29
+ case resource['liveness_type']
30
+ when Constants::ZOOM
31
+ ZoomLivenessResourceResponse.new(resource)
32
+ else
33
+ LivenessResourceResponse.new(resource)
34
+ end
35
+ end
36
+ end
37
+ end
38
+
39
+ #
40
+ # @return [Array<ZoomLivenessResourceResponse>]
41
+ #
42
+ def zoom_liveness_resources
43
+ @liveness_capture.select { |resource| resource.is_a?(ZoomLivenessResourceResponse) }
44
+ end
45
+
46
+ private
47
+
48
+ def parse_id_documents(resources)
49
+ return [] if resources['id_documents'].nil?
50
+
51
+ Validation.assert_is_a(Array, resources['id_documents'], 'id_documents')
52
+ resources['id_documents'].map do |resource|
53
+ IdDocumentResourceResponse.new(resource)
54
+ end
55
+ end
56
+
57
+ def parse_supplementary_documents(resources)
58
+ return [] if resources['supplementary_documents'].nil?
59
+
60
+ Validation.assert_is_a(Array, resources['supplementary_documents'], 'supplementary_documents')
61
+ resources['supplementary_documents'].map do |resource|
62
+ SupplementaryDocumentResourceResponse.new(resource)
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Yoti
4
+ module DocScan
5
+ module Session
6
+ module Retrieve
7
+ class ResourceResponse
8
+ # @return [String]
9
+ attr_reader :id
10
+
11
+ # @return [Array<TaskResponse>]
12
+ attr_reader :tasks
13
+
14
+ #
15
+ # @param [Hash] resource
16
+ #
17
+ def initialize(resource)
18
+ Validation.assert_is_a(String, resource['id'], 'id', true)
19
+ @id = resource['id']
20
+
21
+ if resource['tasks'].nil?
22
+ @tasks = []
23
+ else
24
+ Validation.assert_is_a(Array, resource['tasks'], 'tasks')
25
+ @tasks = resource['tasks'].map do |task|
26
+ case task['type']
27
+ when Constants::ID_DOCUMENT_TEXT_DATA_EXTRACTION
28
+ TextExtractionTaskResponse.new(task)
29
+ when Constants::SUPPLEMENTARY_DOCUMENT_TEXT_DATA_EXTRACTION
30
+ SupplementaryDocumentTextExtractionTaskResponse.new(task)
31
+ else
32
+ TaskResponse.new(task)
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,57 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Yoti
4
+ module DocScan
5
+ module Session
6
+ module Retrieve
7
+ class SupplementaryDocumentResourceResponse < ResourceResponse
8
+ # @return [String]
9
+ attr_reader :document_type
10
+
11
+ # @return [String]
12
+ attr_reader :issuing_country
13
+
14
+ # @return [Array<PageResponse>]
15
+ attr_reader :pages
16
+
17
+ # @return [DocumentFieldsResponse]
18
+ attr_reader :document_fields
19
+
20
+ # @return [FileResponse]
21
+ attr_reader :document_file
22
+
23
+ #
24
+ # @param [Hash] resource
25
+ #
26
+ def initialize(resource)
27
+ super(resource)
28
+
29
+ Validation.assert_is_a(String, resource['document_type'], 'document_type', true)
30
+ @document_type = resource['document_type']
31
+
32
+ Validation.assert_is_a(String, resource['issuing_country'], 'issuing_country', true)
33
+ @issuing_country = resource['issuing_country']
34
+
35
+ if resource['pages'].nil?
36
+ @pages = []
37
+ else
38
+ Validation.assert_is_a(Array, resource['pages'], 'pages')
39
+ @pages = resource['pages'].map { |page| PageResponse.new(page) }
40
+ end
41
+
42
+ @document_fields = DocumentFieldsResponse.new(resource['document_fields']) unless resource['document_fields'].nil?
43
+
44
+ @document_file = FileResponse.new(resource['file']) unless resource['file'].nil?
45
+ end
46
+
47
+ #
48
+ # @return [Array<SupplementaryDocumentTextExtractionTaskResponse>]
49
+ #
50
+ def text_extraction_tasks
51
+ @tasks.select { |task| task.is_a?(SupplementaryDocumentTextExtractionTaskResponse) }
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Yoti
4
+ module DocScan
5
+ module Session
6
+ module Retrieve
7
+ class SupplementaryDocumentTextDataCheckResponse < CheckResponse
8
+ end
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Yoti
4
+ module DocScan
5
+ module Session
6
+ module Retrieve
7
+ class SupplementaryDocumentTextExtractionTaskResponse < TaskResponse
8
+ #
9
+ # @return [Array<GeneratedSupplementaryDocumentTextDataCheckResponse>]
10
+ #
11
+ def generated_text_data_checks
12
+ @generated_checks.select { |check| check.is_a?(GeneratedSupplementaryDocumentTextDataCheckResponse) }
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,89 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Yoti
4
+ module DocScan
5
+ module Session
6
+ module Retrieve
7
+ class TaskResponse
8
+ # @return [String]
9
+ attr_reader :type
10
+
11
+ # @return [String]
12
+ attr_reader :id
13
+
14
+ # @return [String]
15
+ attr_reader :state
16
+
17
+ # @return [Array<String>]
18
+ attr_reader :resources_used
19
+
20
+ # @return [Array<GeneratedMedia>]
21
+ attr_reader :generated_media
22
+
23
+ # @return [Array<GeneratedCheckResponse>]
24
+ attr_reader :generated_checks
25
+
26
+ # @return [<DateTime>]
27
+ attr_reader :created
28
+
29
+ # @return [<DateTime>]
30
+ attr_reader :last_updated
31
+
32
+ #
33
+ # @param [Hash] task
34
+ #
35
+ def initialize(task)
36
+ Validation.assert_is_a(String, task['type'], 'type', true)
37
+ @type = task['type']
38
+
39
+ Validation.assert_is_a(String, task['id'], 'id', true)
40
+ @id = task['id']
41
+
42
+ Validation.assert_is_a(String, task['state'], 'state', true)
43
+ @state = task['state']
44
+
45
+ Validation.assert_is_a(Array, task['resources_used'], 'resources_used', true)
46
+ @resources_used = task['resources_used']
47
+
48
+ @created = DateTime.parse(task['created']) unless task['created'].nil?
49
+ @last_updated = DateTime.parse(task['last_updated']) unless task['last_updated'].nil?
50
+
51
+ if task['generated_checks'].nil?
52
+ @generated_checks = []
53
+ else
54
+ Validation.assert_is_a(Array, task['generated_checks'], 'generated_checks')
55
+ @generated_checks = map_generated_checks(task['generated_checks'])
56
+ end
57
+
58
+ if task['generated_media'].nil?
59
+ @generated_media = []
60
+ else
61
+ Validation.assert_is_a(Array, task['generated_media'], 'generated_media')
62
+ @generated_media = task['generated_media'].map { |media| GeneratedMedia.new(media) }
63
+ end
64
+ end
65
+
66
+ private
67
+
68
+ #
69
+ # @param [Array<Hash>] generated_checks
70
+ #
71
+ # @return [Array<GeneratedCheckResponse>]
72
+ #
73
+ def map_generated_checks(generated_checks)
74
+ generated_checks.map do |check|
75
+ case check['type']
76
+ when Constants::ID_DOCUMENT_TEXT_DATA_CHECK
77
+ GeneratedTextDataCheckResponse.new(check)
78
+ when Constants::SUPPLEMENTARY_DOCUMENT_TEXT_DATA_CHECK
79
+ GeneratedSupplementaryDocumentTextDataCheckResponse.new(check)
80
+ else
81
+ GeneratedCheckResponse.new(check)
82
+ end
83
+ end
84
+ end
85
+ end
86
+ end
87
+ end
88
+ end
89
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Yoti
4
+ module DocScan
5
+ module Session
6
+ module Retrieve
7
+ class TextDataCheckResponse < CheckResponse
8
+ end
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Yoti
4
+ module DocScan
5
+ module Session
6
+ module Retrieve
7
+ class TextExtractionTaskResponse < TaskResponse
8
+ #
9
+ # @return [Array<GeneratedTextDataCheckResponse>]
10
+ #
11
+ def generated_text_data_checks
12
+ @generated_checks.select { |check| check.is_a?(GeneratedTextDataCheckResponse) }
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Yoti
4
+ module DocScan
5
+ module Session
6
+ module Retrieve
7
+ class ZoomLivenessResourceResponse < LivenessResourceResponse
8
+ # @return [FaceMapResponse]
9
+ attr_reader :facemap
10
+
11
+ # @return [Array<FrameResponse>]
12
+ attr_reader :frames
13
+
14
+ #
15
+ # @param [Hash] resource
16
+ #
17
+ def initialize(resource)
18
+ super(resource)
19
+
20
+ @facemap = FaceMapResponse.new(resource['facemap']) unless resource['facemap'].nil?
21
+
22
+ if resource['frames'].nil?
23
+ @frames = []
24
+ else
25
+ Validation.assert_is_a(Array, resource['frames'], 'frames')
26
+ @frames = resource['frames'].map { |frame| FrameResponse.new(frame) }
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,60 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Yoti
4
+ module DocScan
5
+ module Support
6
+ class SupportedDocumentsResponse
7
+ # @return [Array<SupportedCountry>]
8
+ attr_reader :supported_countries
9
+
10
+ #
11
+ # @param [Hash] response
12
+ #
13
+ def initialize(response)
14
+ if response['supported_countries'].nil?
15
+ @supported_countries = []
16
+ else
17
+ Validation.assert_is_a(Array, response['supported_countries'], 'supported_countries')
18
+ @supported_countries = response['supported_countries'].map { |country| SupportedCountry.new(country) }
19
+ end
20
+ end
21
+ end
22
+
23
+ class SupportedCountry
24
+ # @return [String]
25
+ attr_reader :code
26
+
27
+ # @return [Array<SupportedDocument>]
28
+ attr_reader :supported_documents
29
+
30
+ #
31
+ # @param [Hash] country
32
+ #
33
+ def initialize(country)
34
+ Validation.assert_is_a(String, country['code'], 'code', true)
35
+ @code = country['code']
36
+
37
+ if country['supported_documents'].nil?
38
+ @supported_documents = []
39
+ else
40
+ Validation.assert_is_a(Array, country['supported_documents'], 'supported_documents')
41
+ @supported_documents = country['supported_documents'].map { |document| SupportedDocument.new(document) }
42
+ end
43
+ end
44
+ end
45
+
46
+ class SupportedDocument
47
+ # @return [String]
48
+ attr_reader :type
49
+
50
+ #
51
+ # @param [Hash] document
52
+ #
53
+ def initialize(document)
54
+ Validation.assert_is_a(String, document['type'], 'type', true)
55
+ @type = document['type']
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end