jwt 1.5.6 → 2.2.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.
Files changed (58) hide show
  1. checksums.yaml +5 -5
  2. data/.ebert.yml +18 -0
  3. data/.gitignore +1 -1
  4. data/.rubocop.yml +96 -0
  5. data/.travis.yml +26 -10
  6. data/AUTHORS +84 -0
  7. data/Appraisals +18 -0
  8. data/CHANGELOG.md +296 -10
  9. data/Gemfile +0 -1
  10. data/README.md +182 -64
  11. data/lib/jwt.rb +14 -176
  12. data/lib/jwt/algos/ecdsa.rb +35 -0
  13. data/lib/jwt/algos/eddsa.rb +23 -0
  14. data/lib/jwt/algos/hmac.rb +34 -0
  15. data/lib/jwt/algos/ps.rb +43 -0
  16. data/lib/jwt/algos/rsa.rb +19 -0
  17. data/lib/jwt/algos/unsupported.rb +16 -0
  18. data/lib/jwt/base64.rb +19 -0
  19. data/lib/jwt/claims_validator.rb +33 -0
  20. data/lib/jwt/decode.rb +81 -31
  21. data/lib/jwt/default_options.rb +15 -0
  22. data/lib/jwt/encode.rb +68 -0
  23. data/lib/jwt/error.rb +6 -0
  24. data/lib/jwt/json.rb +10 -9
  25. data/lib/jwt/jwk.rb +31 -0
  26. data/lib/jwt/jwk/key_finder.rb +57 -0
  27. data/lib/jwt/jwk/rsa.rb +54 -0
  28. data/lib/jwt/security_utils.rb +57 -0
  29. data/lib/jwt/signature.rb +54 -0
  30. data/lib/jwt/verify.rb +45 -53
  31. data/lib/jwt/version.rb +3 -3
  32. data/ruby-jwt.gemspec +11 -7
  33. metadata +76 -67
  34. data/Manifest +0 -8
  35. data/spec/fixtures/certs/ec256-private.pem +0 -8
  36. data/spec/fixtures/certs/ec256-public.pem +0 -4
  37. data/spec/fixtures/certs/ec256-wrong-private.pem +0 -8
  38. data/spec/fixtures/certs/ec256-wrong-public.pem +0 -4
  39. data/spec/fixtures/certs/ec384-private.pem +0 -9
  40. data/spec/fixtures/certs/ec384-public.pem +0 -5
  41. data/spec/fixtures/certs/ec384-wrong-private.pem +0 -9
  42. data/spec/fixtures/certs/ec384-wrong-public.pem +0 -5
  43. data/spec/fixtures/certs/ec512-private.pem +0 -10
  44. data/spec/fixtures/certs/ec512-public.pem +0 -6
  45. data/spec/fixtures/certs/ec512-wrong-private.pem +0 -10
  46. data/spec/fixtures/certs/ec512-wrong-public.pem +0 -6
  47. data/spec/fixtures/certs/rsa-1024-private.pem +0 -15
  48. data/spec/fixtures/certs/rsa-1024-public.pem +0 -6
  49. data/spec/fixtures/certs/rsa-2048-private.pem +0 -27
  50. data/spec/fixtures/certs/rsa-2048-public.pem +0 -9
  51. data/spec/fixtures/certs/rsa-2048-wrong-private.pem +0 -27
  52. data/spec/fixtures/certs/rsa-2048-wrong-public.pem +0 -9
  53. data/spec/fixtures/certs/rsa-4096-private.pem +0 -51
  54. data/spec/fixtures/certs/rsa-4096-public.pem +0 -14
  55. data/spec/integration/readme_examples_spec.rb +0 -190
  56. data/spec/jwt/verify_spec.rb +0 -197
  57. data/spec/jwt_spec.rb +0 -240
  58. data/spec/spec_helper.rb +0 -31
@@ -1,9 +0,0 @@
1
- -----BEGIN PUBLIC KEY-----
2
- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4GzZTLU48c4WbyvHi+QK
3
- rB71x+T0eq5hqDbQqnlYjhD1Ika7io1iplsdJWJuyxfYbUkb2Ol0fj4koZ/GS6lg
4
- CZr4+8UHbr1qf0Eu5HZSpszs2YxY8U5RHnrpw67co7hlgAR9HbyNf5XIYgLV9ldH
5
- H/eazwnc3F/hgNsV0xjScVilejgocJ4zcsyymvW8t42lteM7bI867ZuJhGop/V+Y
6
- 0HFyrMsPoQyLuCUpr6ulOfrkr7ZOdhAIG8r1HcjOp/AUjM15vfXcbUZjkM/Vloif
7
- X1YitU3upMGJ8/DpFGffMOImrn5r6BT494V8rRyN2qvQoAkLJpqZ0avLxwiR2lgV
8
- QQIDAQAB
9
- -----END PUBLIC KEY-----
@@ -1,27 +0,0 @@
1
- -----BEGIN RSA PRIVATE KEY-----
2
- MIIEpAIBAAKCAQEAzHAVGaW9j4l3/b4ngcjjoIoIcnsQEWOMqErb5VhLZMGIq1gE
3
- O5qxPDAwooKsNotzcAOB3ZyLn7p5D+dmOrNUYkYWgYITNGeSifrnVqQugd5Fh1L8
4
- K7zOGltUo2UtjbN4uJ56tzxBMZp2wejs2/Qu0eu0xZK3To+YkDcWOk92rmNgmUSQ
5
- C/kNyIOj+yBvOo3wTk6HvbhoIarCgJ6Lay1v/hMLyQLzwRY/Qfty1FTIDyTv2dch
6
- 47FsfkZ1KAL+MbUnHuCBPzGxRjXa8Iy9Z7YGxrYasUt1b0um64bscxoIiCu8yLL8
7
- jlg01Rwrjr/MTwKRhwXlMp8B7HTonwtaG6arJwIDAQABAoIBAGFR4dmJusl/qW1T
8
- fj8cQLAFxaupxaZhe24J5NAyzgEy2Dqo9ariIwkB78UM66ozjEqAgOvcP+NTw5m8
9
- kD/VapA1yTTxlO7XdzzUAhiOo80S4IphCMZRZNPLMmluGtdf3lIUr1pXBrn0TCBX
10
- H5o9jaREzpNXGof9d6T/dEdh2J9+uE/p1xE5GSxQfaPheZzCG7636La/DcArg/UR
11
- +TusPqp62BEmk96pE/KKJRmEeH+WnPfSh6sMpLxi3hkEU7AynpliGT6Z6xV4csBI
12
- S/rdpkcj5DWpbnQzkwdrnL2Q+POEq/vlx5/NlezvtQPNLvQWDyY4yBCoMKGb3EbX
13
- xrxP7MECgYEA/kwe4P0Mqk+087IyhjDBGPfcMt8gfYc9nzNfIYSWdSwuSag/hqHq
14
- I4GwHQzUV9ix3iM6w5hin10yAzWxCYZg9hquV+lSvNNpGB76FX6oOqwuAhyQMRwv
15
- eW+VUyfFXeJugwL5JuIaNTvwPpQVDHYtELLifie+uzJ5HC6dhg/XchcCgYEAzc5/
16
- +IXjOlExd/mBgFk/5Y87ifA0ZOgbaJXifYgU0aNSgz1piHxU3n2p4jJ9lSdwwCl2
17
- Fb5EN7666t20PL5QcXJ5ZdaTRLzRlYiqTWzfYHBgttbB1Jl3Ed9GsKuzRgaRqGFC
18
- ANJSqZlKG0NZ3keRtuKdFwq+IVOnsQr9g0TZiXECgYEAqUgtCiMKCloTIGMQpSnR
19
- cXiWWjsUmturls4Q1vQ3YHrvuVLKLyqb/dT4Uu5WcMAs765OESThCit0/pQAbVHK
20
- PCpYwubskAzAGjGM00BEZwJ1gixXhIm5xMIWCowgI7Z3ULlq+IptXeCvtkjHlksZ
21
- BtO+WLLGkkEwRCV38WWcSzMCgYA/Xxqgl/mD94RYAQgTUWgPc69Nph08BQyLg7ue
22
- E8z1UGkT6FEaqc4oRGGPOSTaTK63PQ0TXOb8k0pTD7l0CtYSWMFwzkXCoLGYbeCi
23
- vqd5tqDRLAe7QxYa9rl5pSUqptMrGeeNATZa6sya4H5Hp5oCyny8n54z/OJh7ZRq
24
- W0TwwQKBgQDDP7ksm2pcqadaVAmODdOlaDHbaEcxp8wN7YVz0lM3UpJth96ukbj7
25
- S39eJhXYWOn6oJQb/lN9fGOYqjg3y6IchGZDp67ATvWYvn/NY0R7mt4K4oHx5TuN
26
- rSQlP3WmOGv8Kemw892uRfW/jZyBEHhsfS213WDttVPn9F635GdNWw==
27
- -----END RSA PRIVATE KEY-----
@@ -1,9 +0,0 @@
1
- -----BEGIN PUBLIC KEY-----
2
- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzHAVGaW9j4l3/b4ngcjj
3
- oIoIcnsQEWOMqErb5VhLZMGIq1gEO5qxPDAwooKsNotzcAOB3ZyLn7p5D+dmOrNU
4
- YkYWgYITNGeSifrnVqQugd5Fh1L8K7zOGltUo2UtjbN4uJ56tzxBMZp2wejs2/Qu
5
- 0eu0xZK3To+YkDcWOk92rmNgmUSQC/kNyIOj+yBvOo3wTk6HvbhoIarCgJ6Lay1v
6
- /hMLyQLzwRY/Qfty1FTIDyTv2dch47FsfkZ1KAL+MbUnHuCBPzGxRjXa8Iy9Z7YG
7
- xrYasUt1b0um64bscxoIiCu8yLL8jlg01Rwrjr/MTwKRhwXlMp8B7HTonwtaG6ar
8
- JwIDAQAB
9
- -----END PUBLIC KEY-----
@@ -1,51 +0,0 @@
1
- -----BEGIN RSA PRIVATE KEY-----
2
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- vgSN7aCmI6MBUUB5wDP2K8zX2sh40/uPDVSd6ei1vl3DpPk+h8iExx6AzbohfqZ+
11
- 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
- EWGbN++jcdV5oJX6fsC66nOmKlntYwCL/pRww+oLsbzF8J3dxeDbKNF9JDsCAwEA
13
- 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
- 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
- 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
- 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
- rrD3b136x7/XvqC6pS+bxuvJ8YK4R4qeu42NYT07GOcK/pk8lz0JWTodIt2eevqV
18
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- K5ZHS4YuPKLl0tZMaOkPco9s6t4ES/Y317zQoTzUkAAkkFO4QPzRZL0ESqVBNR0h
29
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- UrcNKOJkFIj7jJUCzv6vcy++hMJEbNXnnTVRnky6e9C2vwzMl33njntapg==
51
- -----END RSA PRIVATE KEY-----
@@ -1,14 +0,0 @@
1
- -----BEGIN PUBLIC KEY-----
2
- MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAqETmgWBi5rCmb7euJplA
3
- /9xs65+bncc9Yvs5zjyycXSW82JfRuyguGm0OvA2wog24dR4N2kT/87DcGtp5JqJ
4
- WADVFNr+2V2r6i57/OMLruRpn3p2r95dmo0COE+BxPFl7XEBT8JbH57ZtpgcB3/x
5
- kS14nLOWFf96hrXPlXJC+VMVKVZmA8k2LRh42vT5wUf4U0Doy/p7yFNSFFa6Q8ww
6
- e4TBy/z/f+rhFD1w8rxlYjallee/ocm7bjZCwbJGMm7orLViqWfsFX3O35PeoJ5h
7
- /7uJ7iRwvTFERkTdwWP/0BeKBeItBR3YFc2mut+V9W+WKRkMSL6Crc+oVSx3p8aB
8
- 7j9SZFzQiRtes4BYETpX1xl2mgIq5hvsFbLw7ESrlIodiwUMTrSIid2DQ6q80kv1
9
- zXPr4+Id6L0sJLxPCaXnTmNtasSwyedJJYxLjwhHJwtzFAeaq18H3O791YKhjAJ6
10
- YxK3zJ59jTE6Pkvqjq183f2PGHVRvgSN7aCmI6MBUUB5wDP2K8zX2sh40/uPDVSd
11
- 6ei1vl3DpPk+h8iExx6AzbohfqZ+5RUUNx127L3MaQvOVC5TxV+R99gwKW++wzcV
12
- uO3m2KqVUj+K1uYBy3KBCUMBbckpEWGbN++jcdV5oJX6fsC66nOmKlntYwCL/pRw
13
- w+oLsbzF8J3dxeDbKNF9JDsCAwEAAQ==
14
- -----END PUBLIC KEY-----
@@ -1,190 +0,0 @@
1
- # frozen_string_literal: true
2
- require_relative '../spec_helper'
3
- require 'jwt'
4
-
5
- describe 'README.md code test' do
6
- context 'algorithm usage' do
7
- let(:payload) { { data: 'test' } }
8
-
9
- it 'NONE' do
10
- token = JWT.encode payload, nil, 'none'
11
- decoded_token = JWT.decode token, nil, false
12
-
13
- expect(token).to eq 'eyJ0eXAiOiJKV1QiLCJhbGciOiJub25lIn0.eyJkYXRhIjoidGVzdCJ9.'
14
- expect(decoded_token).to eq [
15
- { 'data' => 'test' },
16
- { 'typ' => 'JWT', 'alg' => 'none' }
17
- ]
18
- end
19
-
20
- it 'HMAC' do
21
- token = JWT.encode payload, 'my$ecretK3y', 'HS256'
22
- decoded_token = JWT.decode token, 'my$ecretK3y', false
23
-
24
- expect(token).to eq 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJkYXRhIjoidGVzdCJ9.ZxW8go9hz3ETCSfxFxpwSkYg_602gOPKearsf6DsxgY'
25
- expect(decoded_token).to eq [
26
- { 'data' => 'test' },
27
- { 'typ' => 'JWT', 'alg' => 'HS256' }
28
- ]
29
- end
30
-
31
- it 'RSA' do
32
- rsa_private = OpenSSL::PKey::RSA.generate 2048
33
- rsa_public = rsa_private.public_key
34
-
35
- token = JWT.encode payload, rsa_private, 'RS256'
36
- decoded_token = JWT.decode token, rsa_public, true, algorithm: 'RS256'
37
-
38
- expect(decoded_token).to eq [
39
- { 'data' => 'test' },
40
- { 'typ' => 'JWT', 'alg' => 'RS256' }
41
- ]
42
- end
43
-
44
- it 'ECDSA' do
45
- ecdsa_key = OpenSSL::PKey::EC.new 'prime256v1'
46
- ecdsa_key.generate_key
47
- ecdsa_public = OpenSSL::PKey::EC.new ecdsa_key
48
- ecdsa_public.private_key = nil
49
-
50
- token = JWT.encode payload, ecdsa_key, 'ES256'
51
- decoded_token = JWT.decode token, ecdsa_public, true, algorithm: 'ES256'
52
-
53
- expect(decoded_token).to eq [
54
- { 'data' => 'test' },
55
- { 'typ' => 'JWT', 'alg' => 'ES256' }
56
- ]
57
- end
58
- end
59
-
60
- context 'claims' do
61
- let(:hmac_secret) { 'MyP4ssW0rD' }
62
-
63
- context 'exp' do
64
- it 'without leeway' do
65
- exp = Time.now.to_i + 4 * 3600
66
- exp_payload = { data: 'data', exp: exp }
67
-
68
- token = JWT.encode exp_payload, hmac_secret, 'HS256'
69
-
70
- expect do
71
- JWT.decode token, hmac_secret, true, algorithm: 'HS256'
72
- end.not_to raise_error
73
- end
74
-
75
- it 'with leeway' do
76
- exp = Time.now.to_i - 10
77
- leeway = 30 # seconds
78
-
79
- exp_payload = { data: 'data', exp: exp }
80
-
81
- token = JWT.encode exp_payload, hmac_secret, 'HS256'
82
-
83
- expect do
84
- JWT.decode token, hmac_secret, true, leeway: leeway, algorithm: 'HS256'
85
- end.not_to raise_error
86
- end
87
- end
88
-
89
- context 'nbf' do
90
- it 'without leeway' do
91
- nbf = Time.now.to_i - 3600
92
- nbf_payload = { data: 'data', nbf: nbf }
93
- token = JWT.encode nbf_payload, hmac_secret, 'HS256'
94
-
95
- expect do
96
- JWT.decode token, hmac_secret, true, algorithm: 'HS256'
97
- end.not_to raise_error
98
- end
99
-
100
- it 'with leeway' do
101
- nbf = Time.now.to_i + 10
102
- leeway = 30
103
- nbf_payload = { data: 'data', nbf: nbf }
104
- token = JWT.encode nbf_payload, hmac_secret, 'HS256'
105
-
106
- expect do
107
- JWT.decode token, hmac_secret, true, leeway: leeway, algorithm: 'HS256'
108
- end.not_to raise_error
109
- end
110
- end
111
-
112
- it 'iss' do
113
- iss = 'My Awesome Company Inc. or https://my.awesome.website/'
114
- iss_payload = { data: 'data', iss: iss }
115
-
116
- token = JWT.encode iss_payload, hmac_secret, 'HS256'
117
-
118
- expect do
119
- JWT.decode token, hmac_secret, true, iss: iss, algorithm: 'HS256'
120
- end.not_to raise_error
121
- end
122
-
123
- context 'aud' do
124
- it 'array' do
125
- aud = %w(Young Old)
126
- aud_payload = { data: 'data', aud: aud }
127
-
128
- token = JWT.encode aud_payload, hmac_secret, 'HS256'
129
-
130
- expect do
131
- JWT.decode token, hmac_secret, true, aud: %w(Old Young), verify_aud: true, algorithm: 'HS256'
132
- end.not_to raise_error
133
- end
134
-
135
- it 'string' do
136
- expect do
137
- end.not_to raise_error
138
- end
139
- end
140
-
141
- it 'jti' do
142
- iat = Time.now.to_i
143
- hmac_secret = 'test'
144
- jti_raw = [hmac_secret, iat].join(':').to_s
145
- jti = Digest::MD5.hexdigest(jti_raw)
146
- jti_payload = { data: 'data', iat: iat, jti: jti }
147
-
148
- token = JWT.encode jti_payload, hmac_secret, 'HS256'
149
-
150
- expect do
151
- JWT.decode token, hmac_secret, true, verify_jti: true, algorithm: 'HS256'
152
- end.not_to raise_error
153
- end
154
-
155
- context 'iat' do
156
- it 'without leeway' do
157
- iat = Time.now.to_i
158
- iat_payload = { data: 'data', iat: iat }
159
-
160
- token = JWT.encode iat_payload, hmac_secret, 'HS256'
161
-
162
- expect do
163
- JWT.decode token, hmac_secret, true, verify_iat: true, algorithm: 'HS256'
164
- end.not_to raise_error
165
- end
166
-
167
- it 'with leeway' do
168
- iat = Time.now.to_i - 7
169
- iat_payload = { data: 'data', iat: iat, leeway: 10 }
170
-
171
- token = JWT.encode iat_payload, hmac_secret, 'HS256'
172
-
173
- expect do
174
- JWT.decode token, hmac_secret, true, verify_iat: true, algorithm: 'HS256'
175
- end.not_to raise_error
176
- end
177
- end
178
-
179
- it 'sub' do
180
- sub = 'Subject'
181
- sub_payload = { data: 'data', sub: sub }
182
-
183
- token = JWT.encode sub_payload, hmac_secret, 'HS256'
184
-
185
- expect do
186
- JWT.decode token, hmac_secret, true, 'sub' => sub, :verify_sub => true, :algorithm => 'HS256'
187
- end.not_to raise_error
188
- end
189
- end
190
- end
@@ -1,197 +0,0 @@
1
- # frozen_string_literal: true
2
- require 'spec_helper'
3
- require 'jwt/verify'
4
-
5
- module JWT
6
- RSpec.describe Verify do
7
- let(:base_payload) { { 'user_id' => 'some@user.tld' } }
8
- let(:options) { { leeway: 0 } }
9
-
10
- context '.verify_aud(payload, options)' do
11
- let(:scalar_aud) { 'ruby-jwt-audience' }
12
- let(:array_aud) { %w(ruby-jwt-aud test-aud ruby-ruby-ruby) }
13
- let(:scalar_payload) { base_payload.merge('aud' => scalar_aud) }
14
- let(:array_payload) { base_payload.merge('aud' => array_aud) }
15
-
16
- it 'must raise JWT::InvalidAudError when the singular audience does not match' do
17
- expect do
18
- Verify.verify_aud(scalar_payload, options.merge(aud: 'no-match'))
19
- end.to raise_error JWT::InvalidAudError
20
- end
21
-
22
- it 'must raise JWT::InvalidAudError when the payload has an array and none match the supplied value' do
23
- expect do
24
- Verify.verify_aud(array_payload, options.merge(aud: 'no-match'))
25
- end.to raise_error JWT::InvalidAudError
26
- end
27
-
28
- it 'must raise JWT::InvalidAudError when the singular audience does not match and the options aud key is a string' do
29
- expect do
30
- Verify.verify_aud(scalar_payload, options.merge('aud' => 'no-match'))
31
- end.to raise_error JWT::InvalidAudError
32
- end
33
-
34
- it 'must allow a matching singular audience to pass' do
35
- Verify.verify_aud(scalar_payload, options.merge(aud: scalar_aud))
36
- end
37
-
38
- it 'must allow a matching audence to pass when the options key is a string' do
39
- Verify.verify_aud(scalar_payload, options.merge('aud' => scalar_aud))
40
- end
41
-
42
- it 'must allow an array with any value matching the one in the options' do
43
- Verify.verify_aud(array_payload, options.merge(aud: array_aud.first))
44
- end
45
-
46
- it 'must allow an array with any value matching the one in the options with a string options key' do
47
- Verify.verify_aud(array_payload, options.merge('aud' => array_aud.first))
48
- end
49
-
50
- it 'should allow strings or symbolds in options array' do
51
- options['aud'] = [
52
- 'ruby-jwt-aud',
53
- 'test-aud',
54
- 'ruby-ruby-ruby',
55
- :test
56
- ]
57
-
58
- array_payload['aud'].push('test')
59
-
60
- Verify.verify_aud(array_payload, options)
61
- end
62
- end
63
-
64
- context '.verify_expiration(payload, options)' do
65
- let(:leeway) { 10 }
66
- let(:payload) { base_payload.merge('exp' => (Time.now.to_i - 5)) }
67
-
68
- it 'must raise JWT::ExpiredSignature when the token has expired' do
69
- expect do
70
- Verify.verify_expiration(payload, options)
71
- end.to raise_error JWT::ExpiredSignature
72
- end
73
-
74
- it 'must allow some leeway in the expiration when configured' do
75
- Verify.verify_expiration(payload, options.merge(leeway: 10))
76
- end
77
-
78
- it 'must be expired if the exp claim equals the current time' do
79
- payload['exp'] = Time.now.to_i
80
-
81
- expect do
82
- Verify.verify_expiration(payload, options)
83
- end.to raise_error JWT::ExpiredSignature
84
- end
85
- end
86
-
87
- context '.verify_iat(payload, options)' do
88
- let(:iat) { Time.now.to_f }
89
- let(:payload) { base_payload.merge('iat' => iat) }
90
-
91
- it 'must allow a valid iat' do
92
- Verify.verify_iat(payload, options)
93
- end
94
-
95
- it 'must allow configured leeway' do
96
- Verify.verify_iat(payload.merge('iat' => (iat + 60)), options.merge(leeway: 70))
97
- end
98
-
99
- it 'must properly handle integer times' do
100
- Verify.verify_iat(payload.merge('iat' => Time.now.to_i), options)
101
- end
102
-
103
- it 'must raise JWT::InvalidIatError when the iat value is not Numeric' do
104
- expect do
105
- Verify.verify_iat(payload.merge('iat' => 'not a number'), options)
106
- end.to raise_error JWT::InvalidIatError
107
- end
108
-
109
- it 'must raise JWT::InvalidIatError when the iat value is in the future' do
110
- expect do
111
- Verify.verify_iat(payload.merge('iat' => (iat + 120)), options)
112
- end.to raise_error JWT::InvalidIatError
113
- end
114
- end
115
-
116
- context '.verify_iss(payload, options)' do
117
- let(:iss) { 'ruby-jwt-gem' }
118
- let(:payload) { base_payload.merge('iss' => iss) }
119
-
120
- let(:invalid_token) { JWT.encode base_payload, payload[:secret] }
121
-
122
- it 'must raise JWT::InvalidIssuerError when the configured issuer does not match the payload issuer' do
123
- expect do
124
- Verify.verify_iss(payload, options.merge(iss: 'mismatched-issuer'))
125
- end.to raise_error JWT::InvalidIssuerError
126
- end
127
-
128
- it 'must raise JWT::InvalidIssuerError when the payload does not include an issuer' do
129
- expect do
130
- Verify.verify_iss(base_payload, options.merge(iss: iss))
131
- end.to raise_error(JWT::InvalidIssuerError, /received <none>/)
132
- end
133
-
134
- it 'must allow a matching issuer to pass' do
135
- Verify.verify_iss(payload, options.merge(iss: iss))
136
- end
137
- end
138
-
139
- context '.verify_jti(payload, options)' do
140
- let(:payload) { base_payload.merge('jti' => 'some-random-uuid-or-whatever') }
141
-
142
- it 'must allow any jti when the verfy_jti key in the options is truthy but not a proc' do
143
- Verify.verify_jti(payload, options.merge(verify_jti: true))
144
- end
145
-
146
- it 'must raise JWT::InvalidJtiError when the jti is missing' do
147
- expect do
148
- Verify.verify_jti(base_payload, options)
149
- end.to raise_error JWT::InvalidJtiError, /missing/i
150
- end
151
-
152
- it 'must raise JWT::InvalidJtiError when the jti is an empty string' do
153
- expect do
154
- Verify.verify_jti(base_payload.merge('jti' => ' '), options)
155
- end.to raise_error JWT::InvalidJtiError, /missing/i
156
- end
157
-
158
- it 'must raise JWT::InvalidJtiError when verify_jti proc returns false' do
159
- expect do
160
- Verify.verify_jti(payload, options.merge(verify_jti: ->(_jti) { false }))
161
- end.to raise_error JWT::InvalidJtiError, /invalid/i
162
- end
163
-
164
- it 'true proc should not raise JWT::InvalidJtiError' do
165
- Verify.verify_jti(payload, options.merge(verify_jti: ->(_jti) { true }))
166
- end
167
- end
168
-
169
- context '.verify_not_before(payload, options)' do
170
- let(:payload) { base_payload.merge('nbf' => (Time.now.to_i + 5)) }
171
-
172
- it 'must raise JWT::ImmatureSignature when the nbf in the payload is in the future' do
173
- expect do
174
- Verify.verify_not_before(payload, options)
175
- end.to raise_error JWT::ImmatureSignature
176
- end
177
-
178
- it 'must allow some leeway in the token age when configured' do
179
- Verify.verify_not_before(payload, options.merge(leeway: 10))
180
- end
181
- end
182
-
183
- context '.verify_sub(payload, options)' do
184
- let(:sub) { 'ruby jwt subject' }
185
-
186
- it 'must raise JWT::InvalidSubError when the subjects do not match' do
187
- expect do
188
- Verify.verify_sub(base_payload.merge('sub' => 'not-a-match'), options.merge(sub: sub))
189
- end.to raise_error JWT::InvalidSubError
190
- end
191
-
192
- it 'must allow a matching sub' do
193
- Verify.verify_sub(base_payload.merge('sub' => sub), options.merge(sub: sub))
194
- end
195
- end
196
- end
197
- end