@astronautlabs/jwt 0.0.12

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 (83) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +107 -0
  3. package/demo.key +27 -0
  4. package/demo8.key +28 -0
  5. package/dist/browser/base64url.d.ts +4 -0
  6. package/dist/browser/base64url.js +18 -0
  7. package/dist/browser/base64url.js.map +1 -0
  8. package/dist/browser/index.d.ts +5 -0
  9. package/dist/browser/index.js +21 -0
  10. package/dist/browser/index.js.map +1 -0
  11. package/dist/browser/utils.d.ts +6 -0
  12. package/dist/browser/utils.js +24 -0
  13. package/dist/browser/utils.js.map +1 -0
  14. package/dist/browser/webcrypto-jwt.d.ts +22 -0
  15. package/dist/browser/webcrypto-jwt.js +378 -0
  16. package/dist/browser/webcrypto-jwt.js.map +1 -0
  17. package/dist/browser/webcrypto-jwt.test.d.ts +1 -0
  18. package/dist/browser/webcrypto-jwt.test.js +6 -0
  19. package/dist/browser/webcrypto-jwt.test.js.map +1 -0
  20. package/dist/common/expiry.d.ts +1 -0
  21. package/dist/common/expiry.js +25 -0
  22. package/dist/common/expiry.js.map +1 -0
  23. package/dist/common/index.d.ts +2 -0
  24. package/dist/common/index.js +15 -0
  25. package/dist/common/index.js.map +1 -0
  26. package/dist/common/interface.d.ts +38 -0
  27. package/dist/common/interface.js +3 -0
  28. package/dist/common/interface.js.map +1 -0
  29. package/dist/engine.test.d.ts +10 -0
  30. package/dist/engine.test.js +295 -0
  31. package/dist/engine.test.js.map +1 -0
  32. package/dist/fixtures/es256.fixture.d.ts +6 -0
  33. package/dist/fixtures/es256.fixture.js +10 -0
  34. package/dist/fixtures/es256.fixture.js.map +1 -0
  35. package/dist/fixtures/hs256.fixture.d.ts +6 -0
  36. package/dist/fixtures/hs256.fixture.js +10 -0
  37. package/dist/fixtures/hs256.fixture.js.map +1 -0
  38. package/dist/fixtures/hs384.fixture.d.ts +6 -0
  39. package/dist/fixtures/hs384.fixture.js +10 -0
  40. package/dist/fixtures/hs384.fixture.js.map +1 -0
  41. package/dist/fixtures/hs512.fixture.d.ts +6 -0
  42. package/dist/fixtures/hs512.fixture.js +10 -0
  43. package/dist/fixtures/hs512.fixture.js.map +1 -0
  44. package/dist/fixtures/rs256.fixture.d.ts +6 -0
  45. package/dist/fixtures/rs256.fixture.js +10 -0
  46. package/dist/fixtures/rs256.fixture.js.map +1 -0
  47. package/dist/fixtures/rs512.fixture.d.ts +6 -0
  48. package/dist/fixtures/rs512.fixture.js +10 -0
  49. package/dist/fixtures/rs512.fixture.js.map +1 -0
  50. package/dist/index.d.ts +3 -0
  51. package/dist/index.js +18 -0
  52. package/dist/index.js.map +1 -0
  53. package/dist/node/engine.test.d.ts +1 -0
  54. package/dist/node/engine.test.js +6 -0
  55. package/dist/node/engine.test.js.map +1 -0
  56. package/dist/node/index.d.ts +9 -0
  57. package/dist/node/index.js +117 -0
  58. package/dist/node/index.js.map +1 -0
  59. package/dist/test.d.ts +1 -0
  60. package/dist/test.js +9 -0
  61. package/dist/test.js.map +1 -0
  62. package/karma.conf.ts +59 -0
  63. package/package.json +46 -0
  64. package/src/browser/base64url.ts +12 -0
  65. package/src/browser/index.ts +6 -0
  66. package/src/browser/utils.ts +20 -0
  67. package/src/browser/webcrypto-jwt.test.ts +4 -0
  68. package/src/browser/webcrypto-jwt.ts +351 -0
  69. package/src/common/expiry.ts +25 -0
  70. package/src/common/index.ts +2 -0
  71. package/src/common/interface.ts +47 -0
  72. package/src/engine.test.ts +173 -0
  73. package/src/fixtures/es256.fixture.ts +25 -0
  74. package/src/fixtures/hs256.fixture.ts +6 -0
  75. package/src/fixtures/hs384.fixture.ts +6 -0
  76. package/src/fixtures/hs512.fixture.ts +6 -0
  77. package/src/fixtures/rs256.fixture.ts +81 -0
  78. package/src/fixtures/rs512.fixture.ts +81 -0
  79. package/src/index.ts +5 -0
  80. package/src/node/engine.test.ts +4 -0
  81. package/src/node/index.ts +56 -0
  82. package/src/test.ts +7 -0
  83. package/tsconfig.json +37 -0
@@ -0,0 +1,173 @@
1
+ import { suite } from 'razmin';
2
+ import { expect } from 'chai';
3
+ import { JWTEngine, DecodeOptions } from './common';
4
+ import * as RS256Fixtures from './fixtures/rs256.fixture';
5
+ import * as RS512Fixtures from './fixtures/rs512.fixture';
6
+ import * as ES256Fixtures from './fixtures/es256.fixture';
7
+ import * as HS256Fixtures from './fixtures/hs256.fixture';
8
+ import * as HS384Fixtures from './fixtures/hs384.fixture';
9
+ import * as HS512Fixtures from './fixtures/hs512.fixture';
10
+
11
+ export interface AlgorithmFixtures {
12
+ SAMPLE_PUBKEY : string;
13
+ SAMPLE_PRIVATEKEY : string;
14
+ SAMPLE_TOKEN : string;
15
+ SAMPLE_TOKEN_INVALID : string;
16
+ SAMPLE_PUBKEY_2 : string;
17
+ SAMPLE_PRIVATEKEY_2 : string;
18
+ }
19
+
20
+ const ALGORITHMS = {
21
+ HS256: HS256Fixtures,
22
+ HS384: HS384Fixtures,
23
+ HS512: HS512Fixtures,
24
+ RS256: RS256Fixtures,
25
+ RS512: RS512Fixtures,
26
+ ES256: ES256Fixtures,
27
+ };
28
+
29
+ export function engineTest(subjectName : string, engine : JWTEngine) {
30
+ suite(describe => {
31
+ describe(subjectName, it => {
32
+ describe(': Validation', it => {
33
+ describe(': alg', it => {
34
+ it('rejects tokens with the wrong algorithm', async () => {
35
+ try {
36
+ await engine.validate(HS256Fixtures.SAMPLE_TOKEN, { algorithm: 'RS256', secretOrKey: RS256Fixtures.SAMPLE_PUBKEY })
37
+ } catch (e) {
38
+ expect(e.message).to.contain('Token has incorrect algorithm');
39
+ return;
40
+ }
41
+
42
+ throw new Error(`Should not accept token with incorrect algorithm`);
43
+ });
44
+ });
45
+
46
+ describe(': exp', it => {
47
+ it('rejects expired tokens by default', async () => {
48
+ let options = { algorithm: 'HS256', secretOrKey: HS256Fixtures.SAMPLE_PUBKEY };
49
+ let token = await engine.encode({ exp: (Date.now() - 1000) / 1000 }, options);
50
+
51
+ try {
52
+ await engine.validate(token.string, options)
53
+ } catch (e) {
54
+ expect(e.message).to.contain('Token is expired');
55
+ return;
56
+ }
57
+
58
+ throw new Error(`Should not accept an expired token by default`);
59
+ });
60
+
61
+ it('rejects expired tokens with validate.exp=force', async () => {
62
+ let options : DecodeOptions = { algorithm: 'HS256', secretOrKey: HS256Fixtures.SAMPLE_PUBKEY, validate: { exp: 'force' } };
63
+ let token = await engine.encode({ exp: (Date.now() - 1000) / 1000 }, options);
64
+
65
+ try {
66
+ await engine.validate(token.string, options)
67
+ } catch (e) {
68
+ expect(e.message).to.contain('Token is expired');
69
+ return;
70
+ }
71
+
72
+ throw new Error(`Should not accept an expired token with validate.exp=force`);
73
+ });
74
+
75
+ it('accepts fresh tokens with validate.exp=force', async () => {
76
+ let options : DecodeOptions = { algorithm: 'HS256', secretOrKey: HS256Fixtures.SAMPLE_PUBKEY, validate: { exp: 'force' } };
77
+ let token = await engine.encode({ sub: 'abcdef', exp: (Date.now() + 10000) / 1000 }, options);
78
+
79
+ let validatedToken = await engine.validate(token.string, options)
80
+ expect(validatedToken.claims.sub).to.equal('abcdef');
81
+ });
82
+
83
+ it('rejects tokens without exp claim when configured to do so', async () => {
84
+ let options : DecodeOptions = { algorithm: 'HS256', secretOrKey: HS256Fixtures.SAMPLE_PUBKEY, validate: { exp: 'force' } };
85
+ let token = await engine.encode({ sub: 'abcdef' }, options);
86
+
87
+ try {
88
+ await engine.validate(token.string, options)
89
+ } catch (e) {
90
+ expect(e.message).to.contain('Non-expiring tokens are not acceptable');
91
+ return;
92
+ }
93
+
94
+ throw new Error(`Should not accept a token without exp claim when configured to require it`);
95
+ });
96
+
97
+ it('accepts expired tokens when configured to do so', async () => {
98
+ let options : DecodeOptions = { algorithm: 'HS256', secretOrKey: HS256Fixtures.SAMPLE_PUBKEY, validate: { exp: 'ignore' } };
99
+ let token = await engine.encode({ sub: 'abcdef', exp: (Date.now() - 1000) / 1000 }, options);
100
+ let validatedToken = await engine.validate(token.string, options);
101
+ expect(validatedToken.claims.sub).to.equal('abcdef');
102
+ });
103
+ });
104
+ });
105
+
106
+ Object.keys(ALGORITHMS).forEach(alg => testAlgorithm(alg, ALGORITHMS[alg]));
107
+
108
+ function testAlgorithm(algorithm : string, fixtures : AlgorithmFixtures) {
109
+ describe(`: Algorithm=${algorithm}`, async () => {
110
+ it('can verify a token', async () => {
111
+ let token = await engine.validate(
112
+ fixtures.SAMPLE_TOKEN,
113
+ {
114
+ algorithm,
115
+ secretOrKey: fixtures.SAMPLE_PUBKEY
116
+ }
117
+ );
118
+ expect(token.claims.sub).to.equal("1234567890");
119
+ expect(token.claims.iat).to.equal(1516239022);
120
+ });
121
+ it('can detect a forged token', async () => {
122
+ try {
123
+ await engine.validate(fixtures.SAMPLE_TOKEN_INVALID, {
124
+ algorithm,
125
+ secretOrKey: fixtures.SAMPLE_PUBKEY
126
+ });
127
+ } catch (e) {
128
+ expect(e.message).to.contain('Invalid signature');
129
+ return;
130
+ }
131
+
132
+ throw new Error('Engine should have detected forgery');
133
+ });
134
+ it('fails to verify a token with wrong key', async () => {
135
+ try {
136
+ await engine.validate(fixtures.SAMPLE_TOKEN_INVALID, {
137
+ algorithm,
138
+ secretOrKey: fixtures.SAMPLE_PUBKEY_2
139
+ });
140
+ } catch (e) {
141
+ expect(e.message).to.contain('Invalid signature');
142
+ return;
143
+ }
144
+
145
+ throw new Error('Engine should have failed to verify');
146
+ });
147
+ it('can sign a token', async () => {
148
+ let token = await engine.encode({
149
+ foo: 123,
150
+ iat: 1598181440
151
+ }, {
152
+ algorithm,
153
+ secretOrKey: fixtures.SAMPLE_PRIVATEKEY
154
+ });
155
+
156
+ try {
157
+ let validatedToken = await engine.validate(token.string, {
158
+ algorithm,
159
+ secretOrKey: fixtures.SAMPLE_PUBKEY
160
+ });
161
+ expect(validatedToken.claims.iat).to.equal(1598181440);
162
+ } catch (e) {
163
+ console.error(`Caught error during .sign() test:`);
164
+ console.error(e);
165
+ throw new Error(`Should be able to validate signed token '${token.string}', caught error: ${e}`);
166
+ }
167
+ });
168
+ });
169
+ }
170
+
171
+ });
172
+ });
173
+ }
@@ -0,0 +1,25 @@
1
+
2
+ export const SAMPLE_PUBKEY = `-----BEGIN PUBLIC KEY-----
3
+ MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEEVs/o5+uQbTjL3chynL4wXgUg2R9
4
+ q9UU8I5mEovUf86QZ7kOBIjJwqnzD1omageEHWwHdBO6B+dFabmdT9POxg==
5
+ -----END PUBLIC KEY-----`;
6
+ export const SAMPLE_PRIVATEKEY = `-----BEGIN PRIVATE KEY-----
7
+ MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgevZzL1gdAFr88hb2
8
+ OF/2NxApJCzGCEDdfSp6VQO30hyhRANCAAQRWz+jn65BtOMvdyHKcvjBeBSDZH2r
9
+ 1RTwjmYSi9R/zpBnuQ4EiMnCqfMPWiZqB4QdbAd0E7oH50VpuZ1P087G
10
+ -----END PRIVATE KEY-----`;
11
+
12
+ export const SAMPLE_TOKEN = `eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWUsImlhdCI6MTUxNjIzOTAyMn0.tyh-VfuzIxCyGYDlkBA7DfyjrqmSHu6pQ2hoZuFqUSLPNY2N0mpHb3nk5K17HWP_3cYHBw7AhHale5wky6-sVA`;
13
+ export const SAMPLE_TOKEN_INVALID = `eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lISIsImFkbWluIjp0cnVlLCJpYXQiOjE1MTYyMzkwMjJ9.tyh-VfuzIxCyGYDlkBA7DfyjrqmSHu6pQ2hoZuFqUSLPNY2N0mpHb3nk5K17HWP_3cYHBw7AhHale5wky6-sVA`;
14
+
15
+
16
+ export const SAMPLE_PUBKEY_2 = `-----BEGIN PUBLIC KEY-----
17
+ MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE7q33/7EWeDT8mkJxoA8b9hE++198
18
+ pLrd34UbfmMQGERJcowNj3HFf/GDVuSYlmlqOe03JFJUQKIFK/tRKh49cA==
19
+ -----END PUBLIC KEY-----`;
20
+
21
+ export const SAMPLE_PRIVATEKEY_2 = `-----BEGIN PRIVATE KEY-----
22
+ MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgiJpVKn9jlq1LFAz3
23
+ bSWEFjmU8IzLm/T+UK6tsHJGYj+hRANCAATurff/sRZ4NPyaQnGgDxv2ET77X3yk
24
+ ut3fhRt+YxAYRElyjA2PccV/8YNW5JiWaWo57TckUlRAogUr+1EqHj1w
25
+ -----END PRIVATE KEY-----`;
@@ -0,0 +1,6 @@
1
+ export const SAMPLE_TOKEN = `eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c`;
2
+ export const SAMPLE_TOKEN_INVALID = `eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_SNEAKYssw5c`;
3
+ export const SAMPLE_PUBKEY = `your-256-bit-secret`;
4
+ export const SAMPLE_PRIVATEKEY = `your-256-bit-secret`;
5
+ export const SAMPLE_PUBKEY_2 = `wrong-key`;
6
+ export const SAMPLE_PRIVATEKEY_2 = `wrong-key`;
@@ -0,0 +1,6 @@
1
+ export const SAMPLE_TOKEN = `eyJhbGciOiJIUzM4NCIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWUsImlhdCI6MTUxNjIzOTAyMn0.bQTnz6AuMJvmXXQsVPrxeQNvzDkimo7VNXxHeSBfClLufmCVZRUuyTwJF311JHuh`;
2
+ export const SAMPLE_TOKEN_INVALID = `eyJhbGciOiJIUzM4NCIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lISIsImFkbWluIjp0cnVlLCJpYXQiOjE1MTYyMzkwMjJ9.bQTnz6AuMJvmXXQsVPrxeQNvzDkimo7VNXxHeSBfClLufmCVZRUuyTwJF311JHuh`;
3
+ export const SAMPLE_PUBKEY = `your-384-bit-secret`;
4
+ export const SAMPLE_PRIVATEKEY = `your-384-bit-secret`;
5
+ export const SAMPLE_PUBKEY_2 = `wrong-key-384`;
6
+ export const SAMPLE_PRIVATEKEY_2 = `wrong-key-384`;
@@ -0,0 +1,6 @@
1
+ export const SAMPLE_TOKEN = `eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWUsImlhdCI6MTUxNjIzOTAyMn0.VFb0qJ1LRg_4ujbZoRMXnVkUgiuKq5KxWqNdbKq_G9Vvz-S1zZa9LPxtHWKa64zDl2ofkT8F6jBt_K4riU-fPg`;
2
+ export const SAMPLE_TOKEN_INVALID = `eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lISIsImFkbWluIjp0cnVlLCJpYXQiOjE1MTYyMzkwMjJ9.VFb0qJ1LRg_4ujbZoRMXnVkUgiuKq5KxWqNdbKq_G9Vvz-S1zZa9LPxtHWKa64zDl2ofkT8F6jBt_K4riU-fPg`;
3
+ export const SAMPLE_PUBKEY = `your-512-bit-secret`;
4
+ export const SAMPLE_PRIVATEKEY = `your-512-bit-secret`;
5
+ export const SAMPLE_PUBKEY_2 = `wrong-key-512`;
6
+ export const SAMPLE_PRIVATEKEY_2 = `wrong-key-512`;
@@ -0,0 +1,81 @@
1
+
2
+ export const SAMPLE_PUBKEY = `-----BEGIN PUBLIC KEY-----
3
+ MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnzyis1ZjfNB0bBgKFMSv
4
+ vkTtwlvBsaJq7S5wA+kzeVOVpVWwkWdVha4s38XM/pa/yr47av7+z3VTmvDRyAHc
5
+ aT92whREFpLv9cj5lTeJSibyr/Mrm/YtjCZVWgaOYIhwrXwKLqPr/11inWsAkfIy
6
+ tvHWTxZYEcXLgAXFuUuaS3uF9gEiNQwzGTU1v0FqkqTBr4B8nW3HCN47XUu0t8Y0
7
+ e+lf4s4OxQawWD79J9/5d3Ry0vbV3Am1FtGJiJvOwRsIfVChDpYStTcHTCMqtvWb
8
+ V6L11BWkpzGXSW4Hv43qa+GSYOD2QU68Mb59oSk2OB+BtOLpJofmbGEGgvmwyCI9
9
+ MwIDAQAB
10
+ -----END PUBLIC KEY-----`;
11
+ export const SAMPLE_PRIVATEKEY = `-----BEGIN PRIVATE KEY-----
12
+ MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCfPKKzVmN80HRs
13
+ GAoUxK++RO3CW8GxomrtLnAD6TN5U5WlVbCRZ1WFrizfxcz+lr/Kvjtq/v7PdVOa
14
+ 8NHIAdxpP3bCFEQWku/1yPmVN4lKJvKv8yub9i2MJlVaBo5giHCtfAouo+v/XWKd
15
+ awCR8jK28dZPFlgRxcuABcW5S5pLe4X2ASI1DDMZNTW/QWqSpMGvgHydbccI3jtd
16
+ S7S3xjR76V/izg7FBrBYPv0n3/l3dHLS9tXcCbUW0YmIm87BGwh9UKEOlhK1NwdM
17
+ Iyq29ZtXovXUFaSnMZdJbge/jepr4ZJg4PZBTrwxvn2hKTY4H4G04ukmh+ZsYQaC
18
+ +bDIIj0zAgMBAAECggEAKIBGrbCSW2O1yOyQW9nvDUkA5EdsS58Q7US7bvM4iWpu
19
+ DIBwCXur7/VuKnhn/HUhURLzj/JNozynSChqYyG+CvL+ZLy82LUE3ZIBkSdv/vFL
20
+ Ft+VvvRtf1EcsmoqenkZl7aN7HD7DJeXBoz5tyVQKuH17WW0fsi9StGtCcUl+H6K
21
+ zV9Gif0Kj0uLQbCg3THRvKuueBTwCTdjoP0PwaNADgSWb3hJPeLMm/yII4tIMGbO
22
+ w+xd9wJRl+ZN9nkNtQMxszFGdKjedB6goYLQuP0WRZx+YtykaVJdM75bDUvsQar4
23
+ 9Pc21Fp7UVk/CN11DX/hX3TmTJAUtqYADliVKkTbCQKBgQDLU48tBxm3g1CdDM/P
24
+ ZIEmpA3Y/m7e9eX7M1Uo/zDh4G/S9a4kkX6GQY2dLFdCtOS8M4hR11Io7MceBKDi
25
+ djorTZ5zJPQ8+b9Rm+1GlaucGNwRW0cQk2ltT2ksPmJnQn2xvM9T8vE+a4A/YGzw
26
+ mZOfpoVGykWs/tbSzU2aTaOybQKBgQDIfRf6OmirGPh59l+RSuDkZtISF/51mCV/
27
+ S1M4DltWDwhjC2Y2T+meIsb/Mjtz4aVNz0EHB8yvn0TMGr94Uwjv4uBdpVSwz+xL
28
+ hHL7J4rpInH+i0gxa0N+rGwsPwI8wJG95wLY+Kni5KCuXQw55uX1cqnnsahpRZFZ
29
+ EerBXhjqHwKBgBmEjiaHipm2eEqNjhMoOPFBi59dJ0sCL2/cXGa9yEPA6Cfgv49F
30
+ V0zAM2azZuwvSbm4+fXTgTMzrDW/PPXPArPmlOk8jQ6OBY3XdOrz48q+b/gZrYyO
31
+ A6A9ZCSyW6U7+gxxds/BYLeFxF2v21xC2f0iZ/2faykv/oQMUh34en/tAoGACqVZ
32
+ 2JexZyR0TUWf3X80YexzyzIq+OOTWicNzDQ29WLm9xtr2gZ0SUlfd72bGpQoyvDu
33
+ awkm/UxfwtbIxALkvpg1gcN9s8XWrkviLyPyZF7H3tRWiQlBFEDjnZXa8I7pLkRO
34
+ Cmdp3fp17cxTEeAI5feovfzZDH39MdWZuZrdh9ECgYBTEv8S7nK8wrxIC390kroV
35
+ 52eBwzckQU2mWa0thUtaGQiU1EYPCSDcjkrLXwB72ft0dW57KyWtvrB6rt1ORgOL
36
+ eI5hFbwdGQhCHTrAR1vG3SyFPMAm+8JB+sGOD/fvjtZKx//MFNweKFNEF0C/o6Z2
37
+ FXj90PlgF8sCQut36ZfuIQ==
38
+ -----END PRIVATE KEY-----`;
39
+
40
+ export const SAMPLE_TOKEN = `eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWUsImlhdCI6MTUxNjIzOTAyMn0.POstGetfAytaZS82wHcjoTyoqhMyxXiWdR7Nn7A29DNSl0EiXLdwJ6xC6AfgZWF1bOsS_TuYI3OG85AmiExREkrS6tDfTQ2B3WXlrr-wp5AokiRbz3_oB4OxG-W9KcEEbDRcZc0nH3L7LzYptiy1PtAylQGxHTWZXtGz4ht0bAecBgmpdgXMguEIcoqPJ1n3pIWk_dUZegpqx0Lka21H6XxUTxiy8OcaarA8zdnPUnV6AmNP3ecFawIFYdvJB_cm-GvpCSbr8G8y_Mllj8f4x9nBH8pQux89_6gUY618iYv7tuPWBFfEbLxtF2pZS6YC1aSfLQxeNe8djT9YjpvRZA`;
41
+ export const SAMPLE_TOKEN_INVALID = `eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWUsImlhdCI6MTUxNjIzOTAyMn0.fbMk59LQGNup5Jq9_Vq-Df3f1I8YcM_qzgrhl6R33PviVR6jskvlI__B27nZNh3A0CbH5XmCFAFrF41q2C_-EJAz3Wc9ndNBAu9c2EaF8FDDLsVfpVajApO-iQmt2pE_D54QOOw9VRWEBvx-690DMrZVV8R8wWrNgKZ90kQyxGRQKqWDgOAygBoPMxd4goy9_TKDl6D876bE5hlL2AIRP2Gj1EmA2cMaP2T4kGut-XYBmUKRfQUvDYowzsLid6ejhgUzqA7HAk_pC6E9FS79I0f5XLKaOnELOOKOUTHaCexTeYqfvYxSmpvDokFB1jKiEh1dIrkXNLlMFPTJRMWijA`;
42
+
43
+
44
+ export const SAMPLE_PUBKEY_2 = `-----BEGIN PUBLIC KEY-----
45
+ MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnzyis1ZjfNB0bBgKFMSv
46
+ vkTtwlvBsaJq7S5wA+kzeVOVpVWwkWdVha4s38XM/pa/yr47av7+z3VTmvDRyAHc
47
+ aT92whREFpLv9cj5lTeJSibyr/Mrm/YtjCZVWgaOYIhwrXwKLqPr/11inWsAkfIy
48
+ tvHWTxZYEcXLgAXFuUuaS3uF9gEiNQwzGTU1v0FqkqTBr4B8nW3HCN47XUu0t8Y0
49
+ e+lf4s4OxQawWD79J9/5d3Ry0vbV3Am1FtGJiJvOwRsIfVChDpYStTcHTCMqtvWb
50
+ V6L11BWkpzGXSW4Hv43qa+GSYOD2QU68Mb59oSk2OB+BtOLpJofmbGEGgvmwyCI9
51
+ MwIDAQAB
52
+ -----END PUBLIC KEY-----`;
53
+
54
+ export const SAMPLE_PRIVATEKEY_2 = `-----BEGIN PRIVATE KEY-----
55
+ MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDfj0kY6x9bEcNe
56
+ UUtRxPDzQ6rdaVnsC82QPdnwrXqrd6Bu+HmsmcKfwNxTT5m7H2gDQ+clEn7zTJ+u
57
+ sLB3moSmiz6mfRE87rTgNSW5Y8l9uvsV2GCEf1+GIBtdw75Cicq1fE8v+4yMu4xk
58
+ 8NJkY4AyhihOsq7QARB6i1KM5FHOh2aYMZQI+Hx1J9M6fj0GKJbCJh2VkXyqwNb9
59
+ 3SvfYLPLSSkTmzOpdRxQfI8Ql9pri0zHUerhFzy8wmHhSz52qRJknZKnhKU6HAsX
60
+ v7a5lh8C5fXcgad6tpmKJKBpEx00EtLMyqkb0gBzjKUvEbqWjB5659LH6WQZeMuY
61
+ g6abbDbnAgMBAAECggEAL3y/OTTQf0bBqio4hpD/4ZyREeEMAdDsBGSvA6nF8eBC
62
+ SvAq4Ff0+Hw+ENBKxm3AaVkmI0DPiJzRGolborxGyx2u3Cya2ceW0j1X2w5wQW3T
63
+ YeuJbPulbdcqGPu4UWf1kCFsrLORQl+gTdy9xCdClvjaXQUljvd66Zzolxb0rZq9
64
+ keRREJ55VZazBhwjtvfwII7chwzNdFzAX5Ft9IPFOaBoi13bCPTzUPeIazbktwIv
65
+ FpKA51M12LF+fJpY608ACP5FR6ShnAxPbvpgOcVtxhuBvAdDu2jTvB9yASsNnHjE
66
+ VXp1mTBTx+HsO6onIFqkN5fC/3ds+3zyOScu6RkGMQKBgQD7/h/lKRtEWJVML+ag
67
+ a+V2WUy6Yel5IgF7DeH8Z78QOLhB1MUr8jXD8skMcTZiSYuF8rRV5FVHAbv+pnwC
68
+ NkZclCNQqoOVbhIT8wBV+TE0ay5ZSLqLkhCdmmYaBg6WccfzPmcIRwTgC3QWSyku
69
+ jjpRLxEPTEzbnNRuKFaOSbctKQKBgQDjHWiqiSXXEbQdI80cJmoz1o+gLtUKVdK/
70
+ GyUak/AX4PLhG4VZHHHt/AArPYr+eEQcN6aCsWU8qRt6H3LyhBjev93CHAKs4snG
71
+ +edQ7xK0kqervR4KXweTD+wqUVglvqmstGwkI33CFUZwE7t6bKgmALfgdeJxFCLM
72
+ ScV8y0y1jwKBgQDZXjh9IJxYtGD0u00hjHD/ScCZ9ePDjcXhM/SAGa4CfCrU/oim
73
+ g+RFBqTOisnytqYYAWf1v2SgP6q+2zWVYuQG7/IWnz+qIqyNcMwVXUNIiDwO4GGq
74
+ C3ExwgHY6OikdbmY5XdS+JAIA1k78dGwSxea+BKrM5IIzpuf+kPPsV7FIQKBgAOW
75
+ NE/1KIbT/b80EIowRR8adVw3QSAPqOtht11LFtCZudw6PgnhPB9hCnOkXiyUo6a6
76
+ bkPEH3Asz4VHN96CnY3vA8aMALLQRhWBXtjVXbtCUamRrAbH52u4JaepbzXxY+aZ
77
+ VtffQ54sDde5SA2v55vqCP1ffzr/8Wi+hYLqBwUbAoGBAIhtiyG3DVX0j0z1EICq
78
+ ZR2HJJk7KKPcrUGW0fbNqnxIrjqBq22PGD6rkFHQFpD/y/u7NGpOFU12tk099ly+
79
+ EZFf9T6VsMw+7sUFo88gTDL9BK6IBcsYDr5I7QfN5WkXbsrx/s9Yll7urISU3z7o
80
+ eUhPf0cYfvNPR4eQb5FLLrDX
81
+ -----END PRIVATE KEY-----`;
@@ -0,0 +1,81 @@
1
+
2
+ export const SAMPLE_PUBKEY = `-----BEGIN PUBLIC KEY-----
3
+ MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnzyis1ZjfNB0bBgKFMSv
4
+ vkTtwlvBsaJq7S5wA+kzeVOVpVWwkWdVha4s38XM/pa/yr47av7+z3VTmvDRyAHc
5
+ aT92whREFpLv9cj5lTeJSibyr/Mrm/YtjCZVWgaOYIhwrXwKLqPr/11inWsAkfIy
6
+ tvHWTxZYEcXLgAXFuUuaS3uF9gEiNQwzGTU1v0FqkqTBr4B8nW3HCN47XUu0t8Y0
7
+ e+lf4s4OxQawWD79J9/5d3Ry0vbV3Am1FtGJiJvOwRsIfVChDpYStTcHTCMqtvWb
8
+ V6L11BWkpzGXSW4Hv43qa+GSYOD2QU68Mb59oSk2OB+BtOLpJofmbGEGgvmwyCI9
9
+ MwIDAQAB
10
+ -----END PUBLIC KEY-----`;
11
+ export const SAMPLE_PRIVATEKEY = `-----BEGIN PRIVATE KEY-----
12
+ MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCfPKKzVmN80HRs
13
+ GAoUxK++RO3CW8GxomrtLnAD6TN5U5WlVbCRZ1WFrizfxcz+lr/Kvjtq/v7PdVOa
14
+ 8NHIAdxpP3bCFEQWku/1yPmVN4lKJvKv8yub9i2MJlVaBo5giHCtfAouo+v/XWKd
15
+ awCR8jK28dZPFlgRxcuABcW5S5pLe4X2ASI1DDMZNTW/QWqSpMGvgHydbccI3jtd
16
+ S7S3xjR76V/izg7FBrBYPv0n3/l3dHLS9tXcCbUW0YmIm87BGwh9UKEOlhK1NwdM
17
+ Iyq29ZtXovXUFaSnMZdJbge/jepr4ZJg4PZBTrwxvn2hKTY4H4G04ukmh+ZsYQaC
18
+ +bDIIj0zAgMBAAECggEAKIBGrbCSW2O1yOyQW9nvDUkA5EdsS58Q7US7bvM4iWpu
19
+ DIBwCXur7/VuKnhn/HUhURLzj/JNozynSChqYyG+CvL+ZLy82LUE3ZIBkSdv/vFL
20
+ Ft+VvvRtf1EcsmoqenkZl7aN7HD7DJeXBoz5tyVQKuH17WW0fsi9StGtCcUl+H6K
21
+ zV9Gif0Kj0uLQbCg3THRvKuueBTwCTdjoP0PwaNADgSWb3hJPeLMm/yII4tIMGbO
22
+ w+xd9wJRl+ZN9nkNtQMxszFGdKjedB6goYLQuP0WRZx+YtykaVJdM75bDUvsQar4
23
+ 9Pc21Fp7UVk/CN11DX/hX3TmTJAUtqYADliVKkTbCQKBgQDLU48tBxm3g1CdDM/P
24
+ ZIEmpA3Y/m7e9eX7M1Uo/zDh4G/S9a4kkX6GQY2dLFdCtOS8M4hR11Io7MceBKDi
25
+ djorTZ5zJPQ8+b9Rm+1GlaucGNwRW0cQk2ltT2ksPmJnQn2xvM9T8vE+a4A/YGzw
26
+ mZOfpoVGykWs/tbSzU2aTaOybQKBgQDIfRf6OmirGPh59l+RSuDkZtISF/51mCV/
27
+ S1M4DltWDwhjC2Y2T+meIsb/Mjtz4aVNz0EHB8yvn0TMGr94Uwjv4uBdpVSwz+xL
28
+ hHL7J4rpInH+i0gxa0N+rGwsPwI8wJG95wLY+Kni5KCuXQw55uX1cqnnsahpRZFZ
29
+ EerBXhjqHwKBgBmEjiaHipm2eEqNjhMoOPFBi59dJ0sCL2/cXGa9yEPA6Cfgv49F
30
+ V0zAM2azZuwvSbm4+fXTgTMzrDW/PPXPArPmlOk8jQ6OBY3XdOrz48q+b/gZrYyO
31
+ A6A9ZCSyW6U7+gxxds/BYLeFxF2v21xC2f0iZ/2faykv/oQMUh34en/tAoGACqVZ
32
+ 2JexZyR0TUWf3X80YexzyzIq+OOTWicNzDQ29WLm9xtr2gZ0SUlfd72bGpQoyvDu
33
+ awkm/UxfwtbIxALkvpg1gcN9s8XWrkviLyPyZF7H3tRWiQlBFEDjnZXa8I7pLkRO
34
+ Cmdp3fp17cxTEeAI5feovfzZDH39MdWZuZrdh9ECgYBTEv8S7nK8wrxIC390kroV
35
+ 52eBwzckQU2mWa0thUtaGQiU1EYPCSDcjkrLXwB72ft0dW57KyWtvrB6rt1ORgOL
36
+ eI5hFbwdGQhCHTrAR1vG3SyFPMAm+8JB+sGOD/fvjtZKx//MFNweKFNEF0C/o6Z2
37
+ FXj90PlgF8sCQut36ZfuIQ==
38
+ -----END PRIVATE KEY-----`;
39
+
40
+ export const SAMPLE_TOKEN = `eyJhbGciOiJSUzUxMiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWUsImlhdCI6MTUxNjIzOTAyMn0.JlX3gXGyClTBFciHhknWrjo7SKqyJ5iBO0n-3S2_I7cIgfaZAeRDJ3SQEbaPxVC7X8aqGCOM-pQOjZPKUJN8DMFrlHTOdqMs0TwQ2PRBmVAxXTSOZOoEhD4ZNCHohYoyfoDhJDP4Qye_FCqu6POJzg0Jcun4d3KW04QTiGxv2PkYqmB7nHxYuJdnqE3704hIS56pc_8q6AW0WIT0W-nIvwzaSbtBU9RgaC7ZpBD2LiNE265UBIFraMDF8IAFw9itZSUCTKg1Q-q27NwwBZNGYStMdIBDor2Bsq5ge51EkWajzZ7ALisVp-bskzUsqUf77ejqX_CBAqkNdH1Zebn93A`;
41
+ export const SAMPLE_TOKEN_INVALID = `eyJhbGciOiJSUzUxMiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lISIsImFkbWluIjp0cnVlLCJpYXQiOjE1MTYyMzkwMjJ9.JlX3gXGyClTBFciHhknWrjo7SKqyJ5iBO0n-3S2_I7cIgfaZAeRDJ3SQEbaPxVC7X8aqGCOM-pQOjZPKUJN8DMFrlHTOdqMs0TwQ2PRBmVAxXTSOZOoEhD4ZNCHohYoyfoDhJDP4Qye_FCqu6POJzg0Jcun4d3KW04QTiGxv2PkYqmB7nHxYuJdnqE3704hIS56pc_8q6AW0WIT0W-nIvwzaSbtBU9RgaC7ZpBD2LiNE265UBIFraMDF8IAFw9itZSUCTKg1Q-q27NwwBZNGYStMdIBDor2Bsq5ge51EkWajzZ7ALisVp-bskzUsqUf77ejqX_CBAqkNdH1Zebn93A`;
42
+
43
+
44
+ export const SAMPLE_PUBKEY_2 = `-----BEGIN PUBLIC KEY-----
45
+ MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnzyis1ZjfNB0bBgKFMSv
46
+ vkTtwlvBsaJq7S5wA+kzeVOVpVWwkWdVha4s38XM/pa/yr47av7+z3VTmvDRyAHc
47
+ aT92whREFpLv9cj5lTeJSibyr/Mrm/YtjCZVWgaOYIhwrXwKLqPr/11inWsAkfIy
48
+ tvHWTxZYEcXLgAXFuUuaS3uF9gEiNQwzGTU1v0FqkqTBr4B8nW3HCN47XUu0t8Y0
49
+ e+lf4s4OxQawWD79J9/5d3Ry0vbV3Am1FtGJiJvOwRsIfVChDpYStTcHTCMqtvWb
50
+ V6L11BWkpzGXSW4Hv43qa+GSYOD2QU68Mb59oSk2OB+BtOLpJofmbGEGgvmwyCI9
51
+ MwIDAQAB
52
+ -----END PUBLIC KEY-----`;
53
+
54
+ export const SAMPLE_PRIVATEKEY_2 = `-----BEGIN PRIVATE KEY-----
55
+ MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDfj0kY6x9bEcNe
56
+ UUtRxPDzQ6rdaVnsC82QPdnwrXqrd6Bu+HmsmcKfwNxTT5m7H2gDQ+clEn7zTJ+u
57
+ sLB3moSmiz6mfRE87rTgNSW5Y8l9uvsV2GCEf1+GIBtdw75Cicq1fE8v+4yMu4xk
58
+ 8NJkY4AyhihOsq7QARB6i1KM5FHOh2aYMZQI+Hx1J9M6fj0GKJbCJh2VkXyqwNb9
59
+ 3SvfYLPLSSkTmzOpdRxQfI8Ql9pri0zHUerhFzy8wmHhSz52qRJknZKnhKU6HAsX
60
+ v7a5lh8C5fXcgad6tpmKJKBpEx00EtLMyqkb0gBzjKUvEbqWjB5659LH6WQZeMuY
61
+ g6abbDbnAgMBAAECggEAL3y/OTTQf0bBqio4hpD/4ZyREeEMAdDsBGSvA6nF8eBC
62
+ SvAq4Ff0+Hw+ENBKxm3AaVkmI0DPiJzRGolborxGyx2u3Cya2ceW0j1X2w5wQW3T
63
+ YeuJbPulbdcqGPu4UWf1kCFsrLORQl+gTdy9xCdClvjaXQUljvd66Zzolxb0rZq9
64
+ keRREJ55VZazBhwjtvfwII7chwzNdFzAX5Ft9IPFOaBoi13bCPTzUPeIazbktwIv
65
+ FpKA51M12LF+fJpY608ACP5FR6ShnAxPbvpgOcVtxhuBvAdDu2jTvB9yASsNnHjE
66
+ VXp1mTBTx+HsO6onIFqkN5fC/3ds+3zyOScu6RkGMQKBgQD7/h/lKRtEWJVML+ag
67
+ a+V2WUy6Yel5IgF7DeH8Z78QOLhB1MUr8jXD8skMcTZiSYuF8rRV5FVHAbv+pnwC
68
+ NkZclCNQqoOVbhIT8wBV+TE0ay5ZSLqLkhCdmmYaBg6WccfzPmcIRwTgC3QWSyku
69
+ jjpRLxEPTEzbnNRuKFaOSbctKQKBgQDjHWiqiSXXEbQdI80cJmoz1o+gLtUKVdK/
70
+ GyUak/AX4PLhG4VZHHHt/AArPYr+eEQcN6aCsWU8qRt6H3LyhBjev93CHAKs4snG
71
+ +edQ7xK0kqervR4KXweTD+wqUVglvqmstGwkI33CFUZwE7t6bKgmALfgdeJxFCLM
72
+ ScV8y0y1jwKBgQDZXjh9IJxYtGD0u00hjHD/ScCZ9ePDjcXhM/SAGa4CfCrU/oim
73
+ g+RFBqTOisnytqYYAWf1v2SgP6q+2zWVYuQG7/IWnz+qIqyNcMwVXUNIiDwO4GGq
74
+ C3ExwgHY6OikdbmY5XdS+JAIA1k78dGwSxea+BKrM5IIzpuf+kPPsV7FIQKBgAOW
75
+ NE/1KIbT/b80EIowRR8adVw3QSAPqOtht11LFtCZudw6PgnhPB9hCnOkXiyUo6a6
76
+ bkPEH3Asz4VHN96CnY3vA8aMALLQRhWBXtjVXbtCUamRrAbH52u4JaepbzXxY+aZ
77
+ VtffQ54sDde5SA2v55vqCP1ffzr/8Wi+hYLqBwUbAoGBAIhtiyG3DVX0j0z1EICq
78
+ ZR2HJJk7KKPcrUGW0fbNqnxIrjqBq22PGD6rkFHQFpD/y/u7NGpOFU12tk099ly+
79
+ EZFf9T6VsMw+7sUFo88gTDL9BK6IBcsYDr5I7QfN5WkXbsrx/s9Yll7urISU3z7o
80
+ eUhPf0cYfvNPR4eQb5FLLrDX
81
+ -----END PRIVATE KEY-----`;
package/src/index.ts ADDED
@@ -0,0 +1,5 @@
1
+ import { JWTEngine } from './common';
2
+
3
+ export * from './common';
4
+
5
+ export function createJWTEngine() : JWTEngine { throw new Error('No implementation selected'); };
@@ -0,0 +1,4 @@
1
+ import { engineTest } from "../engine.test";
2
+ import { JWT } from "./index";
3
+
4
+ engineTest('NodeJWT', JWT);
@@ -0,0 +1,56 @@
1
+ import { JWTEngine, EncodeOptions, Token, DecodeOptions } from "../common/interface";
2
+ import * as jsonwebtoken from 'jsonwebtoken';
3
+ import { Base64URL } from "../browser/base64url";
4
+ import { validateExpiry } from "../common";
5
+ export * from '../common';
6
+
7
+ export class NodeJWT implements JWTEngine {
8
+ async decodeUntrusted(token: string): Promise<Token> {
9
+ let decodedToken = <Record<string,any>>jsonwebtoken.decode(token);
10
+ return { claims: decodedToken, string: token };
11
+ }
12
+
13
+ async encode(claims: Record<string, any>, options: EncodeOptions): Promise<Token> {
14
+ let string = jsonwebtoken.sign(claims, options.secretOrKey, {
15
+ algorithm: <any>options.algorithm
16
+ });
17
+
18
+ return {
19
+ string,
20
+ claims
21
+ }
22
+ }
23
+
24
+ async validate(string : string, options: DecodeOptions): Promise<Token> {
25
+ let claims : Record<string,any>;
26
+
27
+ try {
28
+ claims = <Record<string,any>>jsonwebtoken.verify(string, options.secretOrKey, {
29
+ algorithms: [ <any>options.algorithm ],
30
+ ignoreExpiration: true
31
+ });
32
+ } catch (e) {
33
+ if (e.message === 'invalid signature') // For uniformity
34
+ throw new Error(`Cannot validate JWT '${string}': Invalid signature`);
35
+ else if (e.message === 'invalid algorithm')
36
+ throw new Error(`Cannot validate JWT '${string}': Token has incorrect algorithm`);
37
+
38
+ throw e;
39
+ }
40
+
41
+ try {
42
+ validateExpiry(claims.exp, options.now, options.validate?.exp);
43
+ } catch (e) {
44
+ throw new Error(`Cannot validate JWT '${string}': ${e.message}`);
45
+ }
46
+
47
+ return {
48
+ string,
49
+ claims
50
+ }
51
+ }
52
+
53
+ }
54
+
55
+ export function createJWTEngine() : JWTEngine { return new NodeJWT(); };
56
+ export const JWT = createJWTEngine();