aliquot 0.15.0 → 2.1.1

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.
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