jwt 1.5.1 → 2.1.0
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/.codeclimate.yml +20 -0
- data/.ebert.yml +18 -0
- data/.gitignore +11 -0
- data/.reek.yml +40 -0
- data/.rspec +1 -0
- data/.rubocop.yml +98 -0
- data/.travis.yml +14 -0
- data/CHANGELOG.md +476 -0
- data/Gemfile +3 -0
- data/LICENSE +7 -0
- data/Manifest +3 -1
- data/README.md +478 -0
- data/Rakefile +8 -15
- data/lib/jwt/algos/ecdsa.rb +35 -0
- data/lib/jwt/algos/eddsa.rb +23 -0
- data/lib/jwt/algos/hmac.rb +33 -0
- data/lib/jwt/algos/rsa.rb +19 -0
- data/lib/jwt/algos/unsupported.rb +16 -0
- data/lib/jwt/decode.rb +49 -0
- data/lib/jwt/default_options.rb +15 -0
- data/lib/jwt/encode.rb +51 -0
- data/lib/jwt/error.rb +16 -0
- data/lib/jwt/security_utils.rb +51 -0
- data/lib/jwt/signature.rb +50 -0
- data/lib/jwt/verify.rb +102 -0
- data/lib/jwt/version.rb +24 -0
- data/lib/jwt.rb +33 -203
- data/ruby-jwt.gemspec +31 -0
- data/spec/fixtures/certs/ec256-private.pem +8 -0
- data/spec/fixtures/certs/ec256-public.pem +4 -0
- data/spec/fixtures/certs/ec256-wrong-private.pem +8 -0
- data/spec/fixtures/certs/ec256-wrong-public.pem +4 -0
- data/spec/fixtures/certs/ec384-private.pem +9 -0
- data/spec/fixtures/certs/ec384-public.pem +5 -0
- data/spec/fixtures/certs/ec384-wrong-private.pem +9 -0
- data/spec/fixtures/certs/ec384-wrong-public.pem +5 -0
- data/spec/fixtures/certs/ec512-private.pem +10 -0
- data/spec/fixtures/certs/ec512-public.pem +6 -0
- data/spec/fixtures/certs/ec512-wrong-private.pem +10 -0
- data/spec/fixtures/certs/ec512-wrong-public.pem +6 -0
- data/spec/fixtures/certs/rsa-1024-private.pem +15 -0
- data/spec/fixtures/certs/rsa-1024-public.pem +6 -0
- data/spec/fixtures/certs/rsa-2048-private.pem +27 -0
- data/spec/fixtures/certs/rsa-2048-public.pem +9 -0
- data/spec/fixtures/certs/rsa-2048-wrong-private.pem +27 -0
- data/spec/fixtures/certs/rsa-2048-wrong-public.pem +9 -0
- data/spec/fixtures/certs/rsa-4096-private.pem +51 -0
- data/spec/fixtures/certs/rsa-4096-public.pem +14 -0
- data/spec/integration/readme_examples_spec.rb +202 -0
- data/spec/jwt/verify_spec.rb +232 -0
- data/spec/jwt_spec.rb +236 -384
- data/spec/spec_helper.rb +28 -0
- metadata +187 -26
- data/jwt.gemspec +0 -34
- data/lib/jwt/json.rb +0 -32
- data/spec/helper.rb +0 -19
@@ -0,0 +1,10 @@
|
|
1
|
+
-----BEGIN EC PARAMETERS-----
|
2
|
+
BgUrgQQAIw==
|
3
|
+
-----END EC PARAMETERS-----
|
4
|
+
-----BEGIN EC PRIVATE KEY-----
|
5
|
+
MIHcAgEBBEIB0/+ffxEj7j62xvGaB5pvzk888e412ESO/EK/K0QlS9dSF8+Rj1rG
|
6
|
+
zqpRB8fvDnoe8xdmkW/W5GKzojMyv7YQYumgBwYFK4EEACOhgYkDgYYABAEw74Yw
|
7
|
+
aTbPY6TtWmxx6LJDzCX2nKWCPnKdZcEH9Ncu8g5RjRBRq2yacja3OoS6nA2YeDng
|
8
|
+
reBJxZr376P6Ns6XcQFWDA6K/MCTrEBCsPxXZNxd8KR9vMGWhgNtWRrcKzwJfQkr
|
9
|
+
suyehZkbbYyFnAWyARKHZuV7VUXmeEmRS/f93MPqVA==
|
10
|
+
-----END EC PRIVATE KEY-----
|
@@ -0,0 +1,6 @@
|
|
1
|
+
-----BEGIN PUBLIC KEY-----
|
2
|
+
MIGbMBAGByqGSM49AgEGBSuBBAAjA4GGAAQBMO+GMGk2z2Ok7VpsceiyQ8wl9pyl
|
3
|
+
gj5ynWXBB/TXLvIOUY0QUatsmnI2tzqEupwNmHg54K3gScWa9++j+jbOl3EBVgwO
|
4
|
+
ivzAk6xAQrD8V2TcXfCkfbzBloYDbVka3Cs8CX0JK7LsnoWZG22MhZwFsgESh2bl
|
5
|
+
e1VF5nhJkUv3/dzD6lQ=
|
6
|
+
-----END PUBLIC KEY-----
|
@@ -0,0 +1,10 @@
|
|
1
|
+
-----BEGIN EC PARAMETERS-----
|
2
|
+
BgUrgQQAIw==
|
3
|
+
-----END EC PARAMETERS-----
|
4
|
+
-----BEGIN EC PRIVATE KEY-----
|
5
|
+
MIHbAgEBBEG/KbA2oCbiCT6L3V8XSz2WKBy0XhGvIFbl/ZkXIXnkYt+1B7wViSVo
|
6
|
+
KCHuMFsi6xU/5nE1EuDG2UsQJmKeAMkIOKAHBgUrgQQAI6GBiQOBhgAEAG0TFWe5
|
7
|
+
cZ5DZIyfuysrCoQySTNxd+aT8sPIxsx7mW6YBTsuO6rEgxyegd2Auy4xtikxpzKv
|
8
|
+
soMXR02999Aaus2jAAt/wxrhhr41BDP4MV0b6Zngb72hna0pcGqit5OyU8AbOJUZ
|
9
|
+
+rdyowRGsOY+aPbOyVhdNcsEdxYC8GdIyCQLBC1H
|
10
|
+
-----END EC PRIVATE KEY-----
|
@@ -0,0 +1,6 @@
|
|
1
|
+
-----BEGIN PUBLIC KEY-----
|
2
|
+
MIGbMBAGByqGSM49AgEGBSuBBAAjA4GGAAQAbRMVZ7lxnkNkjJ+7KysKhDJJM3F3
|
3
|
+
5pPyw8jGzHuZbpgFOy47qsSDHJ6B3YC7LjG2KTGnMq+ygxdHTb330Bq6zaMAC3/D
|
4
|
+
GuGGvjUEM/gxXRvpmeBvvaGdrSlwaqK3k7JTwBs4lRn6t3KjBEaw5j5o9s7JWF01
|
5
|
+
ywR3FgLwZ0jIJAsELUc=
|
6
|
+
-----END PUBLIC KEY-----
|
@@ -0,0 +1,15 @@
|
|
1
|
+
-----BEGIN RSA PRIVATE KEY-----
|
2
|
+
MIICXgIBAAKBgQDO/ahgFDvniFoQ1dm+MdnkBi+Ts5W9AtQNgw4ZHIdPnqEzSgW7
|
3
|
+
0opKEu8hnlLqsIyU2BC2op/xOanipdbXObuFlA6bth1cYRI+YJlR3BbPGOIL6YbJ
|
4
|
+
ud9m0gIsBlCDLm4e/E45ZS+emudISP7/SF7zxvxZlnr1z7HTm7nIIVBvuQIDAQAB
|
5
|
+
AoGBAMzFQAccvU6GI6O4C5sOsiHUxMh3xtCftaxQVGgfQvVPVuXoeteep1Q0ewFl
|
6
|
+
IV4vnkO5pH8pTtVTWG9x5KIy6QCql4qvr2jkOm4mo9uogrpNklvBl2lN4Lxubj0N
|
7
|
+
mGRXaM3hckZl8+JT6uzfBfjy+pd8AOigJGPQCOZn4gmANW7pAkEA82Nh4wpj6ZRU
|
8
|
+
NBiBq3ONZuH4xJm59MI2FWRJsGUFUYdSaFwyKKim52/13d8iUb7v9utWQFRatCXz
|
9
|
+
Lqw9fQyVrwJBANm3dBOVxpUPrYEQsG0q2rdP+u6U3woylxwtQgJxImZKZmmJlPr8
|
10
|
+
9v23rhydvCe1ERPYe7EjF4RGWVPN3KLdExcCQDdzNfL3BApMS97OkoRQQC/nXbjU
|
11
|
+
2SPlN1MqVQuGCG8pqGG0V40h11y1CkvxMS10ldEojq77SOrwFnZUsXGS82sCQQC6
|
12
|
+
XdO7QCaxSq5XIRYlHN4EtS40NLOIYy3/LK6osHel4GIyTVd+UjSLk0QzssJxqwln
|
13
|
+
V5TqWQO0cxPcLQiFUYEZAkEA2G84ilb9QXOgbNyoE1VifNk49hhodbSskLb86uwY
|
14
|
+
Vgtzq1ZsqoPBCasr4WRiXt270n+mo5dNYRlZwiUn9lH78Q==
|
15
|
+
-----END RSA PRIVATE KEY-----
|
@@ -0,0 +1,6 @@
|
|
1
|
+
-----BEGIN PUBLIC KEY-----
|
2
|
+
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDO/ahgFDvniFoQ1dm+MdnkBi+T
|
3
|
+
s5W9AtQNgw4ZHIdPnqEzSgW70opKEu8hnlLqsIyU2BC2op/xOanipdbXObuFlA6b
|
4
|
+
th1cYRI+YJlR3BbPGOIL6YbJud9m0gIsBlCDLm4e/E45ZS+emudISP7/SF7zxvxZ
|
5
|
+
lnr1z7HTm7nIIVBvuQIDAQAB
|
6
|
+
-----END PUBLIC KEY-----
|
@@ -0,0 +1,27 @@
|
|
1
|
+
-----BEGIN RSA PRIVATE KEY-----
|
2
|
+
MIIEpAIBAAKCAQEA4GzZTLU48c4WbyvHi+QKrB71x+T0eq5hqDbQqnlYjhD1Ika7
|
3
|
+
io1iplsdJWJuyxfYbUkb2Ol0fj4koZ/GS6lgCZr4+8UHbr1qf0Eu5HZSpszs2YxY
|
4
|
+
8U5RHnrpw67co7hlgAR9HbyNf5XIYgLV9ldHH/eazwnc3F/hgNsV0xjScVilejgo
|
5
|
+
cJ4zcsyymvW8t42lteM7bI867ZuJhGop/V+Y0HFyrMsPoQyLuCUpr6ulOfrkr7ZO
|
6
|
+
dhAIG8r1HcjOp/AUjM15vfXcbUZjkM/VloifX1YitU3upMGJ8/DpFGffMOImrn5r
|
7
|
+
6BT494V8rRyN2qvQoAkLJpqZ0avLxwiR2lgVQQIDAQABAoIBAEH0Ozgr2fxWEInD
|
8
|
+
V/VooypKPvjr9F1JejGxSkmPN9MocKIOH3dsbZ1uEXa3ItBUxan4XlK06SNgp+tH
|
9
|
+
xULfF/Y6sQlsse59hBq50Uoa69dRShn1AP6JgZVvkduMPBNxUYL5zrs6emsQXb9Q
|
10
|
+
DglDRQfEAJ7vyxSIqQDxYcyT8uSUF70dqFe+E9B2VE3D6ccHc98k41pJrAFAUFH1
|
11
|
+
wwvDhfyYr7/Ultut9wzpZvU1meF3Vna3GOUHfxrG6wu1G+WIWHGjouzThsc1qiVI
|
12
|
+
BtMCJxuCt5fOXRbU4STbMqhB6sZHiOh6J/dZU6JwRYt+IS8FB6kCNFSEWZWQledJ
|
13
|
+
XqtYSQECgYEA9nmnFTRj3fTBq9zMXfCRujkSy6X2bOb39ftNXzHFuc+I6xmv/3Bs
|
14
|
+
P9tDdjueP/SnCb7i/9hXkpEIcxjrjiqgcvD2ym1hE4q+odMzRAXYMdnmzI34SVZE
|
15
|
+
U5hYJcYsXNKrTTleba7QgqdORmyJ9FwqLO40udvmrZMY223XDwgRkOkCgYEA6RkO
|
16
|
+
5wjjrWWp/G1YN3KXZTS1m2/eGrUThohXKAfAjbWWiouNLW2msXrxEWsPRL6xKiHu
|
17
|
+
X9cwZwzi3MstAgk+bphUGUVUkGKNDjWHJA25tDYjbPtkd6xbL4eCHsKpNL3HNYr9
|
18
|
+
N0CIvgn7qjaHRBem0iK7T6keY4axaSVddEwYapkCgYEA13K5qaB1F4Smcpt8DTWH
|
19
|
+
vPe8xUUaZlFzOJLmLCsuwmB2N8Ppg2j7RspcaxJsH021YaB5ftjWm+ipMSr8ZPY/
|
20
|
+
8JlPsNzxuYpTXtNmAbT2KYVm6THEch61dTk6/DIBf1YrpUJbl5by7vJeStL/uBmE
|
21
|
+
SGgksL5XIyzs0opuLdaIvFkCgYAyBLWE8AxjFfCvAQuwAj/ocLITo6KmWnrRIIqL
|
22
|
+
RXaVMgUWv7FQsTnW1cnK8g05tC2yG8vZ9wQk6Mf5lwOWb0NdWgSZ0528ydj41pWk
|
23
|
+
L+nMeN2LMjqxz2NVxJ8wWJcUgTCxFZ0WcRumo9/D+6V1ABpE9zz4cBLcSnfhVypB
|
24
|
+
nV6T6QKBgQCSZNCQ9HPxjAgYcsqc5sjNwuN1GHQZSav3Tye3k6zHENe1lsteT9K8
|
25
|
+
xciGIuhybKZBvB4yImIIHCtnH+AS+mHAGqHarjNDMfvjOq0dMibPx4+bkIiHdBIH
|
26
|
+
Xz+j5kmntvFiUnzr0Z/Tcqo+r8FvyCo1YWgwqGP8XoFrswD7gy7cZw==
|
27
|
+
-----END RSA PRIVATE KEY-----
|
@@ -0,0 +1,9 @@
|
|
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-----
|
@@ -0,0 +1,27 @@
|
|
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-----
|
@@ -0,0 +1,9 @@
|
|
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-----
|
@@ -0,0 +1,51 @@
|
|
1
|
+
-----BEGIN RSA PRIVATE KEY-----
|
2
|
+
MIIJJwIBAAKCAgEAqETmgWBi5rCmb7euJplA/9xs65+bncc9Yvs5zjyycXSW82Jf
|
3
|
+
RuyguGm0OvA2wog24dR4N2kT/87DcGtp5JqJWADVFNr+2V2r6i57/OMLruRpn3p2
|
4
|
+
r95dmo0COE+BxPFl7XEBT8JbH57ZtpgcB3/xkS14nLOWFf96hrXPlXJC+VMVKVZm
|
5
|
+
A8k2LRh42vT5wUf4U0Doy/p7yFNSFFa6Q8wwe4TBy/z/f+rhFD1w8rxlYjallee/
|
6
|
+
ocm7bjZCwbJGMm7orLViqWfsFX3O35PeoJ5h/7uJ7iRwvTFERkTdwWP/0BeKBeIt
|
7
|
+
BR3YFc2mut+V9W+WKRkMSL6Crc+oVSx3p8aB7j9SZFzQiRtes4BYETpX1xl2mgIq
|
8
|
+
5hvsFbLw7ESrlIodiwUMTrSIid2DQ6q80kv1zXPr4+Id6L0sJLxPCaXnTmNtasSw
|
9
|
+
yedJJYxLjwhHJwtzFAeaq18H3O791YKhjAJ6YxK3zJ59jTE6Pkvqjq183f2PGHVR
|
10
|
+
vgSN7aCmI6MBUUB5wDP2K8zX2sh40/uPDVSd6ei1vl3DpPk+h8iExx6AzbohfqZ+
|
11
|
+
5RUUNx127L3MaQvOVC5TxV+R99gwKW++wzcVuO3m2KqVUj+K1uYBy3KBCUMBbckp
|
12
|
+
EWGbN++jcdV5oJX6fsC66nOmKlntYwCL/pRww+oLsbzF8J3dxeDbKNF9JDsCAwEA
|
13
|
+
AQKCAgBJF8TZJjlP5CQoGy227pNhkSpvH6HFY6qyuFZf09XfmrmHd4/Tiy41bRUx
|
14
|
+
FO90iR7t8hFWYHqjf/k9eCtDdi164MGukYJqgVoQG6kYLLgCfI21DMlJk9otLFtu
|
15
|
+
gnroRcP05EWhk9dpYONJgcGLMHSKj6n4x7nGTHe41HkbfcrB6ukiT7l4o4q5BAxb
|
16
|
+
cFadMtoXr/ZvxJrIZgkddJ7snGHjBcP5DCkgM7MZy6aoilWv1/UNrOF9MdgNA9zz
|
17
|
+
rrD3b136x7/XvqC6pS+bxuvJ8YK4R4qeu42NYT07GOcK/pk8lz0JWTodIt2eevqV
|
18
|
+
6lGFj7c2mv7PCpJRVgbVGL/RTVVap/+jbcRVLdnYKsII/dANG7iXnfwRgkLWet5D
|
19
|
+
OOsPuvIuyiSaJIwcdRE3SSO+tZhKLt+gh/oLxBPw5Ex0FwsVTtYn3Q/X3EAx+Wph
|
20
|
+
eFcRr3TVkDg0MfdWWkgk16DvYB5cWc29coTaH1g+2juadNHbtVAigwJorKc6sxH3
|
21
|
+
QGsW0WQJ8ZRZgJkSUuu3nr7QD3ZrgHptONQAh1RWGnIWi6OlMfaPdMo+SDnnL5SG
|
22
|
+
mpOPjWadDc1XvMFnKQYMYB5GWU/ZNmnZmDLyg1Pc0Y+qRUc0s83nZFHN60KnUrSz
|
23
|
+
0MZDspSFtr0fMx0b2/EB4EbuXd3QjQURF6P6HtWBu6oFnzu1AQKCAQEA2R9BKJgJ
|
24
|
+
vNP+DUu8NBzwmi0cKlAiaxt+w90i5DWq1XWPKgi+RVLkaQSJqHoYQVNgEwL/cWxp
|
25
|
+
s2r3GCMNIdOrGdcm8dX/6UYFpRaFcViTycVEA7cwZOMppgqr2Q+ZYX42K7HObUVL
|
26
|
+
JGvdEWWWfSsynUGsrG87DC1gl94ANxCdqkZdbW5d3X0w5v7M/1tlrmAeskZSZpeT
|
27
|
+
8BwwM6REb0U/B4/i8TLtLi/PGmMTOIxW41uKS/S6kq/gwyv+jNNO0ljhPt25iSbV
|
28
|
+
K5ZHS4YuPKLl0tZMaOkPco9s6t4ES/Y317zQoTzUkAAkkFO4QPzRZL0ESqVBNR0h
|
29
|
+
Ao7FLmFZzFHpoQKCAQEAxmZBn0UrJLXkD7bw66y4RwzjQYmxLlkEl3uvjrvVSuL1
|
30
|
+
mAHDW58aGIpFFZ8QSTtNewIBQYNifp/cdFHAagqtl/iMGEegaOpJAKu/ykrkfZUp
|
31
|
+
7mYDNng4ZWpypeKaGMAQoNzZiUpF+BDnqbeb/kgYu6sNlh9gRHR79rgAuZQxZ/1B
|
32
|
+
tE8WcUFi4CnTq2QLqX4LwMuZHWXAJQoMoW3K5av+J544lIM6GdMJuIONtBBkKVQD
|
33
|
+
ErrJ0bqYeykrFS6pKl/NBCZLGo5xFFRiYEdZ1GlA3uW3EGKppz6PS7194+x5UVts
|
34
|
+
xZPUfkgdFjWCczkl4JDoWfaNn5sgXtiVbGh1n3gYWwKCAQB7vHEg1kyuXU4qe5/d
|
35
|
+
PyTraIvlnVeQHNJIgy0QS3l5Pw8A0IzG6y+anehpqHNMP1zAWPQEytkOVAZPriIc
|
36
|
+
xgl7p37dUa0PX0V2SPhxmR5YXeCeEXc197PTmb9H67jos8nhauqOoW/qaMJK2M9D
|
37
|
+
tCubLUNf3eAT14R16CHNP93qnUE/TSeXQ3JsIofne0neb47u4F6zcuzvaNEbjSEn
|
38
|
+
HJqID7sw5GoA6WQo0I+yqWAXICMXmHf/gtYfxGHEFeSUwexULH5BKG1R8sncw7J0
|
39
|
+
Ag3h8xkGrNON4SkcTLy8Iay/eS6YxRcKndo4mk2mU65tr77TX4xi3Z/jWkQLY5WO
|
40
|
+
eJwhAoIBABO17wkSxyGDjJ/fDfpsE3bDmgRV2KuBHoqqOBvXH26sM7ghXLZKjT4o
|
41
|
+
5ooqXmTYJm91GIjYs71exnkr8hDW9L4nbEuxOgeSVyRg69H+NMshOaQ8sE8GDJxO
|
42
|
+
wgsnAyY4Vq6UomwYW/E0RL/AxRezM/nZGaVzgo3qgLJXP4MwbOQm7hMq1FD2LQuW
|
43
|
+
PDhH3Ty+kA5ca97W0Asd/3k+Pi0pNDvdZUOj8e7E369cKoTcKAdPGGsQ8aILhsCd
|
44
|
+
q3EUTKwwDl8+KrH9utBJPejQzeTjfBVo/xH6q145QeVFcy9ku/zQN3M9p5vQMEuX
|
45
|
+
j1lBMTkpTFw7uYBE2idyHw5BJoZsWQcCggEADfZTChqnOncItSflzGoaAACrr4/x
|
46
|
+
KyT/4A+cPMCs11JN9J+EWsCezya2o1l/NF7YPcBR4qjCmFMEiq5GxH5fGLQp0aa7
|
47
|
+
V13mHA8XBQ25OW2K7BGJhMHdbuvTnl6jsOfC4+t7P2bUAYxoP6/ncxTzZ5OlBN5k
|
48
|
+
aMv9firWl1kSKK75ww9DWn6j0rQ4dBetwX45EMcs+iKIdydg0fmJxR2EJ+uQsCFy
|
49
|
+
xcWBEDqV7qLUi6UrAPL3v/DXUv9wKcKOTbKw/aNE8+YTWMUO330GCJ5cVU1eTL5t
|
50
|
+
UrcNKOJkFIj7jJUCzv6vcy++hMJEbNXnnTVRnky6e9C2vwzMl33njntapg==
|
51
|
+
-----END RSA PRIVATE KEY-----
|
@@ -0,0 +1,14 @@
|
|
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-----
|
@@ -0,0 +1,202 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../spec_helper'
|
4
|
+
require 'jwt'
|
5
|
+
|
6
|
+
describe 'README.md code test' do
|
7
|
+
context 'algorithm usage' do
|
8
|
+
let(:payload) { { data: 'test' } }
|
9
|
+
|
10
|
+
it 'NONE' do
|
11
|
+
token = JWT.encode payload, nil, 'none'
|
12
|
+
decoded_token = JWT.decode token, nil, false
|
13
|
+
|
14
|
+
expect(token).to eq 'eyJhbGciOiJub25lIn0.eyJkYXRhIjoidGVzdCJ9.'
|
15
|
+
expect(decoded_token).to eq [
|
16
|
+
{ 'data' => 'test' },
|
17
|
+
{ 'alg' => 'none' }
|
18
|
+
]
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'HMAC' do
|
22
|
+
token = JWT.encode payload, 'my$ecretK3y', 'HS256'
|
23
|
+
decoded_token = JWT.decode token, 'my$ecretK3y', false
|
24
|
+
|
25
|
+
expect(token).to eq 'eyJhbGciOiJIUzI1NiJ9.eyJkYXRhIjoidGVzdCJ9.pNIWIL34Jo13LViZAJACzK6Yf0qnvT_BuwOxiMCPE-Y'
|
26
|
+
expect(decoded_token).to eq [
|
27
|
+
{ 'data' => 'test' },
|
28
|
+
{ 'alg' => 'HS256' }
|
29
|
+
]
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'RSA' do
|
33
|
+
rsa_private = OpenSSL::PKey::RSA.generate 2048
|
34
|
+
rsa_public = rsa_private.public_key
|
35
|
+
|
36
|
+
token = JWT.encode payload, rsa_private, 'RS256'
|
37
|
+
decoded_token = JWT.decode token, rsa_public, true, algorithm: 'RS256'
|
38
|
+
|
39
|
+
expect(decoded_token).to eq [
|
40
|
+
{ 'data' => 'test' },
|
41
|
+
{ 'alg' => 'RS256' }
|
42
|
+
]
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'ECDSA' do
|
46
|
+
ecdsa_key = OpenSSL::PKey::EC.new 'prime256v1'
|
47
|
+
ecdsa_key.generate_key
|
48
|
+
ecdsa_public = OpenSSL::PKey::EC.new ecdsa_key
|
49
|
+
ecdsa_public.private_key = nil
|
50
|
+
|
51
|
+
token = JWT.encode payload, ecdsa_key, 'ES256'
|
52
|
+
decoded_token = JWT.decode token, ecdsa_public, true, algorithm: 'ES256'
|
53
|
+
|
54
|
+
expect(decoded_token).to eq [
|
55
|
+
{ 'data' => 'test' },
|
56
|
+
{ 'alg' => 'ES256' }
|
57
|
+
]
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
context 'claims' do
|
62
|
+
let(:hmac_secret) { 'MyP4ssW0rD' }
|
63
|
+
|
64
|
+
context 'exp' do
|
65
|
+
it 'without leeway' do
|
66
|
+
exp = Time.now.to_i + 4 * 3600
|
67
|
+
exp_payload = { data: 'data', exp: exp }
|
68
|
+
|
69
|
+
token = JWT.encode exp_payload, hmac_secret, 'HS256'
|
70
|
+
|
71
|
+
expect do
|
72
|
+
JWT.decode token, hmac_secret, true, algorithm: 'HS256'
|
73
|
+
end.not_to raise_error
|
74
|
+
end
|
75
|
+
|
76
|
+
it 'with leeway' do
|
77
|
+
exp = Time.now.to_i - 10
|
78
|
+
leeway = 30 # seconds
|
79
|
+
|
80
|
+
exp_payload = { data: 'data', exp: exp }
|
81
|
+
|
82
|
+
token = JWT.encode exp_payload, hmac_secret, 'HS256'
|
83
|
+
|
84
|
+
expect do
|
85
|
+
JWT.decode token, hmac_secret, true, leeway: leeway, algorithm: 'HS256'
|
86
|
+
end.not_to raise_error
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
context 'nbf' do
|
91
|
+
it 'without leeway' do
|
92
|
+
nbf = Time.now.to_i - 3600
|
93
|
+
nbf_payload = { data: 'data', nbf: nbf }
|
94
|
+
token = JWT.encode nbf_payload, hmac_secret, 'HS256'
|
95
|
+
|
96
|
+
expect do
|
97
|
+
JWT.decode token, hmac_secret, true, algorithm: 'HS256'
|
98
|
+
end.not_to raise_error
|
99
|
+
end
|
100
|
+
|
101
|
+
it 'with leeway' do
|
102
|
+
nbf = Time.now.to_i + 10
|
103
|
+
leeway = 30
|
104
|
+
nbf_payload = { data: 'data', nbf: nbf }
|
105
|
+
token = JWT.encode nbf_payload, hmac_secret, 'HS256'
|
106
|
+
|
107
|
+
expect do
|
108
|
+
JWT.decode token, hmac_secret, true, leeway: leeway, algorithm: 'HS256'
|
109
|
+
end.not_to raise_error
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
it 'iss' do
|
114
|
+
iss = 'My Awesome Company Inc. or https://my.awesome.website/'
|
115
|
+
iss_payload = { data: 'data', iss: iss }
|
116
|
+
|
117
|
+
token = JWT.encode iss_payload, hmac_secret, 'HS256'
|
118
|
+
|
119
|
+
expect do
|
120
|
+
JWT.decode token, hmac_secret, true, iss: iss, algorithm: 'HS256'
|
121
|
+
end.not_to raise_error
|
122
|
+
end
|
123
|
+
|
124
|
+
context 'aud' do
|
125
|
+
it 'array' do
|
126
|
+
aud = %w[Young Old]
|
127
|
+
aud_payload = { data: 'data', aud: aud }
|
128
|
+
|
129
|
+
token = JWT.encode aud_payload, hmac_secret, 'HS256'
|
130
|
+
|
131
|
+
expect do
|
132
|
+
JWT.decode token, hmac_secret, true, aud: %w[Old Young], verify_aud: true, algorithm: 'HS256'
|
133
|
+
end.not_to raise_error
|
134
|
+
end
|
135
|
+
|
136
|
+
it 'string' do
|
137
|
+
expect do
|
138
|
+
end.not_to raise_error
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
it 'jti' do
|
143
|
+
iat = Time.now.to_i
|
144
|
+
hmac_secret = 'test'
|
145
|
+
jti_raw = [hmac_secret, iat].join(':').to_s
|
146
|
+
jti = Digest::MD5.hexdigest(jti_raw)
|
147
|
+
jti_payload = { data: 'data', iat: iat, jti: jti }
|
148
|
+
|
149
|
+
token = JWT.encode jti_payload, hmac_secret, 'HS256'
|
150
|
+
|
151
|
+
expect do
|
152
|
+
JWT.decode token, hmac_secret, true, verify_jti: true, algorithm: 'HS256'
|
153
|
+
end.not_to raise_error
|
154
|
+
end
|
155
|
+
|
156
|
+
context 'iat' do
|
157
|
+
it 'without leeway' do
|
158
|
+
iat = Time.now.to_i
|
159
|
+
iat_payload = { data: 'data', iat: iat }
|
160
|
+
|
161
|
+
token = JWT.encode iat_payload, hmac_secret, 'HS256'
|
162
|
+
|
163
|
+
expect do
|
164
|
+
JWT.decode token, hmac_secret, true, verify_iat: true, algorithm: 'HS256'
|
165
|
+
end.not_to raise_error
|
166
|
+
end
|
167
|
+
|
168
|
+
it 'with leeway' do
|
169
|
+
iat = Time.now.to_i - 7
|
170
|
+
iat_payload = { data: 'data', iat: iat, leeway: 10 }
|
171
|
+
|
172
|
+
token = JWT.encode iat_payload, hmac_secret, 'HS256'
|
173
|
+
|
174
|
+
expect do
|
175
|
+
JWT.decode token, hmac_secret, true, verify_iat: true, algorithm: 'HS256'
|
176
|
+
end.not_to raise_error
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
context 'custom header fields' do
|
181
|
+
it 'with custom field' do
|
182
|
+
payload = { data: 'test' }
|
183
|
+
|
184
|
+
token = JWT.encode payload, nil, 'none', typ: 'JWT'
|
185
|
+
_, header = JWT.decode token, nil, false
|
186
|
+
|
187
|
+
expect(header['typ']).to eq 'JWT'
|
188
|
+
end
|
189
|
+
end
|
190
|
+
|
191
|
+
it 'sub' do
|
192
|
+
sub = 'Subject'
|
193
|
+
sub_payload = { data: 'data', sub: sub }
|
194
|
+
|
195
|
+
token = JWT.encode sub_payload, hmac_secret, 'HS256'
|
196
|
+
|
197
|
+
expect do
|
198
|
+
JWT.decode token, hmac_secret, true, 'sub' => sub, :verify_sub => true, :algorithm => 'HS256'
|
199
|
+
end.not_to raise_error
|
200
|
+
end
|
201
|
+
end
|
202
|
+
end
|
@@ -0,0 +1,232 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
require 'jwt/verify'
|
5
|
+
|
6
|
+
module JWT
|
7
|
+
RSpec.describe Verify do
|
8
|
+
let(:base_payload) { { 'user_id' => 'some@user.tld' } }
|
9
|
+
let(:options) { { leeway: 0 } }
|
10
|
+
|
11
|
+
context '.verify_aud(payload, options)' do
|
12
|
+
let(:scalar_aud) { 'ruby-jwt-aud' }
|
13
|
+
let(:array_aud) { %w[ruby-jwt-aud test-aud ruby-ruby-ruby] }
|
14
|
+
let(:scalar_payload) { base_payload.merge('aud' => scalar_aud) }
|
15
|
+
let(:array_payload) { base_payload.merge('aud' => array_aud) }
|
16
|
+
|
17
|
+
it 'must raise JWT::InvalidAudError when the singular audience does not match' do
|
18
|
+
expect do
|
19
|
+
Verify.verify_aud(scalar_payload, options.merge(aud: 'no-match'))
|
20
|
+
end.to raise_error JWT::InvalidAudError
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'must raise JWT::InvalidAudError when the payload has an array and none match the supplied value' do
|
24
|
+
expect do
|
25
|
+
Verify.verify_aud(array_payload, options.merge(aud: 'no-match'))
|
26
|
+
end.to raise_error JWT::InvalidAudError
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'must allow a matching singular audience to pass' do
|
30
|
+
Verify.verify_aud(scalar_payload, options.merge(aud: scalar_aud))
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'must allow an array with any value matching the one in the options' do
|
34
|
+
Verify.verify_aud(array_payload, options.merge(aud: array_aud.first))
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'must allow an array with any value matching any value in the options array' do
|
38
|
+
Verify.verify_aud(array_payload, options.merge(aud: array_aud))
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'must allow a singular audience payload matching any value in the options array' do
|
42
|
+
Verify.verify_aud(scalar_payload, options.merge(aud: array_aud))
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
context '.verify_expiration(payload, options)' do
|
47
|
+
let(:payload) { base_payload.merge('exp' => (Time.now.to_i - 5)) }
|
48
|
+
|
49
|
+
it 'must raise JWT::ExpiredSignature when the token has expired' do
|
50
|
+
expect do
|
51
|
+
Verify.verify_expiration(payload, options)
|
52
|
+
end.to raise_error JWT::ExpiredSignature
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'must allow some leeway in the expiration when global leeway is configured' do
|
56
|
+
Verify.verify_expiration(payload, options.merge(leeway: 10))
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'must allow some leeway in the expiration when exp_leeway is configured' do
|
60
|
+
Verify.verify_expiration(payload, options.merge(exp_leeway: 10))
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'must be expired if the exp claim equals the current time' do
|
64
|
+
payload['exp'] = Time.now.to_i
|
65
|
+
|
66
|
+
expect do
|
67
|
+
Verify.verify_expiration(payload, options)
|
68
|
+
end.to raise_error JWT::ExpiredSignature
|
69
|
+
end
|
70
|
+
|
71
|
+
context 'when leeway is not specified' do
|
72
|
+
let(:options) { {} }
|
73
|
+
|
74
|
+
it 'used a default leeway of 0' do
|
75
|
+
expect do
|
76
|
+
Verify.verify_expiration(payload, options)
|
77
|
+
end.to raise_error JWT::ExpiredSignature
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
context '.verify_iat(payload, options)' do
|
83
|
+
let(:iat) { Time.now.to_f }
|
84
|
+
let(:payload) { base_payload.merge('iat' => iat) }
|
85
|
+
|
86
|
+
it 'must allow a valid iat' do
|
87
|
+
Verify.verify_iat(payload, options)
|
88
|
+
end
|
89
|
+
|
90
|
+
it 'must allow configured leeway' do
|
91
|
+
Verify.verify_iat(payload.merge('iat' => (iat + 60)), options.merge(leeway: 70))
|
92
|
+
end
|
93
|
+
|
94
|
+
it 'must allow configured iat_leeway' do
|
95
|
+
Verify.verify_iat(payload.merge('iat' => (iat + 60)), options.merge(iat_leeway: 70))
|
96
|
+
end
|
97
|
+
|
98
|
+
it 'must properly handle integer times' do
|
99
|
+
Verify.verify_iat(payload.merge('iat' => Time.now.to_i), options)
|
100
|
+
end
|
101
|
+
|
102
|
+
it 'must raise JWT::InvalidIatError when the iat value is not Numeric' do
|
103
|
+
expect do
|
104
|
+
Verify.verify_iat(payload.merge('iat' => 'not a number'), options)
|
105
|
+
end.to raise_error JWT::InvalidIatError
|
106
|
+
end
|
107
|
+
|
108
|
+
it 'must raise JWT::InvalidIatError when the iat value is in the future' do
|
109
|
+
expect do
|
110
|
+
Verify.verify_iat(payload.merge('iat' => (iat + 120)), options)
|
111
|
+
end.to raise_error JWT::InvalidIatError
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
context '.verify_iss(payload, options)' do
|
116
|
+
let(:iss) { 'ruby-jwt-gem' }
|
117
|
+
let(:payload) { base_payload.merge('iss' => iss) }
|
118
|
+
|
119
|
+
let(:invalid_token) { JWT.encode base_payload, payload[:secret] }
|
120
|
+
|
121
|
+
context 'when iss is a String' do
|
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
|
+
context 'when iss is an Array' do
|
139
|
+
it 'must raise JWT::InvalidIssuerError when no matching issuers in array' do
|
140
|
+
expect do
|
141
|
+
Verify.verify_iss(payload, options.merge(iss: %w[first second]))
|
142
|
+
end.to raise_error JWT::InvalidIssuerError
|
143
|
+
end
|
144
|
+
|
145
|
+
it 'must raise JWT::InvalidIssuerError when the payload does not include an issuer' do
|
146
|
+
expect do
|
147
|
+
Verify.verify_iss(base_payload, options.merge(iss: %w[first second]))
|
148
|
+
end.to raise_error(JWT::InvalidIssuerError, /received <none>/)
|
149
|
+
end
|
150
|
+
|
151
|
+
it 'must allow an array with matching issuer to pass' do
|
152
|
+
Verify.verify_iss(payload, options.merge(iss: ['first', iss, 'third']))
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
context '.verify_jti(payload, options)' do
|
158
|
+
let(:payload) { base_payload.merge('jti' => 'some-random-uuid-or-whatever') }
|
159
|
+
|
160
|
+
it 'must allow any jti when the verfy_jti key in the options is truthy but not a proc' do
|
161
|
+
Verify.verify_jti(payload, options.merge(verify_jti: true))
|
162
|
+
end
|
163
|
+
|
164
|
+
it 'must raise JWT::InvalidJtiError when the jti is missing' do
|
165
|
+
expect do
|
166
|
+
Verify.verify_jti(base_payload, options)
|
167
|
+
end.to raise_error JWT::InvalidJtiError, /missing/i
|
168
|
+
end
|
169
|
+
|
170
|
+
it 'must raise JWT::InvalidJtiError when the jti is an empty string' do
|
171
|
+
expect do
|
172
|
+
Verify.verify_jti(base_payload.merge('jti' => ' '), options)
|
173
|
+
end.to raise_error JWT::InvalidJtiError, /missing/i
|
174
|
+
end
|
175
|
+
|
176
|
+
it 'must raise JWT::InvalidJtiError when verify_jti proc returns false' do
|
177
|
+
expect do
|
178
|
+
Verify.verify_jti(payload, options.merge(verify_jti: ->(_jti) { false }))
|
179
|
+
end.to raise_error JWT::InvalidJtiError, /invalid/i
|
180
|
+
end
|
181
|
+
|
182
|
+
it 'true proc should not raise JWT::InvalidJtiError' do
|
183
|
+
Verify.verify_jti(payload, options.merge(verify_jti: ->(_jti) { true }))
|
184
|
+
end
|
185
|
+
|
186
|
+
it 'it should not throw arguement error with 2 args' do
|
187
|
+
expect do
|
188
|
+
Verify.verify_jti(payload, options.merge(verify_jti: ->(_jti, pl) {
|
189
|
+
true
|
190
|
+
}))
|
191
|
+
end.to_not raise_error
|
192
|
+
end
|
193
|
+
it 'should have payload as second param in proc' do
|
194
|
+
Verify.verify_jti(payload, options.merge(verify_jti: ->(_jti, pl) {
|
195
|
+
expect(pl).to eq(payload)
|
196
|
+
}))
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
200
|
+
context '.verify_not_before(payload, options)' do
|
201
|
+
let(:payload) { base_payload.merge('nbf' => (Time.now.to_i + 5)) }
|
202
|
+
|
203
|
+
it 'must raise JWT::ImmatureSignature when the nbf in the payload is in the future' do
|
204
|
+
expect do
|
205
|
+
Verify.verify_not_before(payload, options)
|
206
|
+
end.to raise_error JWT::ImmatureSignature
|
207
|
+
end
|
208
|
+
|
209
|
+
it 'must allow some leeway in the token age when global leeway is configured' do
|
210
|
+
Verify.verify_not_before(payload, options.merge(leeway: 10))
|
211
|
+
end
|
212
|
+
|
213
|
+
it 'must allow some leeway in the token age when nbf_leeway is configured' do
|
214
|
+
Verify.verify_not_before(payload, options.merge(nbf_leeway: 10))
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
218
|
+
context '.verify_sub(payload, options)' do
|
219
|
+
let(:sub) { 'ruby jwt subject' }
|
220
|
+
|
221
|
+
it 'must raise JWT::InvalidSubError when the subjects do not match' do
|
222
|
+
expect do
|
223
|
+
Verify.verify_sub(base_payload.merge('sub' => 'not-a-match'), options.merge(sub: sub))
|
224
|
+
end.to raise_error JWT::InvalidSubError
|
225
|
+
end
|
226
|
+
|
227
|
+
it 'must allow a matching sub' do
|
228
|
+
Verify.verify_sub(base_payload.merge('sub' => sub), options.merge(sub: sub))
|
229
|
+
end
|
230
|
+
end
|
231
|
+
end
|
232
|
+
end
|