jose 2.0.1 → 2.0.5
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/CHANGELOG.md +28 -0
- package/README.md +32 -16
- package/lib/help/base64url.js +9 -12
- package/lib/help/key_object.js +0 -2
- package/lib/help/key_utils.js +0 -2
- package/lib/help/rsa_primes.js +1 -3
- package/lib/index.mjs +9 -0
- package/lib/jwa/aes_cbc_hmac_sha2.js +5 -1
- package/lib/jwk/key/base.js +41 -31
- package/lib/jwks/keystore.js +10 -7
- package/lib/jwt/index.js +1 -0
- package/package.json +9 -11
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,34 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
|
4
4
|
|
|
5
|
+
## [2.0.5](https://github.com/panva/jose/compare/v2.0.4...v2.0.5) (2021-04-09)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
### Bug Fixes
|
|
9
|
+
|
|
10
|
+
* defer AES CBC w/ HMAC decryption after tag verification passes ([812e03f](https://github.com/panva/jose/commit/812e03fcf4963791ffd9a46417beea5a7a74d995))
|
|
11
|
+
|
|
12
|
+
## [2.0.4](https://github.com/panva/jose/compare/v2.0.3...v2.0.4) (2021-01-18)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
### Performance
|
|
16
|
+
|
|
17
|
+
* improve base64url encoding when available in Node.js ([d5af559](https://github.com/panva/jose/commit/d5af559a94f51ee82951e1def5c5c5749dfa290a))
|
|
18
|
+
|
|
19
|
+
## [2.0.3](https://github.com/panva/jose/compare/v2.0.2...v2.0.3) (2020-10-29)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
### Bug Fixes
|
|
23
|
+
|
|
24
|
+
* allow stubbing of the JWT.decode function ([6c3b92f](https://github.com/panva/jose/commit/6c3b92f4394a5d7092d7336922eda61e311e6f8c))
|
|
25
|
+
|
|
26
|
+
## [2.0.2](https://github.com/panva/jose/compare/v2.0.1...v2.0.2) (2020-09-14)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
### Bug Fixes
|
|
30
|
+
|
|
31
|
+
* **esm:** include esm files in the published package ([1956746](https://github.com/panva/jose/commit/1956746df6542c00bc33af750f93394805b5d603))
|
|
32
|
+
|
|
5
33
|
## [2.0.1](https://github.com/panva/jose/compare/v2.0.0...v2.0.1) (2020-09-10)
|
|
6
34
|
|
|
7
35
|
|
package/README.md
CHANGED
|
@@ -4,6 +4,20 @@
|
|
|
4
4
|
|
|
5
5
|
<p align="center"><img src="/img/demo.gif?raw=true"/></p>
|
|
6
6
|
|
|
7
|
+
## New major version is available
|
|
8
|
+
|
|
9
|
+
`v2.x` continues being supported. It will continue receiving
|
|
10
|
+
bug fixes until 2022-04-30. It will not be receiving any new
|
|
11
|
+
features.
|
|
12
|
+
|
|
13
|
+
`v3.x` is [available](https://github.com/panva/jose) with
|
|
14
|
+
|
|
15
|
+
- Revised API
|
|
16
|
+
- No dependencies
|
|
17
|
+
- Browser support
|
|
18
|
+
- Promise-based API
|
|
19
|
+
- experimental (non-blocking 🎉) Node.js libuv thread pool based runtime
|
|
20
|
+
|
|
7
21
|
## Implemented specs & features
|
|
8
22
|
|
|
9
23
|
The following specifications are implemented by `jose`
|
|
@@ -28,10 +42,6 @@ Available JWT validation profiles
|
|
|
28
42
|
- (draft 04) OIDC Logout Token - [OpenID Connect Back-Channel Logout 1.0][spec-oidc-logout_token]
|
|
29
43
|
- (draft 06) OAuth 2.0 JWT Access Tokens - [JWT Profile for OAuth 2.0 Access Tokens][draft-ietf-oauth-access-token-jwt]
|
|
30
44
|
|
|
31
|
-
## Sponsor
|
|
32
|
-
|
|
33
|
-
[<img width="65" height="65" align="left" src="https://avatars.githubusercontent.com/u/2824157?s=75&v=4" alt="auth0-logo">][sponsor-auth0] If you want to quickly add secure token-based authentication to Node.js projects, feel free to check Auth0’s free plan at [auth0.com/overview][sponsor-auth0].<br><br>
|
|
34
|
-
|
|
35
45
|
## Support
|
|
36
46
|
|
|
37
47
|
If you or your business use `jose`, please consider becoming a [sponsor][support-sponsor] so I can continue maintaining it and adding new features carefree.
|
|
@@ -53,7 +63,7 @@ is also supported.
|
|
|
53
63
|
Installing `jose`
|
|
54
64
|
|
|
55
65
|
```console
|
|
56
|
-
npm install jose
|
|
66
|
+
npm install jose@2
|
|
57
67
|
```
|
|
58
68
|
|
|
59
69
|
Usage
|
|
@@ -307,9 +317,9 @@ jose.JWE.decrypt(
|
|
|
307
317
|
|
|
308
318
|
| JWT profile validation | Supported | Stable profile | |
|
|
309
319
|
| -- | -- | -- | -- |
|
|
310
|
-
| JWT Access Tokens - [JWT Profile for OAuth 2.0 Access Tokens][draft-ietf-oauth-access-token-jwt] | ✓ | ✕<sup>5</sup> | see [`JWT.AccessToken.verify`](/docs/README.md#jwtaccesstokenverifytoken-keyorstore-options) |
|
|
311
|
-
| ID Token - [OpenID Connect Core 1.0][spec-oidc-id_token] | ✓ | ✓ | see [`JWT.IdToken.verify`](/docs/README.md#jwtidtokenverifytoken-keyorstore-options) |
|
|
312
|
-
| Logout Token - [OpenID Connect Back-Channel Logout 1.0][spec-oidc-logout_token] | ✓ | ✕<sup>5</sup> | see [`JWT.LogoutToken.verify`](/docs/README.md#jwtlogouttokenverifytoken-keyorstore-options) |
|
|
320
|
+
| JWT Access Tokens - [JWT Profile for OAuth 2.0 Access Tokens][draft-ietf-oauth-access-token-jwt] | ✓ | ✕<sup>5</sup> | see [`JWT.AccessToken.verify`]([/docs/README.md](https://github.com/panva/jose/blob/v2.x/docs/README.md)#jwtaccesstokenverifytoken-keyorstore-options) |
|
|
321
|
+
| ID Token - [OpenID Connect Core 1.0][spec-oidc-id_token] | ✓ | ✓ | see [`JWT.IdToken.verify`]([/docs/README.md](https://github.com/panva/jose/blob/v2.x/docs/README.md)#jwtidtokenverifytoken-keyorstore-options) |
|
|
322
|
+
| Logout Token - [OpenID Connect Back-Channel Logout 1.0][spec-oidc-logout_token] | ✓ | ✕<sup>5</sup> | see [`JWT.LogoutToken.verify`]([/docs/README.md](https://github.com/panva/jose/blob/v2.x/docs/README.md)#jwtlogouttokenverifytoken-keyorstore-options) |
|
|
313
323
|
| JARM - [JWT Secured Authorization Response Mode for OAuth 2.0][draft-jarm] | ◯ |||
|
|
314
324
|
| [JWT Response for OAuth Token Introspection][draft-jwtintrospection] | ◯ |||
|
|
315
325
|
| [OAuth 2.0 DPoP][draft-dpop] | ◯ |||
|
|
@@ -331,6 +341,13 @@ attention to changelog and the drafts themselves.
|
|
|
331
341
|
|
|
332
342
|
## FAQ
|
|
333
343
|
|
|
344
|
+
#### Supported Versions
|
|
345
|
+
|
|
346
|
+
| Version | Bug Fixes 🐞 | New Features ⭐ |
|
|
347
|
+
| ------- | --------- | -------- |
|
|
348
|
+
| [3.x.x](https://github.com/panva/jose) | ✅ | ✅ |
|
|
349
|
+
| [2.x.x](https://github.com/panva/jose/tree/v2.x) | ✅ until 2022-04-30 | ❌ |
|
|
350
|
+
|
|
334
351
|
#### Semver?
|
|
335
352
|
|
|
336
353
|
**Yes.** Everything that's either exported in the TypeScript definitions file or
|
|
@@ -381,13 +398,13 @@ in terms of performance and API (not having well defined errors).
|
|
|
381
398
|
|
|
382
399
|
+ this was an amazing opportunity to learn JOSE as a whole
|
|
383
400
|
|
|
384
|
-
[documentation-jwe]: /docs/README.md#jwe-json-web-encryption
|
|
385
|
-
[documentation-jwk]: /docs/README.md#jwk-json-web-key
|
|
386
|
-
[documentation-jwks]: /docs/README.md#jwks-json-web-key-set
|
|
387
|
-
[documentation-jws]: /docs/README.md#jws-json-web-signature
|
|
388
|
-
[documentation-jwt]: /docs/README.md#jwt-json-web-token
|
|
389
|
-
[documentation-none]: /docs/README.md#jwknone
|
|
390
|
-
[documentation]: /docs/README.md
|
|
401
|
+
[documentation-jwe]: https://github.com/panva/jose/blob/v2.x/docs/README.md#jwe-json-web-encryption
|
|
402
|
+
[documentation-jwk]: https://github.com/panva/jose/blob/v2.x/docs/README.md#jwk-json-web-key
|
|
403
|
+
[documentation-jwks]: https://github.com/panva/jose/blob/v2.x/docs/README.md#jwks-json-web-key-set
|
|
404
|
+
[documentation-jws]: https://github.com/panva/jose/blob/v2.x/docs/README.md#jws-json-web-signature
|
|
405
|
+
[documentation-jwt]: https://github.com/panva/jose/blob/v2.x/docs/README.md#jwt-json-web-token
|
|
406
|
+
[documentation-none]: https://github.com/panva/jose/blob/v2.x/docs/README.md#jwknone
|
|
407
|
+
[documentation]: https://github.com/panva/jose/blob/v2.x/docs/README.md
|
|
391
408
|
[node-jose]: https://github.com/cisco/node-jose
|
|
392
409
|
[spec-b64]: https://tools.ietf.org/html/rfc7797
|
|
393
410
|
[spec-cookbook]: https://tools.ietf.org/html/rfc7520
|
|
@@ -407,4 +424,3 @@ in terms of performance and API (not having well defined errors).
|
|
|
407
424
|
[spec-oidc-logout_token]: https://openid.net/specs/openid-connect-backchannel-1_0-04.html#LogoutToken
|
|
408
425
|
[oidc-token-hash]: https://www.npmjs.com/package/oidc-token-hash
|
|
409
426
|
[support-sponsor]: https://github.com/sponsors/panva
|
|
410
|
-
[sponsor-auth0]: https://auth0.com/overview?utm_source=GHsponsor&utm_medium=GHsponsor&utm_campaign=panva-jose&utm_content=auth
|
package/lib/help/base64url.js
CHANGED
|
@@ -1,15 +1,12 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
const
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
const encodeBuffer = (buf) => {
|
|
12
|
-
return fromBase64(buf.toString('base64'))
|
|
1
|
+
let encode
|
|
2
|
+
let encodeBuffer
|
|
3
|
+
if (Buffer.isEncoding('base64url')) {
|
|
4
|
+
encode = (input, encoding = 'utf8') => Buffer.from(input, encoding).toString('base64url')
|
|
5
|
+
encodeBuffer = (buf) => buf.toString('base64url')
|
|
6
|
+
} else {
|
|
7
|
+
const fromBase64 = (base64) => base64.replace(/=/g, '').replace(/\+/g, '-').replace(/\//g, '_')
|
|
8
|
+
encode = (input, encoding = 'utf8') => fromBase64(Buffer.from(input, encoding).toString('base64'))
|
|
9
|
+
encodeBuffer = (buf) => fromBase64(buf.toString('base64'))
|
|
13
10
|
}
|
|
14
11
|
|
|
15
12
|
const decodeToBuffer = (input) => {
|
package/lib/help/key_object.js
CHANGED
package/lib/help/key_utils.js
CHANGED
package/lib/help/rsa_primes.js
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
/* global BigInt */
|
|
2
|
-
|
|
3
1
|
const { randomBytes } = require('crypto')
|
|
4
2
|
|
|
5
3
|
const base64url = require('./base64url')
|
|
@@ -67,7 +65,7 @@ const modPow = (a, b, n) => {
|
|
|
67
65
|
let result = ONE
|
|
68
66
|
let x = a
|
|
69
67
|
while (b > 0) {
|
|
70
|
-
|
|
68
|
+
const leastSignificantBit = b % TWO
|
|
71
69
|
b = b / TWO
|
|
72
70
|
if (leastSignificantBit === ONE) {
|
|
73
71
|
result = result * x
|
package/lib/index.mjs
ADDED
|
@@ -44,13 +44,17 @@ const decrypt = (size, sign, { [KEYOBJECT]: keyObject }, ciphertext, { iv, tag =
|
|
|
44
44
|
const expectedTag = sign({ [KEYOBJECT]: macKey }, macData, tag).slice(0, keySize)
|
|
45
45
|
const macCheckPassed = timingSafeEqual(tag, expectedTag)
|
|
46
46
|
|
|
47
|
+
if (!macCheckPassed) {
|
|
48
|
+
throw new JWEDecryptionFailed()
|
|
49
|
+
}
|
|
50
|
+
|
|
47
51
|
let cleartext
|
|
48
52
|
try {
|
|
49
53
|
const cipher = createDecipheriv(`aes-${size}-cbc`, encKey, iv)
|
|
50
54
|
cleartext = Buffer.concat([cipher.update(ciphertext), cipher.final()])
|
|
51
55
|
} catch (err) {}
|
|
52
56
|
|
|
53
|
-
if (!cleartext
|
|
57
|
+
if (!cleartext) {
|
|
54
58
|
throw new JWEDecryptionFailed()
|
|
55
59
|
}
|
|
56
60
|
|
package/lib/jwk/key/base.js
CHANGED
|
@@ -106,38 +106,48 @@ class Key {
|
|
|
106
106
|
},
|
|
107
107
|
kid: {
|
|
108
108
|
enumerable: true,
|
|
109
|
-
...(kid
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
109
|
+
...(kid
|
|
110
|
+
? { value: kid }
|
|
111
|
+
: {
|
|
112
|
+
get () {
|
|
113
|
+
Object.defineProperty(this, 'kid', { value: this.thumbprint, configurable: false })
|
|
114
|
+
return this.kid
|
|
115
|
+
},
|
|
116
|
+
configurable: true
|
|
117
|
+
})
|
|
116
118
|
},
|
|
117
|
-
...(x5c
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
119
|
+
...(x5c
|
|
120
|
+
? {
|
|
121
|
+
x5t: {
|
|
122
|
+
enumerable: true,
|
|
123
|
+
...(x5t
|
|
124
|
+
? { value: x5t }
|
|
125
|
+
: {
|
|
126
|
+
get () {
|
|
127
|
+
Object.defineProperty(this, 'x5t', { value: thumbprint.x5t(this.x5c[0]), configurable: false })
|
|
128
|
+
return this.x5t
|
|
129
|
+
},
|
|
130
|
+
configurable: true
|
|
131
|
+
})
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
: undefined),
|
|
135
|
+
...(x5c
|
|
136
|
+
? {
|
|
137
|
+
'x5t#S256': {
|
|
138
|
+
enumerable: true,
|
|
139
|
+
...(x5t256
|
|
140
|
+
? { value: x5t256 }
|
|
141
|
+
: {
|
|
142
|
+
get () {
|
|
143
|
+
Object.defineProperty(this, 'x5t#S256', { value: thumbprint['x5t#S256'](this.x5c[0]), configurable: false })
|
|
144
|
+
return this['x5t#S256']
|
|
145
|
+
},
|
|
146
|
+
configurable: true
|
|
147
|
+
})
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
: undefined),
|
|
141
151
|
thumbprint: {
|
|
142
152
|
get () {
|
|
143
153
|
Object.defineProperty(this, 'thumbprint', { value: thumbprint.kid(this[THUMBPRINT_MATERIAL]()), configurable: false })
|
package/lib/jwks/keystore.js
CHANGED
|
@@ -26,14 +26,16 @@ const keyscore = (key, { alg, use, ops }) => {
|
|
|
26
26
|
class KeyStore {
|
|
27
27
|
constructor (...keys) {
|
|
28
28
|
while (keys.some(Array.isArray)) {
|
|
29
|
-
keys = keys.flat
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
29
|
+
keys = keys.flat
|
|
30
|
+
? keys.flat()
|
|
31
|
+
: keys.reduce((acc, val) => {
|
|
32
|
+
if (Array.isArray(val)) {
|
|
33
|
+
return [...acc, ...val]
|
|
34
|
+
}
|
|
33
35
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
36
|
+
acc.push(val)
|
|
37
|
+
return acc
|
|
38
|
+
}, [])
|
|
37
39
|
}
|
|
38
40
|
if (keys.some(k => !isKey(k) || !k.kty)) {
|
|
39
41
|
throw new TypeError('all keys must be instances of a key instantiated by JWK.asKey')
|
|
@@ -171,6 +173,7 @@ function asKeyStore (jwks, { ignoreErrors = false, calculateMissingRSAPrimes = f
|
|
|
171
173
|
if (!ignoreErrors) {
|
|
172
174
|
throw err
|
|
173
175
|
}
|
|
176
|
+
return undefined
|
|
174
177
|
}
|
|
175
178
|
}).filter(Boolean)
|
|
176
179
|
|
package/lib/jwt/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "jose",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.5",
|
|
4
4
|
"description": "JSON Web Almost Everything - JWA, JWS, JWE, JWK, JWT, JWKS for Node.js with minimal dependencies",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"access token",
|
|
@@ -56,6 +56,7 @@
|
|
|
56
56
|
"types": "types/index.d.ts",
|
|
57
57
|
"files": [
|
|
58
58
|
"lib/**/*.js",
|
|
59
|
+
"lib/**/*.mjs",
|
|
59
60
|
"LICENSE_THIRD_PARTY",
|
|
60
61
|
"types/index.d.ts"
|
|
61
62
|
],
|
|
@@ -88,20 +89,16 @@
|
|
|
88
89
|
"@panva/asn1.js": "^1.0.0"
|
|
89
90
|
},
|
|
90
91
|
"devDependencies": {
|
|
91
|
-
"@commitlint/cli": "^
|
|
92
|
-
"@commitlint/config-conventional": "^
|
|
92
|
+
"@commitlint/cli": "^11.0.0",
|
|
93
|
+
"@commitlint/config-conventional": "^11.0.0",
|
|
93
94
|
"ava": "^2.4.0",
|
|
94
|
-
"
|
|
95
|
-
"
|
|
96
|
-
"
|
|
97
|
-
"standard": "^14.3.1"
|
|
95
|
+
"c8": "^7.3.5",
|
|
96
|
+
"husky": "^4.3.0",
|
|
97
|
+
"standard": "^16.0.0"
|
|
98
98
|
},
|
|
99
99
|
"engines": {
|
|
100
100
|
"node": ">=10.13.0 < 13 || >=13.7.0"
|
|
101
101
|
},
|
|
102
|
-
"standard": {
|
|
103
|
-
"parser": "babel-eslint"
|
|
104
|
-
},
|
|
105
102
|
"standard-version": {
|
|
106
103
|
"scripts": {
|
|
107
104
|
"postchangelog": "sed -i '' -e 's/### \\[/## [/g' CHANGELOG.md"
|
|
@@ -134,7 +131,8 @@
|
|
|
134
131
|
},
|
|
135
132
|
{
|
|
136
133
|
"type": "perf",
|
|
137
|
-
"
|
|
134
|
+
"section": "Performance",
|
|
135
|
+
"hidden": false
|
|
138
136
|
},
|
|
139
137
|
{
|
|
140
138
|
"type": "test",
|