aliquot 0.15.0 → 2.1.1

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: 54635adaeefcc42d7fb42a854825fb7f88472ab34be2992813d899581f278969
4
- data.tar.gz: 3f66d3b5d5cc20d3a58e0c0e64958906beee8e80f07af26a4868ad27efa68e2d
3
+ metadata.gz: 340c8e93be8733d7b403356c5d7b85f0f1b69466e8492f6750875f7d1b4b0332
4
+ data.tar.gz: 27bb764e594448851ddceaaf0e65afd0a8c7916b82cf65514f077ad67d65ac56
5
5
  SHA512:
6
- metadata.gz: 23548bcc9c7e7a5ad77353bae8eab0283bd7593b3a9cf536298961d501a0b1b3181b722bf3e75ae0805d9c9dfa336d71a037ed5553eb57d0082b69a7e62aa60b
7
- data.tar.gz: a14a66a56577b6de570fa4164f30d2ca96c3a23b5b6b915d136dfd7d825242c0ae6a403cc138ff97e26f76dcad1450ba67d8a733f7b45611141ba46241fafdb8
6
+ metadata.gz: 70e3dfd919b5b2dde76eb7025a6627b46f2462096a7a9ce747764315c8b612104be97a38c7c4e8f7b2d5927e807adf992dc4bd7c145d5e091c6a699c5fae4830
7
+ data.tar.gz: 58c0275b221f378289d417131eb3e84039be05183b09e0e00cdb0b5ad8450d59c28d859ec5242544ce6eedbd0b0a933b6ad82e4e3bd0fb3ae0d62041e9e44a8d
data/lib/aliquot/error.rb CHANGED
@@ -29,5 +29,6 @@ module Aliquot
29
29
  # When shared_secret is invalid
30
30
  class InvalidSharedSecretError < Error; end
31
31
 
32
- class InvalidMerchantIDError < Error; end
32
+ # When recipient_id is invalid
33
+ class InvalidRecipientIDError < Error; end
33
34
  end
@@ -10,29 +10,29 @@ module Aliquot
10
10
  ##
11
11
  # A Payment represents a single payment using Google Pay.
12
12
  # It is used to verify/decrypt the supplied token by using the shared secret,
13
- # thus avoiding having knowledge of merchant primary keys.
13
+ # thus avoiding having knowledge of any private keys involved.
14
14
  class Payment
15
15
  SUPPORTED_PROTOCOL_VERSIONS = %w[ECv1 ECv2].freeze
16
16
  ##
17
17
  # Parameters:
18
18
  # token_string:: Google Pay token (JSON string)
19
19
  # shared_secret:: Base64 encoded shared secret
20
- # merchant_id:: Google Pay merchant ID
20
+ # recipient_id:: Google Pay recipient ID
21
21
  # signing_keys:: Signing keys fetched from Google
22
- def initialize(token_string, shared_secret, merchant_id,
22
+ def initialize(token_string, shared_secret, recipient_id,
23
23
  signing_keys: ENV['GOOGLE_SIGNING_KEYS'])
24
24
 
25
25
  begin
26
26
  validation = Aliquot::Validator::Token.new(JSON.parse(token_string))
27
27
  validation.validate
28
28
  rescue JSON::JSONError => e
29
- raise InputError, "invalid token JSON, #{e.message}"
29
+ raise InputError, "token JSON is invalid, #{e.message}"
30
30
  end
31
31
 
32
32
  @token = validation.output
33
33
 
34
34
  @shared_secret = shared_secret
35
- @merchant_id = merchant_id
35
+ @recipient_id = recipient_id
36
36
  @signing_keys = signing_keys
37
37
  end
38
38
 
@@ -43,13 +43,13 @@ module Aliquot
43
43
  raise Error, "supported protocol versions are #{SUPPORTED_PROTOCOL_VERSIONS.join(', ')}"
44
44
  end
45
45
 
46
- @recipient_id = validate_merchant_id
46
+ @recipient_id = validate_recipient_id
47
47
 
48
48
  check_shared_secret
49
49
 
50
50
  if protocol_version == 'ECv2'
51
51
  @intermediate_key = validate_intermediate_key
52
- raise InvalidSignatureError, 'intermediate certificate has expired' if intermediate_key_expired?
52
+ raise InvalidSignatureError, 'intermediate certificate is expired' if intermediate_key_expired?
53
53
  end
54
54
 
55
55
  check_signature
@@ -59,22 +59,22 @@ module Aliquot
59
59
  begin
60
60
  aes_key, mac_key = derive_keys(@signed_message[:ephemeralPublicKey], @shared_secret, 'Google')
61
61
  rescue => e
62
- raise KeyDerivationError, "unable to derive keys, #{e.message}"
62
+ raise KeyDerivationError, "cannot derive keys, #{e.message}"
63
63
  end
64
64
 
65
- raise InvalidMacError, 'MAC did not match' unless valid_mac?(mac_key)
65
+ raise InvalidMacError, 'MAC does not match' unless valid_mac?(mac_key)
66
66
 
67
67
  begin
68
68
  @message = JSON.parse(decrypt(aes_key, @signed_message[:encryptedMessage]))
69
69
  rescue JSON::JSONError => e
70
- raise InputError, "invalid encryptedMessage JSON, #{e.message}"
70
+ raise InputError, "encryptedMessage JSON is invalid, #{e.message}"
71
71
  rescue => e
72
72
  raise DecryptionError, "decryption failed, #{e.message}"
73
73
  end
74
74
 
75
75
  @message = validate_message
76
76
 
77
- raise TokenExpiredError, 'token has expired' if expired?
77
+ raise TokenExpiredError, 'token is expired' if expired?
78
78
 
79
79
  @message
80
80
  end
@@ -102,9 +102,10 @@ module Aliquot
102
102
  @intermediate_key[:keyExpiration].to_i < cur_millis
103
103
  end
104
104
 
105
- def validate_merchant_id
106
- raise InvalidMerchantIDError unless /\A[[:graph:]]+\z/ =~ @merchant_id
107
- "merchant:#{@merchant_id}"
105
+ def validate_recipient_id
106
+ raise InvalidRecipientIDError, 'recipient_id must be alphanumeric and punctuation' unless /\A[[:graph:]]+\z/ =~ @recipient_id
107
+
108
+ @recipient_id
108
109
  end
109
110
 
110
111
  def check_shared_secret
@@ -133,7 +134,7 @@ module Aliquot
133
134
  key.verify(new_digest, message_signature, signed_string_message)
134
135
  end.any?
135
136
 
136
- raise InvalidSignatureError, 'signature of signedMessage did not match' unless success
137
+ raise InvalidSignatureError, 'signature of signedMessage does not match' unless success
137
138
  when 'ECv2'
138
139
  signed_key_signature = ['Google', 'ECv2', @token[:intermediateSigningKey][:signedKey]].map do |str|
139
140
  [str.length].pack('V') + str
@@ -141,7 +142,7 @@ module Aliquot
141
142
 
142
143
  # Check that the intermediate key signed the message
143
144
  pkey = OpenSSL::PKey::EC.new(Base64.strict_decode64(@intermediate_key[:keyValue]))
144
- raise InvalidSignatureError, 'signature of signedMessage did not match' unless pkey.verify(new_digest, message_signature, signed_string_message)
145
+ raise InvalidSignatureError, 'signature of signedMessage does not match' unless pkey.verify(new_digest, message_signature, signed_string_message)
145
146
 
146
147
  intermediate_signatures = @token[:intermediateSigningKey][:signatures]
147
148
 
@@ -152,7 +153,7 @@ module Aliquot
152
153
  signed_key_signature
153
154
  )
154
155
 
155
- raise InvalidSignatureError, 'no valid signature of intermediate key found' unless success
156
+ raise InvalidSignatureError, 'no valid signature of intermediate key' unless success
156
157
  end
157
158
  rescue OpenSSL::PKey::PKeyError => e
158
159
  # Catches problems with verifying signature. Can be caused by signature
@@ -9,143 +9,221 @@ module Aliquot
9
9
  module Validator
10
10
  # Verified according to:
11
11
  # https://developers.google.com/pay/api/web/guides/resources/payment-data-cryptography#payment-method-token-structure
12
- module Predicates
13
- include Dry::Logic::Predicates
14
-
15
- CUSTOM_PREDICATE_ERRORS = {
16
- base64?: 'must be Base64',
17
- pan?: 'must be a pan',
18
- ec_public_key?: 'must be an EC public key',
19
- eci?: 'must be an ECI',
20
- json_string?: 'must be valid JSON',
21
- integer_string?: 'must be string encoded integer',
22
- month?: 'must be a month (1..12)',
23
- year?: 'must be a year (2000..3000)',
24
- base64_asn1?: 'must be base64 encoded asn1 value',
25
-
26
- authMethodCryptogram3DS: 'authMethod CRYPTOGRAM_3DS requires eciIndicator',
27
- authMethodCard: 'eciIndicator/cryptogram must be omitted when PAN_ONLY',
28
- }.freeze
29
-
30
- # Support Ruby 2.3, but use the faster #match? when available.
31
- match_b = ''.respond_to?(:match?) ? ->(s, re) { s.match?(re) } : ->(s, re) { !!(s =~ re) }
32
-
33
- def self.to_bool(lbd)
34
- lbd.call
35
- true
36
- rescue
37
- false
38
- end
39
12
 
40
- predicate(:base64?) do |x|
41
- str?(x) &&
42
- match_b.call(x, /\A[=A-Za-z0-9+\/]*\z/) && # allowable chars
43
- x.length.remainder(4).zero? && # multiple of 4
44
- !match_b.call(x, /=[^$=]/) && # may only end with ='s
45
- !match_b.call(x, /===/) # at most 2 ='s
13
+ CUSTOM_ERRORS = {
14
+ base64?: 'must be Base64',
15
+ pan?: 'must be a PAN',
16
+ ec_public_key?: 'must be an EC public key',
17
+ eci?: 'must be an ECI',
18
+ integer_string?: 'must be string encoded integer',
19
+ month?: 'must be a month (1..12)',
20
+ year?: 'must be a year (2000..3000)',
21
+ base64_asn1?: 'must be base64-encoded ANS.1 value',
22
+ json?: 'must be valid JSON',
23
+
24
+ is_authMethodCryptogram3DS: 'authMethod CRYPTOGRAM_3DS requires eciIndicator',
25
+ is_authMethodCard: 'eciIndicator/cryptogram must be omitted when PAN_ONLY',
26
+ }.freeze
27
+
28
+ def self.base64_check(value)
29
+ /\A[=A-Za-z0-9+\/]*\z/.match?(value) && # allowable chars
30
+ value.length.remainder(4).zero? && # multiple of 4
31
+ !/=[^$=]/.match?(value) && # may only end with ='s
32
+ !/===/.match?(value) # at most 2 ='s
33
+ end
34
+
35
+ Dry::Validation.register_macro(:base64?) do
36
+ if key?
37
+ unless Aliquot::Validator.base64_check(value)
38
+ key.failure(CUSTOM_ERRORS[:base64?])
39
+ end
46
40
  end
41
+ end
47
42
 
48
- # We should figure out how strict we should be. Hopefully we can discard
49
- # the above Base64? predicate and use the following simpler one:
50
- #predicate(:strict_base64?) { |x| !!Base64.strict_decode64(x) rescue false }
43
+ def self.ans1_check(value)
44
+ OpenSSL::ASN1.decode(Base64.strict_decode64(value)) rescue false
45
+ end
51
46
 
52
- predicate(:pan?) { |x| match_b.call(x, /\A[1-9][0-9]{11,18}\z/) }
47
+ Dry::Validation.register_macro(:base64_asn1?) do
48
+ if key?
49
+ unless Aliquot::Validator.ans1_check(value)
50
+ key.failure(CUSTOM_ERRORS[:base64_asn1?])
51
+ end
52
+ end
53
+ end
53
54
 
54
- predicate(:eci?) { |x| str?(x) && match_b.call(x, /\A\d{1,2}\z/) }
55
+ Dry::Validation.register_macro(:pan?) do
56
+ if key?
57
+ unless /\A[1-9][0-9]{11,18}\z/.match?(value)
58
+ key.failure(CUSTOM_ERRORS[:pan?])
59
+ end
60
+ end
61
+ end
55
62
 
56
- predicate(:ec_public_key?) { |x| base64?(x) && OpenSSL::PKey::EC.new(Base64.decode64(x)).check_key rescue false }
63
+ Dry::Validation.register_macro(:ec_public_key?) do
64
+ if key?
65
+ begin
66
+ OpenSSL::PKey::EC.new(Base64.decode64(value)).check_key
67
+ rescue
68
+ key.failure(CUSTOM_ERRORS[:ec_public_key?])
69
+ end
70
+ end
71
+ end
57
72
 
58
- predicate(:json_string?) { |x| !!JSON.parse(x) rescue false }
73
+ Dry::Validation.register_macro(:eci?) do
74
+ if key?
75
+ unless /\A\d{1,2}\z/.match?(value)
76
+ key.failure(CUSTOM_ERRORS[:eci?])
77
+ end
78
+ end
79
+ end
59
80
 
60
- predicate(:integer_string?) { |x| str?(x) && match_b.call(x, /\A\d+\z/) }
81
+ Dry::Validation.register_macro(:integer_string?) do
82
+ if key?
83
+ unless /\A\d+\z/.match?(value)
84
+ key.failure(CUSTOM_ERRORS[:integer_string?])
85
+ end
86
+ end
87
+ end
61
88
 
62
- predicate(:month?) { |x| x.between?(1, 12) }
89
+ Dry::Validation.register_macro(:json?) do
90
+ if key?
91
+ json = JSON.parse(value) rescue false
92
+ key.failure(CUSTOM_ERRORS[:json?]) unless json
93
+ end
94
+ end
63
95
 
64
- predicate(:year?) { |x| x.between?(2000, 3000) }
96
+ Dry::Validation.register_macro(:month?) do
97
+ if key?
98
+ unless value.between?(1, 12)
99
+ key.failure(CUSTOM_ERRORS[:month?])
100
+ end
101
+ end
102
+ end
65
103
 
66
- predicate(:base64_asn1?) { |x| OpenSSL::ASN1.decode(Base64.strict_decode64(x)) rescue false }
104
+ Dry::Validation.register_macro(:year?) do
105
+ if key?
106
+ unless value.between?(2000, 3000)
107
+ key.failure(CUSTOM_ERRORS[:year?])
108
+ end
109
+ end
67
110
  end
68
111
 
69
- # Base for DRY-Validation schemas used in Aliquot.
70
- class BaseSchema < Dry::Validation::Schema::JSON
71
- predicates(Predicates)
72
- def self.messages
73
- super.merge(en: { errors: Predicates::CUSTOM_PREDICATE_ERRORS })
112
+ class SignedKeyContract < Dry::Validation::Contract
113
+ json do
114
+ required(:keyExpiration).filled(:str?)
115
+ required(:keyValue).filled(:str?)
74
116
  end
117
+ rule(:keyExpiration).validate(:integer_string?)
118
+ rule(:keyValue).validate(:ec_public_key?)
75
119
  end
76
120
 
77
- # Schema used for the 'intermediateSigningKey' hash included in ECv2.
78
- IntermediateSigningKeySchema = Dry::Validation.Schema(BaseSchema) do
79
- required(:signedKey).filled(:str?, :json_string?)
121
+ SignedKeySchema = SignedKeyContract.new
80
122
 
81
- # TODO: Check if elements of array are valid signatures
82
- required(:signatures).filled(:array?) { each { base64? & base64_asn1? } }
123
+ # Schema used for the 'intermediateSigningKey' hash included in ECv2.
124
+ class IntermediateSigningKeyContract < Dry::Validation::Contract
125
+ json do
126
+ required(:signedKey).filled(:str?)
127
+ required(:signatures).array(:str?)
128
+ end
129
+ rule(:signedKey).validate(:json?)
130
+ rule(:signatures).each do
131
+ key.failure('must be Base64') unless Aliquot::Validator.base64_check(value) &&
132
+ Aliquot::Validator.ans1_check(value)
133
+ end
83
134
  end
84
135
 
85
- SignedKeySchema = Dry::Validation.Schema(BaseSchema) do
86
- required(:keyExpiration).filled(:integer_string?)
87
- required(:keyValue).filled(:ec_public_key?)
88
- end
136
+ IntermediateSigningKeySchema = IntermediateSigningKeyContract.new
89
137
 
90
138
  # DRY-Validation schema for Google Pay token
91
- TokenSchema = Dry::Validation.Schema(BaseSchema) do
92
- required(:signature).filled(:str?, :base64?, :base64_asn1?)
93
-
94
- # Currently supposed to be ECv1, but may evolve.
95
- required(:protocolVersion).filled(:str?)
96
- required(:signedMessage).filled(:str?, :json_string?)
97
-
98
- optional(:intermediateSigningKey).schema(IntermediateSigningKeySchema)
139
+ class TokenContract < Dry::Validation::Contract
140
+ json do
141
+ required(:signature).filled(:str?)
142
+ required(:signedMessage).filled(:str?)
143
+ required(:protocolVersion).filled(:str?)
144
+ optional(:intermediateSigningKey).hash(IntermediateSigningKeyContract.new.schema)
145
+ end
146
+ rule(:signature).validate(:base64?, :base64_asn1?)
147
+ rule(:signedMessage).validate(:json?)
99
148
 
100
- rule('ECv2 implies intermediateSigningKey': %i[protocolVersion intermediateSigningKey]) do |version, intermediatekey|
101
- version.eql?('ECv2') > intermediatekey.filled?
149
+ rule(:intermediateSigningKey) do
150
+ key.failure('is missing') if 'ECv2'.eql?(values[:protocolVersion]) &&
151
+ values[:intermediateSigningKey].nil?
102
152
  end
103
153
  end
104
154
 
155
+ TokenSchema = TokenContract.new
156
+
105
157
  # DRY-Validation schema for signedMessage component Google Pay token
106
- SignedMessageSchema = Dry::Validation.Schema(BaseSchema) do
107
- required(:encryptedMessage).filled(:str?, :base64?)
108
- required(:ephemeralPublicKey).filled(:str?, :base64?).value(size?: 44)
109
- required(:tag).filled(:str?, :base64?)
158
+ class SignedMessageContract < Dry::Validation::Contract
159
+ json do
160
+ required(:encryptedMessage).filled(:str?)
161
+ required(:ephemeralPublicKey).filled(:str?)
162
+ required(:tag).filled(:str?)
163
+ end
164
+ rule(:encryptedMessage).validate(:base64?)
165
+ rule(:ephemeralPublicKey).validate(:base64?)
166
+ rule(:tag).validate(:base64?)
110
167
  end
111
168
 
112
- # DRY-Validation schema for paymentMethodDetails component Google Pay token
113
- PaymentMethodDetailsSchema = Dry::Validation.Schema(BaseSchema) do
114
- required(:pan).filled(:integer_string?, :pan?)
115
- required(:expirationMonth).filled(:int?, :month?)
116
- required(:expirationYear).filled(:int?, :year?)
117
- required(:authMethod).filled(:str?, included_in?: %w[PAN_ONLY CRYPTOGRAM_3DS])
118
-
119
- optional(:cryptogram).filled(:str?)
120
- optional(:eciIndicator).filled(:str?, :eci?)
169
+ SignedMessageSchema = SignedMessageContract.new
121
170
 
122
- rule('when authMethod is CRYPTOGRAM_3DS, cryptogram': %i[authMethod cryptogram]) do |method, cryptogram|
123
- method.eql?('CRYPTOGRAM_3DS') > cryptogram.filled?
171
+ # DRY-Validation schema for paymentMethodDetails component Google Pay token
172
+ class PaymentMethodDetailsContract < Dry::Validation::Contract
173
+ json do
174
+ required(:pan).filled(:str?)
175
+ required(:expirationMonth).filled(:int?)
176
+ 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
+ end
182
+ rule(:pan).validate(:integer_string?, :pan?)
183
+ rule(:expirationMonth).validate(:month?)
184
+ rule(:expirationYear).validate(:year?)
185
+ rule(:eciIndicator).validate(:eci?)
186
+
187
+ rule(:cryptogram) do
188
+ key.failure('is missing') if 'CRYPTOGRAM_3DS'.eql?(values[:authMethod]) &&
189
+ values[:cryptogram].nil?
124
190
  end
125
191
 
126
- rule('when authMethod is PAN_ONLY, eciIndicator': %i[authMethod eciIndicator]) do |method, eci|
127
- method.eql?('PAN_ONLY').then(eci.none?)
192
+ rule(:cryptogram) do
193
+ key.failure('cannot be defined') if 'PAN_ONLY'.eql?(values[:authMethod]) &&
194
+ !values[:cryptogram].nil?
128
195
  end
129
196
 
130
- rule('when authMethod is PAN_ONLY, cryptogram': %i[authMethod cryptogram]) do |method, cryptogram|
131
- method.eql?('PAN_ONLY').then(cryptogram.none?)
197
+ rule(:eciIndicator) do
198
+ key.failure('cannot be defined') if 'PAN_ONLY'.eql?(values[:authMethod]) &&
199
+ !values[:eciIndicator].nil?
132
200
  end
133
201
  end
134
202
 
203
+ PaymentMethodDetailsSchema = PaymentMethodDetailsContract.new
204
+
135
205
  # DRY-Validation schema for encryptedMessage component Google Pay token
136
- EncryptedMessageSchema = Dry::Validation.Schema(BaseSchema) do
137
- required(:messageExpiration).filled(:str?, :integer_string?)
138
- required(:messageId).filled(:str?)
139
- required(:paymentMethod).filled(:str?, eql?: 'CARD')
140
- required(:paymentMethodDetails).schema(PaymentMethodDetailsSchema)
206
+ class EncryptedMessageContract < Dry::Validation::Contract
207
+ json do
208
+ required(:messageExpiration).filled(:str?)
209
+ required(:messageId).filled(:str?)
210
+ required(:paymentMethod).filled(:str?)
211
+ required(:paymentMethodDetails).filled(:hash).schema(PaymentMethodDetailsContract.schema)
212
+ end
213
+ rule(:messageExpiration).validate(:integer_string?)
214
+ rule(:paymentMethod) do
215
+ key.failure('must be equal to CARD') unless 'CARD'.eql?(value)
216
+ end
141
217
  end
142
218
 
219
+ EncryptedMessageSchema = EncryptedMessageContract.new
220
+
143
221
  module InstanceMethods
144
222
  attr_reader :output
145
223
 
146
224
  def validate
147
225
  @validation ||= @schema.call(@input)
148
- @output = @validation.output
226
+ @output = @validation.to_h
149
227
  return true if @validation.success?
150
228
  raise Aliquot::ValidationError, "validation error(s), #{errors_formatted}"
151
229
  end
@@ -176,7 +254,9 @@ module Aliquot
176
254
  # Class for validating a Google Pay token
177
255
  class Token
178
256
  include InstanceMethods
257
+
179
258
  class Error < ::Aliquot::Error; end
259
+
180
260
  def initialize(input)
181
261
  @input = input
182
262
  @schema = TokenSchema
@@ -186,7 +266,9 @@ module Aliquot
186
266
  # Class for validating the SignedMessage component of a Google Pay token
187
267
  class SignedMessage
188
268
  include InstanceMethods
269
+
189
270
  class Error < ::Aliquot::Error; end
271
+
190
272
  def initialize(input)
191
273
  @input = input
192
274
  @schema = SignedMessageSchema
@@ -196,7 +278,9 @@ module Aliquot
196
278
  # Class for validating the encryptedMessage component of a Google Pay token
197
279
  class EncryptedMessageValidator
198
280
  include InstanceMethods
281
+
199
282
  class Error < ::Aliquot::Error; end
283
+
200
284
  def initialize(input)
201
285
  @input = input
202
286
  @schema = EncryptedMessageSchema
@@ -205,7 +289,9 @@ module Aliquot
205
289
 
206
290
  class SignedKeyValidator
207
291
  include InstanceMethods
292
+
208
293
  class Error < ::Aliquot::Error; end
294
+
209
295
  def initialize(input)
210
296
  @input = input
211
297
  @schema = SignedKeySchema
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: 0.15.0
4
+ version: 2.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Clearhaus
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-01-17 00:00:00.000000000 Z
11
+ date: 2022-09-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: dry-validation
@@ -16,56 +16,84 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '0'
19
+ version: '1.8'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '0'
26
+ version: '1.8'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: excon
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '0'
33
+ version: 0.71.0
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '0'
40
+ version: 0.71.0
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: hkdf
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: '0'
47
+ version: '0.3'
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: '0'
54
+ version: '0.3'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: aliquot-pay
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
59
  - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: 0.12.0
61
+ version: 2.1.1
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: 0.12.0
68
+ version: 2.1.1
69
+ - !ruby/object:Gem::Dependency
70
+ name: bundler
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '2.3'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '2.3'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rake
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '13.0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '13.0'
69
97
  - !ruby/object:Gem::Dependency
70
98
  name: rspec
71
99
  requirement: !ruby/object:Gem::Requirement
@@ -80,6 +108,20 @@ dependencies:
80
108
  - - "~>"
81
109
  - !ruby/object:Gem::Version
82
110
  version: '3'
111
+ - !ruby/object:Gem::Dependency
112
+ name: pry
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
83
125
  description:
84
126
  email: hello@clearhaus.com
85
127
  executables: []
@@ -100,16 +142,16 @@ require_paths:
100
142
  - lib
101
143
  required_ruby_version: !ruby/object:Gem::Requirement
102
144
  requirements:
103
- - - ">="
145
+ - - "~>"
104
146
  - !ruby/object:Gem::Version
105
- version: '0'
147
+ version: '2.7'
106
148
  required_rubygems_version: !ruby/object:Gem::Requirement
107
149
  requirements:
108
150
  - - ">="
109
151
  - !ruby/object:Gem::Version
110
152
  version: '0'
111
153
  requirements: []
112
- rubygems_version: 3.0.2
154
+ rubygems_version: 3.1.6
113
155
  signing_key:
114
156
  specification_version: 4
115
157
  summary: Validates Google Pay tokens