@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.
- package/LICENSE +21 -0
- package/README.md +107 -0
- package/demo.key +27 -0
- package/demo8.key +28 -0
- package/dist/browser/base64url.d.ts +4 -0
- package/dist/browser/base64url.js +18 -0
- package/dist/browser/base64url.js.map +1 -0
- package/dist/browser/index.d.ts +5 -0
- package/dist/browser/index.js +21 -0
- package/dist/browser/index.js.map +1 -0
- package/dist/browser/utils.d.ts +6 -0
- package/dist/browser/utils.js +24 -0
- package/dist/browser/utils.js.map +1 -0
- package/dist/browser/webcrypto-jwt.d.ts +22 -0
- package/dist/browser/webcrypto-jwt.js +378 -0
- package/dist/browser/webcrypto-jwt.js.map +1 -0
- package/dist/browser/webcrypto-jwt.test.d.ts +1 -0
- package/dist/browser/webcrypto-jwt.test.js +6 -0
- package/dist/browser/webcrypto-jwt.test.js.map +1 -0
- package/dist/common/expiry.d.ts +1 -0
- package/dist/common/expiry.js +25 -0
- package/dist/common/expiry.js.map +1 -0
- package/dist/common/index.d.ts +2 -0
- package/dist/common/index.js +15 -0
- package/dist/common/index.js.map +1 -0
- package/dist/common/interface.d.ts +38 -0
- package/dist/common/interface.js +3 -0
- package/dist/common/interface.js.map +1 -0
- package/dist/engine.test.d.ts +10 -0
- package/dist/engine.test.js +295 -0
- package/dist/engine.test.js.map +1 -0
- package/dist/fixtures/es256.fixture.d.ts +6 -0
- package/dist/fixtures/es256.fixture.js +10 -0
- package/dist/fixtures/es256.fixture.js.map +1 -0
- package/dist/fixtures/hs256.fixture.d.ts +6 -0
- package/dist/fixtures/hs256.fixture.js +10 -0
- package/dist/fixtures/hs256.fixture.js.map +1 -0
- package/dist/fixtures/hs384.fixture.d.ts +6 -0
- package/dist/fixtures/hs384.fixture.js +10 -0
- package/dist/fixtures/hs384.fixture.js.map +1 -0
- package/dist/fixtures/hs512.fixture.d.ts +6 -0
- package/dist/fixtures/hs512.fixture.js +10 -0
- package/dist/fixtures/hs512.fixture.js.map +1 -0
- package/dist/fixtures/rs256.fixture.d.ts +6 -0
- package/dist/fixtures/rs256.fixture.js +10 -0
- package/dist/fixtures/rs256.fixture.js.map +1 -0
- package/dist/fixtures/rs512.fixture.d.ts +6 -0
- package/dist/fixtures/rs512.fixture.js +10 -0
- package/dist/fixtures/rs512.fixture.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +18 -0
- package/dist/index.js.map +1 -0
- package/dist/node/engine.test.d.ts +1 -0
- package/dist/node/engine.test.js +6 -0
- package/dist/node/engine.test.js.map +1 -0
- package/dist/node/index.d.ts +9 -0
- package/dist/node/index.js +117 -0
- package/dist/node/index.js.map +1 -0
- package/dist/test.d.ts +1 -0
- package/dist/test.js +9 -0
- package/dist/test.js.map +1 -0
- package/karma.conf.ts +59 -0
- package/package.json +46 -0
- package/src/browser/base64url.ts +12 -0
- package/src/browser/index.ts +6 -0
- package/src/browser/utils.ts +20 -0
- package/src/browser/webcrypto-jwt.test.ts +4 -0
- package/src/browser/webcrypto-jwt.ts +351 -0
- package/src/common/expiry.ts +25 -0
- package/src/common/index.ts +2 -0
- package/src/common/interface.ts +47 -0
- package/src/engine.test.ts +173 -0
- package/src/fixtures/es256.fixture.ts +25 -0
- package/src/fixtures/hs256.fixture.ts +6 -0
- package/src/fixtures/hs384.fixture.ts +6 -0
- package/src/fixtures/hs512.fixture.ts +6 -0
- package/src/fixtures/rs256.fixture.ts +81 -0
- package/src/fixtures/rs512.fixture.ts +81 -0
- package/src/index.ts +5 -0
- package/src/node/engine.test.ts +4 -0
- package/src/node/index.ts +56 -0
- package/src/test.ts +7 -0
- package/tsconfig.json +37 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) Astronaut Labs, LLC.
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
# @/jwt
|
|
2
|
+
|
|
3
|
+
> This library is **Alpha quality** in the `0.0.x` series (no automatic updates
|
|
4
|
+
> by semver). Please take caution if you choose to use it, and do not use it
|
|
5
|
+
> in production. We welcome PRs for fixes, features and general improvements.
|
|
6
|
+
|
|
7
|
+
A simple isomorphic JWT library (works in browser and Node.js) with support for
|
|
8
|
+
signing and verifying JWTs using a number of common algorithms.
|
|
9
|
+
|
|
10
|
+
# Installation
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
npm install @astronautlabs/jwt
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
# Usage
|
|
17
|
+
|
|
18
|
+
## Common Options
|
|
19
|
+
|
|
20
|
+
- `now` -- Specify the UNIX wall clock time to use when enforcing `exp` claims. When not specified, `Date.now()` is used.
|
|
21
|
+
- `algorithm` -- The signature algorithm to use. See [Supported Algorithms](#supported-algorithms) for the options.
|
|
22
|
+
- `secretOrKey` -- The key to use for the operation. When using asymmetric
|
|
23
|
+
algorithms (like `RS256`, `ES256`, etc) you should pass public keys for
|
|
24
|
+
`validate()` and private keys for `encode()`
|
|
25
|
+
|
|
26
|
+
## Signing
|
|
27
|
+
|
|
28
|
+
```typescript
|
|
29
|
+
async encode(claims: any, options: EncodeOptions): Promise<Token>
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
### Remarks
|
|
33
|
+
|
|
34
|
+
Returns a `Token` object with the given claims, and signed by the credentials
|
|
35
|
+
specified in `options` (see `algorithm` and `secretOrKey`).
|
|
36
|
+
|
|
37
|
+
### Example
|
|
38
|
+
|
|
39
|
+
```typescript
|
|
40
|
+
import { JWT } from '@astronautlabs/jwt';
|
|
41
|
+
|
|
42
|
+
try {
|
|
43
|
+
let token = await JWT.encode({ sub: 123 }, { algorithm: 'HS256', secretOrKey: 'stuff' });
|
|
44
|
+
console.dir(token); // => { string: 'eY...', claims: { sub: ..., ... } }
|
|
45
|
+
} catch (e) {
|
|
46
|
+
console.error('Failed to validate token: ');
|
|
47
|
+
console.error(e);
|
|
48
|
+
}
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
## Validation
|
|
53
|
+
|
|
54
|
+
```typescript
|
|
55
|
+
JWT.validate(string : string, options: DecodeOptions): Promise<Token>
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Returns a `Token` object if the given string is a valid (and trusted) JWT.
|
|
59
|
+
If validation fails, throws an `Error`.
|
|
60
|
+
|
|
61
|
+
Types of errors `JWT.validate()` can throw:
|
|
62
|
+
- Algorithm mismatch: If the token header's `alg` claim does not match the
|
|
63
|
+
configured algorithm (`options.algorithm`)
|
|
64
|
+
- Signature mismatch: If the signature does not match
|
|
65
|
+
- Expiration: If the token's `exp` claim is not acceptable according to policy
|
|
66
|
+
|
|
67
|
+
```typescript
|
|
68
|
+
import { JWT } from '@astronautlabs/jwt';
|
|
69
|
+
|
|
70
|
+
try {
|
|
71
|
+
let token = await JWT.validate(`eY...`, { algorithm: 'HS256', secretOrKey: 'stuff' });
|
|
72
|
+
console.dir(token); // => { string: 'eY...', claims: { sub: ..., ... } }
|
|
73
|
+
} catch (e) {
|
|
74
|
+
console.error('Failed to validate token: ');
|
|
75
|
+
console.error(e);
|
|
76
|
+
}
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### Expiration
|
|
80
|
+
|
|
81
|
+
You can configure a policy for built-in validation of the `exp` claim when validating tokens.
|
|
82
|
+
To do so, specify `{ validate: { exp: "(policyName)" }}` within the `options` passed to `JWT.validate()`.
|
|
83
|
+
|
|
84
|
+
The available policies are:
|
|
85
|
+
- `when-present` (default) -- When a token has an `exp` claim, fail validation if the token is expired
|
|
86
|
+
- `force` -- Require tokens to have a valid (fresh) `exp` claim
|
|
87
|
+
- `ignore` -- Ignore `exp` even when it is present (it will still be available on `token.claims`).
|
|
88
|
+
|
|
89
|
+
You can override the current time by providing `options.now`. Consider using this instead
|
|
90
|
+
of `options.validate.exp = 'ignore'`.
|
|
91
|
+
|
|
92
|
+
### Options
|
|
93
|
+
|
|
94
|
+
- `validate`
|
|
95
|
+
* `exp` -- Expiration policy. For more see [Expiration](#expiration)
|
|
96
|
+
|
|
97
|
+
# Supported Platforms
|
|
98
|
+
- **Browser/Web** using WebCrypto
|
|
99
|
+
- **Node.js**
|
|
100
|
+
|
|
101
|
+
# Supported Algorithms
|
|
102
|
+
- `HS256`
|
|
103
|
+
- `HS384`
|
|
104
|
+
- `HS512`
|
|
105
|
+
- `RS256`
|
|
106
|
+
- `RS512`
|
|
107
|
+
- `ES256`
|
package/demo.key
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
-----BEGIN RSA PRIVATE KEY-----
|
|
2
|
+
MIIEogIBAAKCAQEAnzyis1ZjfNB0bBgKFMSvvkTtwlvBsaJq7S5wA+kzeVOVpVWw
|
|
3
|
+
kWdVha4s38XM/pa/yr47av7+z3VTmvDRyAHcaT92whREFpLv9cj5lTeJSibyr/Mr
|
|
4
|
+
m/YtjCZVWgaOYIhwrXwKLqPr/11inWsAkfIytvHWTxZYEcXLgAXFuUuaS3uF9gEi
|
|
5
|
+
NQwzGTU1v0FqkqTBr4B8nW3HCN47XUu0t8Y0e+lf4s4OxQawWD79J9/5d3Ry0vbV
|
|
6
|
+
3Am1FtGJiJvOwRsIfVChDpYStTcHTCMqtvWbV6L11BWkpzGXSW4Hv43qa+GSYOD2
|
|
7
|
+
QU68Mb59oSk2OB+BtOLpJofmbGEGgvmwyCI9MwIDAQABAoIBACiARq2wkltjtcjs
|
|
8
|
+
kFvZ7w1JAORHbEufEO1Eu27zOIlqbgyAcAl7q+/1bip4Z/x1IVES84/yTaM8p0go
|
|
9
|
+
amMhvgry/mS8vNi1BN2SAZEnb/7xSxbflb70bX9RHLJqKnp5GZe2jexw+wyXlwaM
|
|
10
|
+
+bclUCrh9e1ltH7IvUrRrQnFJfh+is1fRon9Co9Li0GwoN0x0byrrngU8Ak3Y6D9
|
|
11
|
+
D8GjQA4Elm94ST3izJv8iCOLSDBmzsPsXfcCUZfmTfZ5DbUDMbMxRnSo3nQeoKGC
|
|
12
|
+
0Lj9FkWcfmLcpGlSXTO+Ww1L7EGq+PT3NtRae1FZPwjddQ1/4V905kyQFLamAA5Y
|
|
13
|
+
lSpE2wkCgYEAy1OPLQcZt4NQnQzPz2SBJqQN2P5u3vXl+zNVKP8w4eBv0vWuJJF+
|
|
14
|
+
hkGNnSxXQrTkvDOIUddSKOzHHgSg4nY6K02ecyT0PPm/UZvtRpWrnBjcEVtHEJNp
|
|
15
|
+
bU9pLD5iZ0J9sbzPU/LxPmuAP2Bs8JmTn6aFRspFrP7W0s1Nmk2jsm0CgYEAyH0X
|
|
16
|
+
+jpoqxj4efZfkUrg5GbSEhf+dZglf0tTOA5bVg8IYwtmNk/pniLG/zI7c+GlTc9B
|
|
17
|
+
BwfMr59EzBq/eFMI7+LgXaVUsM/sS4Ry+yeK6SJx/otIMWtDfqxsLD8CPMCRvecC
|
|
18
|
+
2Pip4uSgrl0MOebl9XKp57GoaUWRWRHqwV4Y6h8CgYAZhI4mh4qZtnhKjY4TKDjx
|
|
19
|
+
QYufXSdLAi9v3FxmvchDwOgn4L+PRVdMwDNms2bsL0m5uPn104EzM6w1vzz1zwKz
|
|
20
|
+
5pTpPI0OjgWN13Tq8+PKvm/4Ga2MjgOgPWQkslulO/oMcXbPwWC3hcRdr9tcQtn9
|
|
21
|
+
Imf9n2spL/6EDFId+Hp/7QKBgAqlWdiXsWckdE1Fn91/NGHsc8syKvjjk1onDcw0
|
|
22
|
+
NvVi5vcba9oGdElJX3e9mxqUKMrw7msJJv1MX8LWyMQC5L6YNYHDfbPF1q5L4i8j
|
|
23
|
+
8mRex97UVokJQRRA452V2vCO6S5ETgpnad36de3MUxHgCOX3qL382Qx9/THVmbma
|
|
24
|
+
3YfRAoGAUxL/Eu5yvMK8SAt/dJK6FedngcM3JEFNplmtLYVLWhkIlNRGDwkg3I5K
|
|
25
|
+
y18Ae9n7dHVueyslrb6weq7dTkYDi3iOYRW8HRkIQh06wEdbxt0shTzAJvvCQfrB
|
|
26
|
+
jg/3747WSsf/zBTcHihTRBdAv6OmdhV4/dD5YBfLAkLrd+mX7iE=
|
|
27
|
+
-----END RSA PRIVATE KEY-----
|
package/demo8.key
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
-----BEGIN PRIVATE KEY-----
|
|
2
|
+
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCfPKKzVmN80HRs
|
|
3
|
+
GAoUxK++RO3CW8GxomrtLnAD6TN5U5WlVbCRZ1WFrizfxcz+lr/Kvjtq/v7PdVOa
|
|
4
|
+
8NHIAdxpP3bCFEQWku/1yPmVN4lKJvKv8yub9i2MJlVaBo5giHCtfAouo+v/XWKd
|
|
5
|
+
awCR8jK28dZPFlgRxcuABcW5S5pLe4X2ASI1DDMZNTW/QWqSpMGvgHydbccI3jtd
|
|
6
|
+
S7S3xjR76V/izg7FBrBYPv0n3/l3dHLS9tXcCbUW0YmIm87BGwh9UKEOlhK1NwdM
|
|
7
|
+
Iyq29ZtXovXUFaSnMZdJbge/jepr4ZJg4PZBTrwxvn2hKTY4H4G04ukmh+ZsYQaC
|
|
8
|
+
+bDIIj0zAgMBAAECggEAKIBGrbCSW2O1yOyQW9nvDUkA5EdsS58Q7US7bvM4iWpu
|
|
9
|
+
DIBwCXur7/VuKnhn/HUhURLzj/JNozynSChqYyG+CvL+ZLy82LUE3ZIBkSdv/vFL
|
|
10
|
+
Ft+VvvRtf1EcsmoqenkZl7aN7HD7DJeXBoz5tyVQKuH17WW0fsi9StGtCcUl+H6K
|
|
11
|
+
zV9Gif0Kj0uLQbCg3THRvKuueBTwCTdjoP0PwaNADgSWb3hJPeLMm/yII4tIMGbO
|
|
12
|
+
w+xd9wJRl+ZN9nkNtQMxszFGdKjedB6goYLQuP0WRZx+YtykaVJdM75bDUvsQar4
|
|
13
|
+
9Pc21Fp7UVk/CN11DX/hX3TmTJAUtqYADliVKkTbCQKBgQDLU48tBxm3g1CdDM/P
|
|
14
|
+
ZIEmpA3Y/m7e9eX7M1Uo/zDh4G/S9a4kkX6GQY2dLFdCtOS8M4hR11Io7MceBKDi
|
|
15
|
+
djorTZ5zJPQ8+b9Rm+1GlaucGNwRW0cQk2ltT2ksPmJnQn2xvM9T8vE+a4A/YGzw
|
|
16
|
+
mZOfpoVGykWs/tbSzU2aTaOybQKBgQDIfRf6OmirGPh59l+RSuDkZtISF/51mCV/
|
|
17
|
+
S1M4DltWDwhjC2Y2T+meIsb/Mjtz4aVNz0EHB8yvn0TMGr94Uwjv4uBdpVSwz+xL
|
|
18
|
+
hHL7J4rpInH+i0gxa0N+rGwsPwI8wJG95wLY+Kni5KCuXQw55uX1cqnnsahpRZFZ
|
|
19
|
+
EerBXhjqHwKBgBmEjiaHipm2eEqNjhMoOPFBi59dJ0sCL2/cXGa9yEPA6Cfgv49F
|
|
20
|
+
V0zAM2azZuwvSbm4+fXTgTMzrDW/PPXPArPmlOk8jQ6OBY3XdOrz48q+b/gZrYyO
|
|
21
|
+
A6A9ZCSyW6U7+gxxds/BYLeFxF2v21xC2f0iZ/2faykv/oQMUh34en/tAoGACqVZ
|
|
22
|
+
2JexZyR0TUWf3X80YexzyzIq+OOTWicNzDQ29WLm9xtr2gZ0SUlfd72bGpQoyvDu
|
|
23
|
+
awkm/UxfwtbIxALkvpg1gcN9s8XWrkviLyPyZF7H3tRWiQlBFEDjnZXa8I7pLkRO
|
|
24
|
+
Cmdp3fp17cxTEeAI5feovfzZDH39MdWZuZrdh9ECgYBTEv8S7nK8wrxIC390kroV
|
|
25
|
+
52eBwzckQU2mWa0thUtaGQiU1EYPCSDcjkrLXwB72ft0dW57KyWtvrB6rt1ORgOL
|
|
26
|
+
eI5hFbwdGQhCHTrAR1vG3SyFPMAm+8JB+sGOD/fvjtZKx//MFNweKFNEF0C/o6Z2
|
|
27
|
+
FXj90PlgF8sCQut36ZfuIQ==
|
|
28
|
+
-----END PRIVATE KEY-----
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Base64URL = void 0;
|
|
4
|
+
var Base64URL = /** @class */ (function () {
|
|
5
|
+
function Base64URL() {
|
|
6
|
+
}
|
|
7
|
+
Base64URL.stringify = function (a) {
|
|
8
|
+
var base64string = btoa(String.fromCharCode.apply(0, a));
|
|
9
|
+
return base64string.replace(/=/g, '').replace(/\+/g, '-').replace(/\//g, '_');
|
|
10
|
+
};
|
|
11
|
+
Base64URL.parse = function (s) {
|
|
12
|
+
s = s.replace(/-/g, '+').replace(/_/g, '/').replace(/\s/g, '');
|
|
13
|
+
return new Uint8Array(Array.prototype.map.call(atob(s), function (c) { return c.charCodeAt(0); }));
|
|
14
|
+
};
|
|
15
|
+
return Base64URL;
|
|
16
|
+
}());
|
|
17
|
+
exports.Base64URL = Base64URL;
|
|
18
|
+
//# sourceMappingURL=base64url.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base64url.js","sourceRoot":"","sources":["../../src/browser/base64url.ts"],"names":[],"mappings":";;;AACA;IAAA;IAUA,CAAC;IATiB,mBAAS,GAAvB,UAAwB,CAAC;QACrB,IAAI,YAAY,GAAG,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QACzD,OAAO,YAAY,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IAClF,CAAC;IAEa,eAAK,GAAnB,UAAoB,CAAC;QACjB,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QAC/D,OAAO,IAAI,UAAU,CAAC,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,UAAA,CAAC,IAAI,OAAA,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,EAAf,CAAe,CAAC,CAAC,CAAC;IACnF,CAAC;IACL,gBAAC;AAAD,CAAC,AAVD,IAUC;AAVY,8BAAS"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
5
|
+
}) : (function(o, m, k, k2) {
|
|
6
|
+
if (k2 === undefined) k2 = k;
|
|
7
|
+
o[k2] = m[k];
|
|
8
|
+
}));
|
|
9
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
10
|
+
for (var p in m) if (p !== "default" && !exports.hasOwnProperty(p)) __createBinding(exports, m, p);
|
|
11
|
+
};
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
exports.JWT = exports.createJWTEngine = void 0;
|
|
14
|
+
var webcrypto_jwt_1 = require("./webcrypto-jwt");
|
|
15
|
+
__exportStar(require("../common"), exports);
|
|
16
|
+
__exportStar(require("./webcrypto-jwt"), exports);
|
|
17
|
+
function createJWTEngine() { return new webcrypto_jwt_1.WebCryptoJWT(); }
|
|
18
|
+
exports.createJWTEngine = createJWTEngine;
|
|
19
|
+
;
|
|
20
|
+
exports.JWT = createJWTEngine();
|
|
21
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/browser/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;AACA,iDAA+C;AAC/C,4CAA0B;AAC1B,kDAAgC;AAChC,SAAgB,eAAe,KAAiB,OAAO,IAAI,4BAAY,EAAE,CAAC,CAAC,CAAC;AAA5E,0CAA4E;AAAA,CAAC;AAChE,QAAA,GAAG,GAAG,eAAe,EAAE,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Utils = void 0;
|
|
4
|
+
var base64url_1 = require("./base64url");
|
|
5
|
+
var Utils = /** @class */ (function () {
|
|
6
|
+
function Utils() {
|
|
7
|
+
}
|
|
8
|
+
Utils.isString = function (s) {
|
|
9
|
+
return typeof s === 'string';
|
|
10
|
+
};
|
|
11
|
+
Utils.utf8ToUint8Array = function (str) {
|
|
12
|
+
str = btoa(unescape(encodeURIComponent(str)));
|
|
13
|
+
return base64url_1.Base64URL.parse(str);
|
|
14
|
+
};
|
|
15
|
+
Utils.isFunction = function (fn) {
|
|
16
|
+
return typeof fn === 'function';
|
|
17
|
+
};
|
|
18
|
+
Utils.isObject = function (arg) {
|
|
19
|
+
return arg !== null && typeof arg === 'object';
|
|
20
|
+
};
|
|
21
|
+
return Utils;
|
|
22
|
+
}());
|
|
23
|
+
exports.Utils = Utils;
|
|
24
|
+
//# sourceMappingURL=utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/browser/utils.ts"],"names":[],"mappings":";;;AAAA,yCAAwC;AAExC;IAAA;IAiBA,CAAC;IAhBiB,cAAQ,GAAtB,UAAuB,CAAC;QACpB,OAAO,OAAO,CAAC,KAAK,QAAQ,CAAC;IACjC,CAAC;IAEa,sBAAgB,GAA9B,UAA+B,GAAG;QAC9B,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,kBAAkB,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QAC9C,OAAO,qBAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAChC,CAAC;IAEa,gBAAU,GAAxB,UAAyB,EAAE;QACvB,OAAO,OAAO,EAAE,KAAK,UAAU,CAAC;IACpC,CAAC;IAEa,cAAQ,GAAtB,UAAuB,GAAG;QACtB,OAAO,GAAG,KAAK,IAAI,IAAI,OAAO,GAAG,KAAK,QAAQ,CAAC;IACnD,CAAC;IACL,YAAC;AAAD,CAAC,AAjBD,IAiBC;AAjBY,sBAAK"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { JWTEngine, EncodeOptions, Token, DecodeOptions } from "../common/interface";
|
|
2
|
+
export declare class WebCryptoJWT implements JWTEngine {
|
|
3
|
+
private subtleCrypto?;
|
|
4
|
+
constructor(subtleCrypto?: SubtleCrypto);
|
|
5
|
+
decodeUntrusted(token: string): Promise<Token>;
|
|
6
|
+
private findSubtleCrypto;
|
|
7
|
+
encode(payload: Record<string, any>, options: EncodeOptions): Promise<Token>;
|
|
8
|
+
validate(string: string, options: DecodeOptions): Promise<Token>;
|
|
9
|
+
private algorithmOf;
|
|
10
|
+
private str2ab;
|
|
11
|
+
/**
|
|
12
|
+
* Adapted from https://chromium.googlesource.com/chromium/blink/+/master/LayoutTests/crypto/subtle/hmac/sign-verify.html
|
|
13
|
+
*
|
|
14
|
+
* @param token
|
|
15
|
+
* @param secret
|
|
16
|
+
* @param alg
|
|
17
|
+
*/
|
|
18
|
+
private _verify;
|
|
19
|
+
private _sign;
|
|
20
|
+
private _decode;
|
|
21
|
+
private _decodeBase64URL;
|
|
22
|
+
}
|
|
@@ -0,0 +1,378 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Originally from https://github.com/pose/webcrypto-jwt
|
|
3
|
+
// (C) Copyright (c) 2015 Alberto Pose albertopose@gmail.com
|
|
4
|
+
// Used under the terms of the MIT License (https://github.com/pose/webcrypto-jwt/blob/master/LICENSE.md)
|
|
5
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
6
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
7
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
8
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
9
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
10
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
11
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
12
|
+
});
|
|
13
|
+
};
|
|
14
|
+
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
15
|
+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
|
16
|
+
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
17
|
+
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
18
|
+
function step(op) {
|
|
19
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
20
|
+
while (_) try {
|
|
21
|
+
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
22
|
+
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
23
|
+
switch (op[0]) {
|
|
24
|
+
case 0: case 1: t = op; break;
|
|
25
|
+
case 4: _.label++; return { value: op[1], done: false };
|
|
26
|
+
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
27
|
+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
28
|
+
default:
|
|
29
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
30
|
+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
31
|
+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
32
|
+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
33
|
+
if (t[2]) _.ops.pop();
|
|
34
|
+
_.trys.pop(); continue;
|
|
35
|
+
}
|
|
36
|
+
op = body.call(thisArg, _);
|
|
37
|
+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
38
|
+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
42
|
+
exports.WebCryptoJWT = void 0;
|
|
43
|
+
var base64url_1 = require("./base64url");
|
|
44
|
+
var utils_1 = require("./utils");
|
|
45
|
+
var common_1 = require("../common");
|
|
46
|
+
var ALGORITHMS = {
|
|
47
|
+
none: {},
|
|
48
|
+
HS256: {
|
|
49
|
+
importKey: {
|
|
50
|
+
name: 'HMAC',
|
|
51
|
+
hash: 'SHA-256'
|
|
52
|
+
},
|
|
53
|
+
operation: {
|
|
54
|
+
name: 'HMAC',
|
|
55
|
+
hash: 'SHA-256'
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
HS384: {
|
|
59
|
+
importKey: {
|
|
60
|
+
name: 'HMAC',
|
|
61
|
+
hash: 'SHA-384'
|
|
62
|
+
},
|
|
63
|
+
operation: {
|
|
64
|
+
name: 'HMAC',
|
|
65
|
+
hash: 'SHA-384'
|
|
66
|
+
}
|
|
67
|
+
},
|
|
68
|
+
HS512: {
|
|
69
|
+
importKey: {
|
|
70
|
+
name: 'HMAC',
|
|
71
|
+
hash: 'SHA-512'
|
|
72
|
+
},
|
|
73
|
+
operation: {
|
|
74
|
+
name: 'HMAC',
|
|
75
|
+
hash: 'SHA-512'
|
|
76
|
+
}
|
|
77
|
+
},
|
|
78
|
+
RS256: {
|
|
79
|
+
importKey: {
|
|
80
|
+
name: 'RSASSA-PKCS1-v1_5',
|
|
81
|
+
hash: 'SHA-256'
|
|
82
|
+
},
|
|
83
|
+
operation: {
|
|
84
|
+
name: 'RSASSA-PKCS1-v1_5',
|
|
85
|
+
hash: 'SHA-256'
|
|
86
|
+
}
|
|
87
|
+
},
|
|
88
|
+
RS512: {
|
|
89
|
+
importKey: {
|
|
90
|
+
name: 'RSASSA-PKCS1-v1_5',
|
|
91
|
+
hash: 'SHA-512'
|
|
92
|
+
},
|
|
93
|
+
operation: {
|
|
94
|
+
name: 'RSASSA-PKCS1-v1_5',
|
|
95
|
+
hash: 'SHA-512'
|
|
96
|
+
}
|
|
97
|
+
},
|
|
98
|
+
ES256: {
|
|
99
|
+
importKey: {
|
|
100
|
+
name: 'ECDSA',
|
|
101
|
+
namedCurve: 'P-256'
|
|
102
|
+
},
|
|
103
|
+
operation: {
|
|
104
|
+
name: 'ECDSA',
|
|
105
|
+
namedCurve: 'P-256',
|
|
106
|
+
hash: 'SHA-256'
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
};
|
|
110
|
+
var WebCryptoJWT = /** @class */ (function () {
|
|
111
|
+
function WebCryptoJWT(subtleCrypto) {
|
|
112
|
+
this.subtleCrypto = subtleCrypto;
|
|
113
|
+
if (!subtleCrypto)
|
|
114
|
+
this.findSubtleCrypto();
|
|
115
|
+
}
|
|
116
|
+
WebCryptoJWT.prototype.decodeUntrusted = function (token) {
|
|
117
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
118
|
+
var decodedToken;
|
|
119
|
+
return __generator(this, function (_a) {
|
|
120
|
+
decodedToken = this._decode(token);
|
|
121
|
+
return [2 /*return*/, { claims: decodedToken.payload, string: token }];
|
|
122
|
+
});
|
|
123
|
+
});
|
|
124
|
+
};
|
|
125
|
+
WebCryptoJWT.prototype.findSubtleCrypto = function () {
|
|
126
|
+
if ('crypto' in window)
|
|
127
|
+
this.subtleCrypto = crypto.subtle || crypto['webkitSubtle'];
|
|
128
|
+
if (!this.subtleCrypto && 'msCrypto' in window)
|
|
129
|
+
this.subtleCrypto = window['msCrypto'].Subtle;
|
|
130
|
+
};
|
|
131
|
+
WebCryptoJWT.prototype.encode = function (payload, options) {
|
|
132
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
133
|
+
var _a;
|
|
134
|
+
return __generator(this, function (_b) {
|
|
135
|
+
switch (_b.label) {
|
|
136
|
+
case 0:
|
|
137
|
+
_a = {};
|
|
138
|
+
return [4 /*yield*/, this._sign(payload, options.secretOrKey, this.algorithmOf(options))];
|
|
139
|
+
case 1: return [2 /*return*/, (_a.string = _b.sent(),
|
|
140
|
+
_a.claims = payload,
|
|
141
|
+
_a)];
|
|
142
|
+
}
|
|
143
|
+
});
|
|
144
|
+
});
|
|
145
|
+
};
|
|
146
|
+
WebCryptoJWT.prototype.validate = function (string, options) {
|
|
147
|
+
var _a;
|
|
148
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
149
|
+
var decodedToken, algorithm, secretOrKey, claims, _b;
|
|
150
|
+
return __generator(this, function (_c) {
|
|
151
|
+
switch (_c.label) {
|
|
152
|
+
case 0:
|
|
153
|
+
decodedToken = this._decode(string);
|
|
154
|
+
algorithm = this.algorithmOf(options);
|
|
155
|
+
secretOrKey = options.secretOrKey;
|
|
156
|
+
claims = decodedToken.payload;
|
|
157
|
+
// Signature must match
|
|
158
|
+
if (decodedToken.header.alg !== algorithm)
|
|
159
|
+
throw new Error("Cannot validate JWT '" + string + "': Token has incorrect algorithm");
|
|
160
|
+
_b = algorithm !== 'none';
|
|
161
|
+
if (!_b) return [3 /*break*/, 2];
|
|
162
|
+
return [4 /*yield*/, this._verify(decodedToken, secretOrKey, algorithm)];
|
|
163
|
+
case 1:
|
|
164
|
+
_b = !(_c.sent());
|
|
165
|
+
_c.label = 2;
|
|
166
|
+
case 2:
|
|
167
|
+
if (_b)
|
|
168
|
+
throw new Error("Cannot validate JWT '" + string + "': Invalid signature");
|
|
169
|
+
// Algorithm must match
|
|
170
|
+
// Expiration
|
|
171
|
+
try {
|
|
172
|
+
common_1.validateExpiry(claims.exp, options.now, (_a = options.validate) === null || _a === void 0 ? void 0 : _a.exp);
|
|
173
|
+
}
|
|
174
|
+
catch (e) {
|
|
175
|
+
throw new Error("Cannot validate JWT '" + string + "': " + e.message);
|
|
176
|
+
}
|
|
177
|
+
return [2 /*return*/, {
|
|
178
|
+
string: string,
|
|
179
|
+
claims: decodedToken.payload
|
|
180
|
+
}];
|
|
181
|
+
}
|
|
182
|
+
});
|
|
183
|
+
});
|
|
184
|
+
};
|
|
185
|
+
WebCryptoJWT.prototype.algorithmOf = function (options) {
|
|
186
|
+
return options.algorithm || 'HS256';
|
|
187
|
+
};
|
|
188
|
+
WebCryptoJWT.prototype.str2ab = function (str) {
|
|
189
|
+
var buf = new ArrayBuffer(str.length);
|
|
190
|
+
var bufView = new Uint8Array(buf);
|
|
191
|
+
for (var i = 0, strLen = str.length; i < strLen; i++) {
|
|
192
|
+
bufView[i] = str.charCodeAt(i);
|
|
193
|
+
}
|
|
194
|
+
return buf;
|
|
195
|
+
};
|
|
196
|
+
/**
|
|
197
|
+
* Adapted from https://chromium.googlesource.com/chromium/blink/+/master/LayoutTests/crypto/subtle/hmac/sign-verify.html
|
|
198
|
+
*
|
|
199
|
+
* @param token
|
|
200
|
+
* @param secret
|
|
201
|
+
* @param alg
|
|
202
|
+
*/
|
|
203
|
+
WebCryptoJWT.prototype._verify = function (token, secret, alg) {
|
|
204
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
205
|
+
var importAlgorithm, keyFormat, secretBuf, encoder, key, e_1, identifier, partialToken, signaturePart, messageAsUint8Array, signatureAsUint8Array, e_2;
|
|
206
|
+
return __generator(this, function (_a) {
|
|
207
|
+
switch (_a.label) {
|
|
208
|
+
case 0:
|
|
209
|
+
if (alg === 'none')
|
|
210
|
+
return [2 /*return*/, true];
|
|
211
|
+
importAlgorithm = ALGORITHMS[alg];
|
|
212
|
+
if (!importAlgorithm)
|
|
213
|
+
throw new Error("Algorithm " + alg + " is not supported");
|
|
214
|
+
encoder = new TextEncoder();
|
|
215
|
+
// TODO Test utf8ToUint8Array function
|
|
216
|
+
if (secret.includes('-----BEGIN PUBLIC KEY-----')) {
|
|
217
|
+
secretBuf = this.str2ab(atob(secret
|
|
218
|
+
.replace(/^-----BEGIN PUBLIC KEY-----\n/, '')
|
|
219
|
+
.replace(/\n-----END PUBLIC KEY-----/, '')
|
|
220
|
+
.replace(/\n/g, '')));
|
|
221
|
+
keyFormat = 'spki';
|
|
222
|
+
}
|
|
223
|
+
else if (secret.includes('-----BEGIN RSA PUBLIC KEY-----')) {
|
|
224
|
+
throw new Error("PKCS#1 keys are not supported. "
|
|
225
|
+
+ "Please convert the key to PKCS#8 instead: "
|
|
226
|
+
+ "openssl pkcs8 -topk8 -inform PEM -outform PEM -nocrypt -in pkcs1.key -out pkcs8.key");
|
|
227
|
+
}
|
|
228
|
+
else {
|
|
229
|
+
secretBuf = encoder.encode(secret);
|
|
230
|
+
keyFormat = 'raw';
|
|
231
|
+
}
|
|
232
|
+
if (!this.subtleCrypto)
|
|
233
|
+
throw new Error("Not supported: No Subtle Crypto support");
|
|
234
|
+
_a.label = 1;
|
|
235
|
+
case 1:
|
|
236
|
+
_a.trys.push([1, 3, , 4]);
|
|
237
|
+
return [4 /*yield*/, this.subtleCrypto.importKey(keyFormat, secretBuf, importAlgorithm.importKey, false, ['verify'])];
|
|
238
|
+
case 2:
|
|
239
|
+
key = _a.sent();
|
|
240
|
+
return [3 /*break*/, 4];
|
|
241
|
+
case 3:
|
|
242
|
+
e_1 = _a.sent();
|
|
243
|
+
identifier = "jwtUncaughtError" + Math.floor(10000 + Math.random() * 10000);
|
|
244
|
+
console.error("JWT.verify(): Caught error while importing " + alg + " key: format=" + keyFormat + ", importAlgorithm: " + JSON.stringify(importAlgorithm.importKey) + ".");
|
|
245
|
+
console.error(e_1);
|
|
246
|
+
if (typeof window !== 'undefined') {
|
|
247
|
+
window[identifier] = e_1;
|
|
248
|
+
console.error("To aid in debugging, this error was saved to " + identifier);
|
|
249
|
+
}
|
|
250
|
+
throw e_1;
|
|
251
|
+
case 4:
|
|
252
|
+
partialToken = token.encodedHeader + "." + token.encodedPayload;
|
|
253
|
+
signaturePart = token.signature;
|
|
254
|
+
messageAsUint8Array = encoder.encode(partialToken);
|
|
255
|
+
signatureAsUint8Array = base64url_1.Base64URL.parse(signaturePart);
|
|
256
|
+
if (!this.subtleCrypto)
|
|
257
|
+
throw new Error("Not supported: No Subtle Crypto support");
|
|
258
|
+
_a.label = 5;
|
|
259
|
+
case 5:
|
|
260
|
+
_a.trys.push([5, 7, , 8]);
|
|
261
|
+
return [4 /*yield*/, this.subtleCrypto.verify(importAlgorithm.operation, key, signatureAsUint8Array, messageAsUint8Array)];
|
|
262
|
+
case 6: return [2 /*return*/, _a.sent()];
|
|
263
|
+
case 7:
|
|
264
|
+
e_2 = _a.sent();
|
|
265
|
+
console.error("JWT.verify(): Caught error while verifying token:");
|
|
266
|
+
console.error(e_2);
|
|
267
|
+
throw e_2;
|
|
268
|
+
case 8: return [2 /*return*/];
|
|
269
|
+
}
|
|
270
|
+
});
|
|
271
|
+
});
|
|
272
|
+
};
|
|
273
|
+
;
|
|
274
|
+
WebCryptoJWT.prototype._sign = function (payload, secret, alg) {
|
|
275
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
276
|
+
var importAlgorithm, payloadAsJSON, header, headerAsJSON, partialToken, keyFormat, encoder, secretBuf, key, e_3, messageAsUint8Array, signature, e_4, signatureAsBase64, token;
|
|
277
|
+
return __generator(this, function (_a) {
|
|
278
|
+
switch (_a.label) {
|
|
279
|
+
case 0:
|
|
280
|
+
importAlgorithm = ALGORITHMS[alg];
|
|
281
|
+
if (!importAlgorithm)
|
|
282
|
+
throw new Error("Algorithm '" + alg + "' is not supported");
|
|
283
|
+
payloadAsJSON = JSON.stringify(payload);
|
|
284
|
+
header = { alg: alg, typ: 'JWT' };
|
|
285
|
+
headerAsJSON = JSON.stringify(header);
|
|
286
|
+
partialToken = base64url_1.Base64URL.stringify(utils_1.Utils.utf8ToUint8Array(headerAsJSON)) + '.' +
|
|
287
|
+
base64url_1.Base64URL.stringify(utils_1.Utils.utf8ToUint8Array(payloadAsJSON));
|
|
288
|
+
if (alg === 'none')
|
|
289
|
+
return [2 /*return*/, partialToken + "."];
|
|
290
|
+
keyFormat = 'raw';
|
|
291
|
+
encoder = new TextEncoder();
|
|
292
|
+
// TODO Test utf8ToUint8Array function
|
|
293
|
+
if (secret.includes('-----BEGIN RSA PRIVATE KEY-----')) {
|
|
294
|
+
throw new Error("PKCS#1 keys are not supported. Please convert the key to PKCS#8 instead: openssl pkcs8 -topk8 -inform PEM -outform PEM -nocrypt -in pkcs1.key -out pkcs8.key");
|
|
295
|
+
}
|
|
296
|
+
else if (secret.includes('-----BEGIN PRIVATE KEY-----')) {
|
|
297
|
+
secretBuf = this.str2ab(atob(secret
|
|
298
|
+
.replace(/^-----BEGIN PRIVATE KEY-----\n/, '')
|
|
299
|
+
.replace(/\n-----END PRIVATE KEY-----/, '')
|
|
300
|
+
.replace(/\n/g, '')));
|
|
301
|
+
keyFormat = 'pkcs8';
|
|
302
|
+
}
|
|
303
|
+
else {
|
|
304
|
+
secretBuf = encoder.encode(secret);
|
|
305
|
+
}
|
|
306
|
+
if (!this.subtleCrypto)
|
|
307
|
+
throw new Error("Not supported: No Subtle Crypto support");
|
|
308
|
+
_a.label = 1;
|
|
309
|
+
case 1:
|
|
310
|
+
_a.trys.push([1, 3, , 4]);
|
|
311
|
+
return [4 /*yield*/, this.subtleCrypto.importKey(keyFormat, secretBuf, importAlgorithm.importKey, false, ['sign'])];
|
|
312
|
+
case 2:
|
|
313
|
+
key = _a.sent();
|
|
314
|
+
return [3 /*break*/, 4];
|
|
315
|
+
case 3:
|
|
316
|
+
e_3 = _a.sent();
|
|
317
|
+
console.error("JWT.sign(): Caught error while importing " + alg + " key: format=" + keyFormat + ", importAlgorithm: " + JSON.stringify(importAlgorithm.importKey));
|
|
318
|
+
console.error(e_3);
|
|
319
|
+
throw e_3;
|
|
320
|
+
case 4:
|
|
321
|
+
messageAsUint8Array = utils_1.Utils.utf8ToUint8Array(partialToken);
|
|
322
|
+
if (!this.subtleCrypto)
|
|
323
|
+
throw new Error("Not supported: No Subtle Crypto support");
|
|
324
|
+
_a.label = 5;
|
|
325
|
+
case 5:
|
|
326
|
+
_a.trys.push([5, 7, , 8]);
|
|
327
|
+
return [4 /*yield*/, this.subtleCrypto.sign(importAlgorithm.operation, key, messageAsUint8Array)];
|
|
328
|
+
case 6:
|
|
329
|
+
signature = _a.sent();
|
|
330
|
+
return [3 /*break*/, 8];
|
|
331
|
+
case 7:
|
|
332
|
+
e_4 = _a.sent();
|
|
333
|
+
console.error("JWT.sign(): Caught error while signing token:");
|
|
334
|
+
console.error(e_4);
|
|
335
|
+
throw e_4;
|
|
336
|
+
case 8:
|
|
337
|
+
signatureAsBase64 = base64url_1.Base64URL.stringify(new Uint8Array(signature));
|
|
338
|
+
token = partialToken + "." + signatureAsBase64;
|
|
339
|
+
return [2 /*return*/, token];
|
|
340
|
+
}
|
|
341
|
+
});
|
|
342
|
+
});
|
|
343
|
+
};
|
|
344
|
+
;
|
|
345
|
+
WebCryptoJWT.prototype._decode = function (token) {
|
|
346
|
+
var parts = token.split('.');
|
|
347
|
+
if (parts.length !== 3)
|
|
348
|
+
throw new Error("Invalid token '" + token + "': must have 3 parts separated by '.'");
|
|
349
|
+
return {
|
|
350
|
+
encodedHeader: parts[0],
|
|
351
|
+
encodedPayload: parts[1],
|
|
352
|
+
signature: parts[2],
|
|
353
|
+
header: JSON.parse(this._decodeBase64URL(parts[0])),
|
|
354
|
+
payload: JSON.parse(this._decodeBase64URL(parts[1])),
|
|
355
|
+
};
|
|
356
|
+
};
|
|
357
|
+
;
|
|
358
|
+
WebCryptoJWT.prototype._decodeBase64URL = function (string) {
|
|
359
|
+
string = string.replace(/-/g, '+').replace(/_/g, '/');
|
|
360
|
+
switch (string.length % 4) {
|
|
361
|
+
case 0:
|
|
362
|
+
break;
|
|
363
|
+
case 2:
|
|
364
|
+
string += '==';
|
|
365
|
+
break;
|
|
366
|
+
case 3:
|
|
367
|
+
string += '=';
|
|
368
|
+
break;
|
|
369
|
+
default:
|
|
370
|
+
throw new Error("Illegal Base64URL string '" + string + "'");
|
|
371
|
+
}
|
|
372
|
+
// TODO Use shim or document incompatible browsers
|
|
373
|
+
return decodeURIComponent(escape(atob(string)));
|
|
374
|
+
};
|
|
375
|
+
return WebCryptoJWT;
|
|
376
|
+
}());
|
|
377
|
+
exports.WebCryptoJWT = WebCryptoJWT;
|
|
378
|
+
//# sourceMappingURL=webcrypto-jwt.js.map
|