aliquot 2.3.1 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e752bf7cf311e4fe611e3c868ed08510c54d9e1b05b327d5dfa390b3eeb8cee7
4
- data.tar.gz: 5c7df397cabccc5009c712546838c67329f4e2c835935ba56e62f71b6c368920
3
+ metadata.gz: f8e2a9a7e324874ed68aeaacd8a072ea00dedfce4e6022494f7333c94b55ec1d
4
+ data.tar.gz: 5bfc71f786436d227100470dc37a0d8715196b59d474d0b39b6dd3afa730ff61
5
5
  SHA512:
6
- metadata.gz: 648c2bb459b2a09b602c13dab8c8221fc726c886e047789c84ebf51d1436a3f5fece61255905744cf817dcf114d9833f3f0281d5c7ed18a6eb1c44a60b770521
7
- data.tar.gz: eb060ab6212f664bf3545a306dee4eaac7f63a6388921faf70cc28393e7bc606731d408edb3224ce737c3bc9ef8be8efa16942df717e157a1f3e0f746ad467f6
6
+ metadata.gz: c95f8f7f99e9bbb9dfa7685927521e135b480e8a9e098c265771d592e1ebbd9c16e75be9b11b03cb369d0290e6fbb5c860be7cfad2252543b84950448011e13b
7
+ data.tar.gz: 9983ede008609ae095ce8dc863e361c7f3c46e449efe59c7d0422331284b9e18ec8b1182d14da9a71b5361266435c68d6fb125750165968d82ea755365ec9ff3
@@ -66,6 +66,9 @@ module Aliquot
66
66
 
67
67
  begin
68
68
  @message = JSON.parse(decrypt(aes_key, @signed_message[:encryptedMessage]))
69
+ @message['paymentMethodDetails'].merge!(
70
+ 'threedsCryptogram' => @message['paymentMethodDetails']
71
+ .delete('3dsCryptogram')) if @message['paymentMethodDetails']['3dsCryptogram']
69
72
  rescue JSON::JSONError => e
70
73
  raise InputError, "encryptedMessage JSON is invalid, #{e.message}"
71
74
  rescue => e
@@ -221,7 +224,20 @@ module Aliquot
221
224
  validator.validate
222
225
 
223
226
  # Output is hashed with symbolized keys.
224
- validator.output
227
+ message_hash = validator.output
228
+
229
+ payment_method_details_message = message_hash[:paymentMethodDetails]
230
+ message_details_validator =
231
+ if message_hash[:paymentMethod] == 'TOKENIZED_CARD' ||
232
+ message_hash[:paymentMethodDetails]['authMethod'] == 'CRYPTOGRAM_3DS'
233
+ Aliquot::Validator::PaymentMethodDetailsValidator.new(payment_method_details_message, protocol_version, true)
234
+ else
235
+ Aliquot::Validator::PaymentMethodDetailsValidator.new(payment_method_details_message, protocol_version, false)
236
+ end
237
+ message_details_validator.validate
238
+ message_hash[:paymentMethodDetails] = message_details_validator.output
239
+
240
+ message_hash
225
241
  end
226
242
 
227
243
  ##
@@ -21,8 +21,8 @@ module Aliquot
21
21
  base64_asn1?: 'must be base64-encoded ANS.1 value',
22
22
  json?: 'must be valid JSON',
23
23
 
24
- is_authMethodCryptogram3DS: 'authMethod CRYPTOGRAM_3DS requires eciIndicator',
25
- is_authMethodCard: 'eciIndicator/cryptogram must be omitted when PAN_ONLY',
24
+ is_authMethodCryptogram3DS: 'authMethod CRYPTOGRAM_3DS or 3DS requires eciIndicator',
25
+ is_authMethodCard: 'eciIndicator/cryptogram/3dsCryptogram must be omitted when PAN_ONLY',
26
26
  }.freeze
27
27
 
28
28
  def self.base64_check(value)
@@ -118,8 +118,6 @@ module Aliquot
118
118
  rule(:keyValue).validate(:ec_public_key?)
119
119
  end
120
120
 
121
- SignedKeySchema = SignedKeyContract.new
122
-
123
121
  # Schema used for the 'intermediateSigningKey' hash included in ECv2.
124
122
  class IntermediateSigningKeyContract < Dry::Validation::Contract
125
123
  json do
@@ -129,12 +127,10 @@ module Aliquot
129
127
  rule(:signedKey).validate(:json?)
130
128
  rule(:signatures).each do
131
129
  key.failure('must be Base64') unless Aliquot::Validator.base64_check(value) &&
132
- Aliquot::Validator.ans1_check(value)
130
+ Aliquot::Validator.ans1_check(value)
133
131
  end
134
132
  end
135
133
 
136
- IntermediateSigningKeySchema = IntermediateSigningKeyContract.new
137
-
138
134
  # DRY-Validation schema for Google Pay token
139
135
  class TokenContract < Dry::Validation::Contract
140
136
  json do
@@ -147,13 +143,11 @@ module Aliquot
147
143
  rule(:signedMessage).validate(:json?)
148
144
 
149
145
  rule(:intermediateSigningKey) do
150
- key.failure('is missing') if 'ECv2'.eql?(values[:protocolVersion]) &&
151
- values[:intermediateSigningKey].nil?
146
+ key.failure('is missing') if values[:protocolVersion] == 'ECv2' &&
147
+ values[:intermediateSigningKey].nil?
152
148
  end
153
149
  end
154
150
 
155
- TokenSchema = TokenContract.new
156
-
157
151
  # DRY-Validation schema for signedMessage component Google Pay token
158
152
  class SignedMessageContract < Dry::Validation::Contract
159
153
  json do
@@ -166,41 +160,55 @@ module Aliquot
166
160
  rule(:tag).validate(:base64?)
167
161
  end
168
162
 
169
- SignedMessageSchema = SignedMessageContract.new
170
-
171
- # DRY-Validation schema for paymentMethodDetails component Google Pay token
172
- class PaymentMethodDetailsContract < Dry::Validation::Contract
163
+ class CommonPaymentMethodDetailsContract < Dry::Validation::Contract
173
164
  json do
174
- required(:pan).filled(:str?)
175
165
  required(:expirationMonth).filled(:int?)
176
166
  required(:expirationYear).filled(:int?)
177
- required(:authMethod).filled(:str?, included_in?: %w[PAN_ONLY CRYPTOGRAM_3DS])
178
-
179
- optional(:cryptogram).filled(:str?)
180
- optional(:eciIndicator).filled(:str?)
181
167
  end
182
- rule(:pan).validate(:integer_string?, :pan?)
183
168
  rule(:expirationMonth).validate(:month?)
184
169
  rule(:expirationYear).validate(:year?)
185
- rule(:eciIndicator).validate(:eci?)
170
+ end
186
171
 
187
- rule(:cryptogram) do
188
- key.failure('is missing') if 'CRYPTOGRAM_3DS'.eql?(values[:authMethod]) &&
189
- values[:cryptogram].nil?
172
+ class ECv1_PaymentMethodDetailsContract < CommonPaymentMethodDetailsContract
173
+ json(CommonPaymentMethodDetailsContract.schema) do
174
+ required(:pan).filled(:str?)
190
175
  end
191
176
 
192
- rule(:cryptogram) do
193
- key.failure('cannot be defined') if 'PAN_ONLY'.eql?(values[:authMethod]) &&
194
- !values[:cryptogram].nil?
177
+ rule(:pan).validate(:integer_string?, :pan?)
178
+ end
179
+
180
+ class ECv1_TokenizedPaymentMethodDetailsContract < CommonPaymentMethodDetailsContract
181
+ json(CommonPaymentMethodDetailsContract.schema) do
182
+ required(:dpan).filled(:str?)
183
+ required(:threedsCryptogram).filled(:str?)
184
+ required(:eciIndicator).filled(:str?)
185
+ required(:authMethod).filled(:str?, included_in?: %w[3DS])
195
186
  end
196
187
 
197
- rule(:eciIndicator) do
198
- key.failure('cannot be defined') if 'PAN_ONLY'.eql?(values[:authMethod]) &&
199
- !values[:eciIndicator].nil?
188
+ rule(:dpan).validate(:integer_string?, :pan?)
189
+ rule(:eciIndicator).validate(:eci?)
190
+ end
191
+
192
+ class ECv2_PaymentMethodDetailsContract < CommonPaymentMethodDetailsContract
193
+ json(CommonPaymentMethodDetailsContract.schema) do
194
+ required(:pan).filled(:str?)
195
+ required(:authMethod).filled(:str?, included_in?: %w[PAN_ONLY])
200
196
  end
197
+
198
+ rule(:pan).validate(:integer_string?, :pan?)
201
199
  end
202
200
 
203
- PaymentMethodDetailsSchema = PaymentMethodDetailsContract.new
201
+ class ECv2_TokenizedPaymentMethodDetailsContract < CommonPaymentMethodDetailsContract
202
+ json(CommonPaymentMethodDetailsContract.schema) do
203
+ required(:pan).filled(:str?)
204
+ required(:cryptogram).filled(:str?)
205
+ required(:eciIndicator).filled(:str?)
206
+ required(:authMethod).filled(:str?, included_in?: %w[CRYPTOGRAM_3DS])
207
+ end
208
+
209
+ rule(:pan).validate(:integer_string?, :pan?)
210
+ rule(:eciIndicator).validate(:eci?)
211
+ end
204
212
 
205
213
  # DRY-Validation schema for encryptedMessage component Google Pay token
206
214
  class EncryptedMessageContract < Dry::Validation::Contract
@@ -208,17 +216,40 @@ module Aliquot
208
216
  required(:messageExpiration).filled(:str?)
209
217
  required(:messageId).filled(:str?)
210
218
  required(:paymentMethod).filled(:str?)
211
- required(:paymentMethodDetails).filled(:hash).schema(PaymentMethodDetailsContract.schema)
219
+ required(:paymentMethodDetails).filled(:hash)
212
220
  optional(:gatewayMerchantId).filled(:str?)
213
221
  end
214
222
  rule(:messageExpiration).validate(:integer_string?)
223
+
224
+ rule(:paymentMethodDetails).validate do
225
+ contract =
226
+ if values[:protocolVersion] == 'ECv1'
227
+ if values[:paymentMethod] == 'TOKENIZED_CARD'
228
+ ECv1_TokenizedPaymentMethodDetailsContract.new
229
+ else
230
+ ECv1_PaymentMethodDetailsContract.new
231
+ end
232
+ else
233
+ if values[:authMethod] == 'CRYPTOGRAM_3DS'
234
+ ECv2_TokenizedPaymentMethodDetailsContract.new
235
+ else
236
+ ECv2_PaymentMethodDetailsContract.new
237
+ end
238
+ end
239
+ contract.call(values[:paymentMethodDetails])
240
+ end
241
+
215
242
  rule(:paymentMethod) do
216
- key.failure('must be equal to CARD') unless 'CARD'.eql?(value)
243
+ if values[:paymentMethodDetails].is_a?(Hash)
244
+ if '3DS'.eql?(values[:paymentMethodDetails]['authMethod']) # Tokenized ECv1
245
+ key.failure('must be equal to TOKENIZED_CARD') unless value == 'TOKENIZED_CARD'
246
+ else
247
+ key.failure('must be equal to CARD') unless value == 'CARD'
248
+ end
249
+ end
217
250
  end
218
251
  end
219
252
 
220
- EncryptedMessageSchema = EncryptedMessageContract.new
221
-
222
253
  module InstanceMethods
223
254
  attr_reader :output
224
255
 
@@ -259,7 +290,7 @@ module Aliquot
259
290
 
260
291
  def initialize(input)
261
292
  @input = input
262
- @schema = TokenSchema
293
+ @schema = TokenContract.new
263
294
  end
264
295
  end
265
296
 
@@ -271,7 +302,7 @@ module Aliquot
271
302
 
272
303
  def initialize(input)
273
304
  @input = input
274
- @schema = SignedMessageSchema
305
+ @schema = SignedMessageContract.new
275
306
  end
276
307
  end
277
308
 
@@ -283,7 +314,32 @@ module Aliquot
283
314
 
284
315
  def initialize(input)
285
316
  @input = input
286
- @schema = EncryptedMessageSchema
317
+ @schema = EncryptedMessageContract.new
318
+ end
319
+ end
320
+
321
+ # Class for validating the encryptedMessage component of a Google Pay token
322
+ class PaymentMethodDetailsValidator
323
+ include InstanceMethods
324
+
325
+ class Error < ::Aliquot::Error; end
326
+
327
+ def initialize(input, version, tokenized)
328
+ @input = input
329
+ @schema =
330
+ if version == 'ECv1'
331
+ if tokenized
332
+ Aliquot::Validator::ECv1_TokenizedPaymentMethodDetailsContract.new
333
+ else
334
+ Aliquot::Validator::ECv1_PaymentMethodDetailsContract.new
335
+ end
336
+ else
337
+ if tokenized
338
+ Aliquot::Validator::ECv2_TokenizedPaymentMethodDetailsContract.new
339
+ else
340
+ Aliquot::Validator::ECv2_PaymentMethodDetailsContract.new
341
+ end
342
+ end
287
343
  end
288
344
  end
289
345
 
@@ -294,7 +350,7 @@ module Aliquot
294
350
 
295
351
  def initialize(input)
296
352
  @input = input
297
- @schema = SignedKeySchema
353
+ @schema = SignedKeyContract.new
298
354
  end
299
355
  end
300
356
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: aliquot
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.3.1
4
+ version: 3.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Clearhaus
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-09-29 00:00:00.000000000 Z
11
+ date: 2024-02-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: dry-validation
@@ -58,14 +58,14 @@ dependencies:
58
58
  requirements:
59
59
  - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: '3.0'
61
+ version: '4.0'
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
- version: '3.0'
68
+ version: '4.0'
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: rspec
71
71
  requirement: !ruby/object:Gem::Requirement
@@ -94,7 +94,7 @@ dependencies:
94
94
  - - "~>"
95
95
  - !ruby/object:Gem::Version
96
96
  version: 0.14.1
97
- description:
97
+ description:
98
98
  email: hello@clearhaus.com
99
99
  executables: []
100
100
  extensions: []
@@ -108,7 +108,7 @@ homepage: https://github.com/clearhaus/aliquot
108
108
  licenses:
109
109
  - MIT
110
110
  metadata: {}
111
- post_install_message:
111
+ post_install_message:
112
112
  rdoc_options: []
113
113
  require_paths:
114
114
  - lib
@@ -123,8 +123,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
123
123
  - !ruby/object:Gem::Version
124
124
  version: '0'
125
125
  requirements: []
126
- rubygems_version: 3.3.5
127
- signing_key:
126
+ rubygems_version: 3.1.6
127
+ signing_key:
128
128
  specification_version: 4
129
129
  summary: Validates Google Pay tokens
130
130
  test_files: []