truelayer-signing 0.1.1 → 0.1.2
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 +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
|