truelayer-signing 0.1.1 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +4 -0
- data/examples/sign-request/Gemfile.lock +2 -3
- data/lib/truelayer-signing/jwt.rb +23 -2
- data/lib/truelayer-signing/signer.rb +2 -1
- data/lib/truelayer-signing/verifier.rb +2 -2
- data/test/test-truelayer-signing.rb +54 -0
- data/truelayer-signing.gemspec +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8cc4b5beb4b79ccfafd7350d4882927d45abea2580d4d4d869d39faae157498d
|
4
|
+
data.tar.gz: ab43241ee2475b2797ff43fc5c142b778ff4e4ef28d042a123b9ac8179d913aa
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6e208e6b3ed16190946cdeceae856ebcddc42b472458b86c527e0dfe52a67fe0d33e954c018f63fcb8502b659081aa35522516f9dacfb12f492b36a7830fe6b6
|
7
|
+
data.tar.gz: 3282b084e0907c8c709dfa2f3d2bef71527bca7181c342a24de63262c70ffa3a9e41f4437eb77f667a1e9c6a45776b8db6549ce709b244128b5fb58006b4afea
|
data/CHANGELOG.md
CHANGED
@@ -23,7 +23,7 @@ GEM
|
|
23
23
|
rake (~> 13.0)
|
24
24
|
public_suffix (5.0.1)
|
25
25
|
rake (13.0.6)
|
26
|
-
truelayer-signing (0.2
|
26
|
+
truelayer-signing (0.1.2)
|
27
27
|
jwt (= 2.6)
|
28
28
|
unf (0.1.4)
|
29
29
|
unf_ext
|
@@ -31,11 +31,10 @@ GEM
|
|
31
31
|
|
32
32
|
PLATFORMS
|
33
33
|
arm64-darwin-21
|
34
|
-
ruby
|
35
34
|
|
36
35
|
DEPENDENCIES
|
37
36
|
http
|
38
37
|
truelayer-signing
|
39
38
|
|
40
39
|
BUNDLED WITH
|
41
|
-
2.4.
|
40
|
+
2.4.13
|
@@ -2,14 +2,16 @@
|
|
2
2
|
# It prevents the payload from being systematically converted to and from JSON.
|
3
3
|
# To be changed in the 'jwt' gem directly, or hard-coded in this library.
|
4
4
|
module JWT
|
5
|
-
|
5
|
+
module_function
|
6
|
+
|
7
|
+
class TrueLayerEncode < Encode
|
6
8
|
# See https://github.com/jwt/ruby-jwt/blob/main/lib/jwt/encode.rb#L53-L55
|
7
9
|
private def encode_payload
|
8
10
|
::JWT::Base64.url_encode(@payload)
|
9
11
|
end
|
10
12
|
end
|
11
13
|
|
12
|
-
class Decode
|
14
|
+
class TrueLayerDecode < Decode
|
13
15
|
# See https://github.com/jwt/ruby-jwt/blob/main/lib/jwt/decode.rb#L154-L156
|
14
16
|
private def payload
|
15
17
|
@payload ||= ::JWT::Base64.url_decode(@segments[1])
|
@@ -17,4 +19,23 @@ module JWT
|
|
17
19
|
raise JWT::DecodeError, 'Invalid segment encoding'
|
18
20
|
end
|
19
21
|
end
|
22
|
+
|
23
|
+
def truelayer_encode(payload, key, algorithm, headers)
|
24
|
+
TrueLayerEncode.new(
|
25
|
+
payload: payload,
|
26
|
+
key: key,
|
27
|
+
algorithm: algorithm,
|
28
|
+
headers: headers
|
29
|
+
).segments
|
30
|
+
end
|
31
|
+
|
32
|
+
def truelayer_decode(jwt, key, verify, options, &keyfinder)
|
33
|
+
TrueLayerDecode.new(
|
34
|
+
jwt,
|
35
|
+
key,
|
36
|
+
verify,
|
37
|
+
configuration.decode.to_h.merge(options),
|
38
|
+
&keyfinder
|
39
|
+
).decode_segments
|
40
|
+
end
|
20
41
|
end
|
@@ -9,7 +9,8 @@ module TrueLayerSigning
|
|
9
9
|
jws_header_args = { tl_headers: headers }
|
10
10
|
jws_header_args[:jku] = jws_jku if jws_jku
|
11
11
|
jws_header = TrueLayerSigning::JwsHeader.new(jws_header_args).to_h
|
12
|
-
jwt = JWT.
|
12
|
+
jwt = JWT.truelayer_encode(build_signing_payload, private_key, TrueLayerSigning.algorithm,
|
13
|
+
jws_header)
|
13
14
|
header, _, signature = jwt.split(".")
|
14
15
|
|
15
16
|
"#{header}..#{signature}"
|
@@ -27,7 +27,7 @@ module TrueLayerSigning
|
|
27
27
|
jwt_options = { algorithm: TrueLayerSigning.algorithm }
|
28
28
|
|
29
29
|
begin
|
30
|
-
JWT.
|
30
|
+
JWT.truelayer_decode(full_signature, public_key, true, jwt_options)
|
31
31
|
rescue JWT::VerificationError
|
32
32
|
@path = path.end_with?("/") && path[0...-1] || path + "/"
|
33
33
|
payload_b64 = Base64.urlsafe_encode64(build_signing_payload(ordered_headers),
|
@@ -35,7 +35,7 @@ module TrueLayerSigning
|
|
35
35
|
full_signature = [jws_header_b64, payload_b64, signature_b64].join(".")
|
36
36
|
|
37
37
|
begin
|
38
|
-
JWT.
|
38
|
+
JWT.truelayer_decode(full_signature, public_key, true, jwt_options)
|
39
39
|
rescue
|
40
40
|
raise(Error, "Signature verification failed")
|
41
41
|
end
|
@@ -369,4 +369,58 @@ class TrueLayerSigningTest < Minitest::Test
|
|
369
369
|
assert(result.first
|
370
370
|
.start_with?("POST /merchant_accounts/a61acaef-ee05-4077-92f3-25543a11bd8d/sweeping\n"))
|
371
371
|
end
|
372
|
+
|
373
|
+
# TODO: remove if/when we get rid of `lib/truelayer-signing/jwt.rb`
|
374
|
+
def test_jwt_encode_and_decode_should_succeed
|
375
|
+
payload_object = { currency: "GBP", max_amount_in_minor: 50_000_00 }
|
376
|
+
token_when_object = "eyJhbGciOiJIUzI1NiJ9.eyJjdXJyZW5jeSI6IkdCUCIsIm1heF9hbW" +
|
377
|
+
"91bnRfaW5fbWlub3IiOjUwMDAwMDB9.SjbwZCqTl6G7LQNs_M6oQhwl3a9rbqO7p3cVncLtgZY"
|
378
|
+
token_when_json = "eyJhbGciOiJIUzI1NiJ9.IntcImN1cnJlbmN5XCI6XCJHQlBcIixcIm1h" +
|
379
|
+
"eF9hbW91bnRfaW5fbWlub3JcIjo1MDAwMDAwfSI.rvCcgu-JevsNxbjUwJiFOuTd0hzVKvPK5RvGmaoDc7E"
|
380
|
+
|
381
|
+
# succeeds with a hash object
|
382
|
+
assert_equal(token_when_object, JWT.encode(payload_object, "12345", "HS256", {}))
|
383
|
+
assert_equal(
|
384
|
+
[{ "currency" => "GBP", "max_amount_in_minor" => 50_000_00 }, { "alg" => "HS256" }],
|
385
|
+
JWT.decode(token_when_object, "12345", true, algorithm: "HS256")
|
386
|
+
)
|
387
|
+
|
388
|
+
# succeeds with a JSON string
|
389
|
+
assert_equal(token_when_json, JWT.encode(payload_object.to_json, "12345", "HS256", {}))
|
390
|
+
assert_equal(
|
391
|
+
["{\"currency\":\"GBP\",\"max_amount_in_minor\":5000000}", { "alg" => "HS256" }],
|
392
|
+
JWT.decode(token_when_json, "12345", true, algorithm: "HS256")
|
393
|
+
)
|
394
|
+
end
|
395
|
+
|
396
|
+
# TODO: remove if/when we get rid of `lib/truelayer-signing/jwt.rb`
|
397
|
+
def test_jwt_truelayer_encode_and_decode_when_given_json_should_succeed
|
398
|
+
payload_json = { currency: "GBP", max_amount_in_minor: 50_000_00 }.to_json
|
399
|
+
token_when_json = "eyJhbGciOiJIUzI1NiJ9.eyJjdXJyZW5jeSI6IkdCUCIsIm1heF9hbW9" +
|
400
|
+
"1bnRfaW5fbWlub3IiOjUwMDAwMDB9.SjbwZCqTl6G7LQNs_M6oQhwl3a9rbqO7p3cVncLtgZY"
|
401
|
+
|
402
|
+
assert_equal(token_when_json, JWT.truelayer_encode(payload_json, "12345", "HS256", {}))
|
403
|
+
assert_equal(
|
404
|
+
["{\"currency\":\"GBP\",\"max_amount_in_minor\":5000000}", { "alg" => "HS256" }],
|
405
|
+
JWT.truelayer_decode(token_when_json, "12345", true, algorithm: "HS256")
|
406
|
+
)
|
407
|
+
end
|
408
|
+
|
409
|
+
# TODO: remove if/when we get rid of `lib/truelayer-signing/jwt.rb`
|
410
|
+
def test_jwt_truelayer_encode_when_given_a_hash_should_not_succeed
|
411
|
+
payload_object = { currency: "GBP", max_amount_in_minor: 50_000_00 }
|
412
|
+
error = assert_raises(TypeError) { JWT.truelayer_encode(payload_object, "12345", "HS256", {}) }
|
413
|
+
assert_equal("no implicit conversion of Hash into String", error.message)
|
414
|
+
end
|
415
|
+
|
416
|
+
# TODO: remove if/when we get rid of `lib/truelayer-signing/jwt.rb`
|
417
|
+
def test_jwt_truelayer_decode_when_given_a_hash_should_succeed
|
418
|
+
token_when_object = "eyJhbGciOiJIUzI1NiJ9.eyJjdXJyZW5jeSI6IkdCUCIsIm1heF9hbW" +
|
419
|
+
"91bnRfaW5fbWlub3IiOjUwMDAwMDB9.SjbwZCqTl6G7LQNs_M6oQhwl3a9rbqO7p3cVncLtgZY"
|
420
|
+
|
421
|
+
assert_equal(
|
422
|
+
["{\"currency\":\"GBP\",\"max_amount_in_minor\":5000000}", { "alg" => "HS256" }],
|
423
|
+
JWT.truelayer_decode(token_when_object, "12345", true, algorithm: "HS256")
|
424
|
+
)
|
425
|
+
end
|
372
426
|
end
|
data/truelayer-signing.gemspec
CHANGED
@@ -2,7 +2,7 @@ $LOAD_PATH.unshift(::File.join(::File.dirname(__FILE__), "lib"))
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = "truelayer-signing"
|
5
|
-
s.version = "0.1.
|
5
|
+
s.version = "0.1.2"
|
6
6
|
s.summary = "Ruby gem to produce and verify TrueLayer API requests signatures"
|
7
7
|
s.description = "TrueLayer provides instant access to open banking to " \
|
8
8
|
"easily integrate next-generation payments and financial data into any app." \
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: truelayer-signing
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kevin Plattret
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-05-
|
11
|
+
date: 2023-05-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: jwt
|