jose 6.0.8 → 6.0.9
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/README.md +1 -1
- package/dist/types/index.d.ts +1 -2
- package/dist/types/jwe/compact/encrypt.d.ts +6 -2
- package/dist/types/jwe/flattened/encrypt.d.ts +6 -9
- package/dist/types/jwe/general/encrypt.d.ts +9 -9
- package/dist/types/jwks/remote.d.ts +10 -1
- package/dist/types/jws/compact/sign.d.ts +6 -2
- package/dist/types/jws/flattened/sign.d.ts +6 -4
- package/dist/types/jws/general/sign.d.ts +9 -6
- package/dist/types/jwt/encrypt.d.ts +15 -9
- package/dist/types/jwt/produce.d.ts +17 -101
- package/dist/types/jwt/sign.d.ts +15 -3
- package/dist/types/jwt/unsecured.d.ts +15 -2
- package/dist/types/types.d.ts +107 -0
- package/dist/types/util/errors.d.ts +15 -1
- package/dist/webapi/jwe/compact/encrypt.js +7 -7
- package/dist/webapi/jwe/flattened/encrypt.js +44 -44
- package/dist/webapi/jwe/general/encrypt.js +40 -40
- package/dist/webapi/jwks/local.js +11 -14
- package/dist/webapi/jwks/remote.js +52 -46
- package/dist/webapi/jws/compact/sign.js +4 -4
- package/dist/webapi/jws/flattened/sign.js +20 -20
- package/dist/webapi/jws/general/sign.js +13 -13
- package/dist/webapi/jwt/encrypt.js +69 -36
- package/dist/webapi/jwt/produce.js +57 -42
- package/dist/webapi/jwt/sign.js +40 -9
- package/dist/webapi/jwt/unsecured.js +34 -2
- package/package.json +1 -1
|
@@ -7,44 +7,44 @@ import checkKeyType from '../../lib/check_key_type.js';
|
|
|
7
7
|
import validateCrit from '../../lib/validate_crit.js';
|
|
8
8
|
import normalizeKey from '../../lib/normalize_key.js';
|
|
9
9
|
export class FlattenedSign {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
10
|
+
#payload;
|
|
11
|
+
#protectedHeader;
|
|
12
|
+
#unprotectedHeader;
|
|
13
13
|
constructor(payload) {
|
|
14
14
|
if (!(payload instanceof Uint8Array)) {
|
|
15
15
|
throw new TypeError('payload must be an instance of Uint8Array');
|
|
16
16
|
}
|
|
17
|
-
this
|
|
17
|
+
this.#payload = payload;
|
|
18
18
|
}
|
|
19
19
|
setProtectedHeader(protectedHeader) {
|
|
20
|
-
if (this
|
|
20
|
+
if (this.#protectedHeader) {
|
|
21
21
|
throw new TypeError('setProtectedHeader can only be called once');
|
|
22
22
|
}
|
|
23
|
-
this
|
|
23
|
+
this.#protectedHeader = protectedHeader;
|
|
24
24
|
return this;
|
|
25
25
|
}
|
|
26
26
|
setUnprotectedHeader(unprotectedHeader) {
|
|
27
|
-
if (this
|
|
27
|
+
if (this.#unprotectedHeader) {
|
|
28
28
|
throw new TypeError('setUnprotectedHeader can only be called once');
|
|
29
29
|
}
|
|
30
|
-
this
|
|
30
|
+
this.#unprotectedHeader = unprotectedHeader;
|
|
31
31
|
return this;
|
|
32
32
|
}
|
|
33
33
|
async sign(key, options) {
|
|
34
|
-
if (!this
|
|
34
|
+
if (!this.#protectedHeader && !this.#unprotectedHeader) {
|
|
35
35
|
throw new JWSInvalid('either setProtectedHeader or setUnprotectedHeader must be called before #sign()');
|
|
36
36
|
}
|
|
37
|
-
if (!isDisjoint(this
|
|
37
|
+
if (!isDisjoint(this.#protectedHeader, this.#unprotectedHeader)) {
|
|
38
38
|
throw new JWSInvalid('JWS Protected and JWS Unprotected Header Parameter names must be disjoint');
|
|
39
39
|
}
|
|
40
40
|
const joseHeader = {
|
|
41
|
-
...this
|
|
42
|
-
...this
|
|
41
|
+
...this.#protectedHeader,
|
|
42
|
+
...this.#unprotectedHeader,
|
|
43
43
|
};
|
|
44
|
-
const extensions = validateCrit(JWSInvalid, new Map([['b64', true]]), options?.crit, this
|
|
44
|
+
const extensions = validateCrit(JWSInvalid, new Map([['b64', true]]), options?.crit, this.#protectedHeader, joseHeader);
|
|
45
45
|
let b64 = true;
|
|
46
46
|
if (extensions.has('b64')) {
|
|
47
|
-
b64 = this.
|
|
47
|
+
b64 = this.#protectedHeader.b64;
|
|
48
48
|
if (typeof b64 !== 'boolean') {
|
|
49
49
|
throw new JWSInvalid('The "b64" (base64url-encode payload) Header Parameter must be a boolean');
|
|
50
50
|
}
|
|
@@ -54,13 +54,13 @@ export class FlattenedSign {
|
|
|
54
54
|
throw new JWSInvalid('JWS "alg" (Algorithm) Header Parameter missing or invalid');
|
|
55
55
|
}
|
|
56
56
|
checkKeyType(alg, key, 'sign');
|
|
57
|
-
let payload = this
|
|
57
|
+
let payload = this.#payload;
|
|
58
58
|
if (b64) {
|
|
59
59
|
payload = encoder.encode(b64u(payload));
|
|
60
60
|
}
|
|
61
61
|
let protectedHeader;
|
|
62
|
-
if (this
|
|
63
|
-
protectedHeader = encoder.encode(b64u(JSON.stringify(this
|
|
62
|
+
if (this.#protectedHeader) {
|
|
63
|
+
protectedHeader = encoder.encode(b64u(JSON.stringify(this.#protectedHeader)));
|
|
64
64
|
}
|
|
65
65
|
else {
|
|
66
66
|
protectedHeader = encoder.encode('');
|
|
@@ -75,10 +75,10 @@ export class FlattenedSign {
|
|
|
75
75
|
if (b64) {
|
|
76
76
|
jws.payload = decoder.decode(payload);
|
|
77
77
|
}
|
|
78
|
-
if (this
|
|
79
|
-
jws.header = this
|
|
78
|
+
if (this.#unprotectedHeader) {
|
|
79
|
+
jws.header = this.#unprotectedHeader;
|
|
80
80
|
}
|
|
81
|
-
if (this
|
|
81
|
+
if (this.#protectedHeader) {
|
|
82
82
|
jws.protected = decoder.decode(protectedHeader);
|
|
83
83
|
}
|
|
84
84
|
return jws;
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { FlattenedSign } from '../flattened/sign.js';
|
|
2
2
|
import { JWSInvalid } from '../../util/errors.js';
|
|
3
3
|
class IndividualSignature {
|
|
4
|
-
parent;
|
|
4
|
+
#parent;
|
|
5
5
|
protectedHeader;
|
|
6
6
|
unprotectedHeader;
|
|
7
7
|
options;
|
|
8
8
|
key;
|
|
9
9
|
constructor(sig, key, options) {
|
|
10
|
-
this
|
|
10
|
+
this.#parent = sig;
|
|
11
11
|
this.key = key;
|
|
12
12
|
this.options = options;
|
|
13
13
|
}
|
|
@@ -26,37 +26,37 @@ class IndividualSignature {
|
|
|
26
26
|
return this;
|
|
27
27
|
}
|
|
28
28
|
addSignature(...args) {
|
|
29
|
-
return this
|
|
29
|
+
return this.#parent.addSignature(...args);
|
|
30
30
|
}
|
|
31
31
|
sign(...args) {
|
|
32
|
-
return this
|
|
32
|
+
return this.#parent.sign(...args);
|
|
33
33
|
}
|
|
34
34
|
done() {
|
|
35
|
-
return this
|
|
35
|
+
return this.#parent;
|
|
36
36
|
}
|
|
37
37
|
}
|
|
38
38
|
export class GeneralSign {
|
|
39
|
-
|
|
40
|
-
|
|
39
|
+
#payload;
|
|
40
|
+
#signatures = [];
|
|
41
41
|
constructor(payload) {
|
|
42
|
-
this
|
|
42
|
+
this.#payload = payload;
|
|
43
43
|
}
|
|
44
44
|
addSignature(key, options) {
|
|
45
45
|
const signature = new IndividualSignature(this, key, options);
|
|
46
|
-
this.
|
|
46
|
+
this.#signatures.push(signature);
|
|
47
47
|
return signature;
|
|
48
48
|
}
|
|
49
49
|
async sign() {
|
|
50
|
-
if (!this.
|
|
50
|
+
if (!this.#signatures.length) {
|
|
51
51
|
throw new JWSInvalid('at least one signature must be added');
|
|
52
52
|
}
|
|
53
53
|
const jws = {
|
|
54
54
|
signatures: [],
|
|
55
55
|
payload: '',
|
|
56
56
|
};
|
|
57
|
-
for (let i = 0; i < this.
|
|
58
|
-
const signature = this
|
|
59
|
-
const flattened = new FlattenedSign(this
|
|
57
|
+
for (let i = 0; i < this.#signatures.length; i++) {
|
|
58
|
+
const signature = this.#signatures[i];
|
|
59
|
+
const flattened = new FlattenedSign(this.#payload);
|
|
60
60
|
flattened.setProtectedHeader(signature.protectedHeader);
|
|
61
61
|
flattened.setUnprotectedHeader(signature.unprotectedHeader);
|
|
62
62
|
const { payload, ...rest } = await flattened.sign(signature.key, signature.options);
|
|
@@ -1,74 +1,107 @@
|
|
|
1
1
|
import { CompactEncrypt } from '../jwe/compact/encrypt.js';
|
|
2
|
-
import { encoder } from '../lib/buffer_utils.js';
|
|
3
2
|
import { ProduceJWT } from './produce.js';
|
|
4
|
-
export class EncryptJWT
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
3
|
+
export class EncryptJWT {
|
|
4
|
+
#cek;
|
|
5
|
+
#iv;
|
|
6
|
+
#keyManagementParameters;
|
|
7
|
+
#protectedHeader;
|
|
8
|
+
#replicateIssuerAsHeader;
|
|
9
|
+
#replicateSubjectAsHeader;
|
|
10
|
+
#replicateAudienceAsHeader;
|
|
11
|
+
#jwt;
|
|
12
|
+
constructor(payload = {}) {
|
|
13
|
+
this.#jwt = new ProduceJWT(payload);
|
|
14
|
+
}
|
|
15
|
+
setIssuer(issuer) {
|
|
16
|
+
this.#jwt.iss = issuer;
|
|
17
|
+
return this;
|
|
18
|
+
}
|
|
19
|
+
setSubject(subject) {
|
|
20
|
+
this.#jwt.sub = subject;
|
|
21
|
+
return this;
|
|
22
|
+
}
|
|
23
|
+
setAudience(audience) {
|
|
24
|
+
this.#jwt.aud = audience;
|
|
25
|
+
return this;
|
|
26
|
+
}
|
|
27
|
+
setJti(jwtId) {
|
|
28
|
+
this.#jwt.jti = jwtId;
|
|
29
|
+
return this;
|
|
30
|
+
}
|
|
31
|
+
setNotBefore(input) {
|
|
32
|
+
this.#jwt.nbf = input;
|
|
33
|
+
return this;
|
|
34
|
+
}
|
|
35
|
+
setExpirationTime(input) {
|
|
36
|
+
this.#jwt.exp = input;
|
|
37
|
+
return this;
|
|
38
|
+
}
|
|
39
|
+
setIssuedAt(input) {
|
|
40
|
+
this.#jwt.iat = input;
|
|
41
|
+
return this;
|
|
42
|
+
}
|
|
12
43
|
setProtectedHeader(protectedHeader) {
|
|
13
|
-
if (this
|
|
44
|
+
if (this.#protectedHeader) {
|
|
14
45
|
throw new TypeError('setProtectedHeader can only be called once');
|
|
15
46
|
}
|
|
16
|
-
this
|
|
47
|
+
this.#protectedHeader = protectedHeader;
|
|
17
48
|
return this;
|
|
18
49
|
}
|
|
19
50
|
setKeyManagementParameters(parameters) {
|
|
20
|
-
if (this
|
|
51
|
+
if (this.#keyManagementParameters) {
|
|
21
52
|
throw new TypeError('setKeyManagementParameters can only be called once');
|
|
22
53
|
}
|
|
23
|
-
this
|
|
54
|
+
this.#keyManagementParameters = parameters;
|
|
24
55
|
return this;
|
|
25
56
|
}
|
|
26
57
|
setContentEncryptionKey(cek) {
|
|
27
|
-
if (this
|
|
58
|
+
if (this.#cek) {
|
|
28
59
|
throw new TypeError('setContentEncryptionKey can only be called once');
|
|
29
60
|
}
|
|
30
|
-
this
|
|
61
|
+
this.#cek = cek;
|
|
31
62
|
return this;
|
|
32
63
|
}
|
|
33
64
|
setInitializationVector(iv) {
|
|
34
|
-
if (this
|
|
65
|
+
if (this.#iv) {
|
|
35
66
|
throw new TypeError('setInitializationVector can only be called once');
|
|
36
67
|
}
|
|
37
|
-
this
|
|
68
|
+
this.#iv = iv;
|
|
38
69
|
return this;
|
|
39
70
|
}
|
|
40
71
|
replicateIssuerAsHeader() {
|
|
41
|
-
this
|
|
72
|
+
this.#replicateIssuerAsHeader = true;
|
|
42
73
|
return this;
|
|
43
74
|
}
|
|
44
75
|
replicateSubjectAsHeader() {
|
|
45
|
-
this
|
|
76
|
+
this.#replicateSubjectAsHeader = true;
|
|
46
77
|
return this;
|
|
47
78
|
}
|
|
48
79
|
replicateAudienceAsHeader() {
|
|
49
|
-
this
|
|
80
|
+
this.#replicateAudienceAsHeader = true;
|
|
50
81
|
return this;
|
|
51
82
|
}
|
|
52
83
|
async encrypt(key, options) {
|
|
53
|
-
const enc = new CompactEncrypt(
|
|
54
|
-
if (this
|
|
55
|
-
this
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
this
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
84
|
+
const enc = new CompactEncrypt(this.#jwt.data());
|
|
85
|
+
if (this.#protectedHeader &&
|
|
86
|
+
(this.#replicateIssuerAsHeader ||
|
|
87
|
+
this.#replicateSubjectAsHeader ||
|
|
88
|
+
this.#replicateAudienceAsHeader)) {
|
|
89
|
+
this.#protectedHeader = {
|
|
90
|
+
...this.#protectedHeader,
|
|
91
|
+
iss: this.#replicateIssuerAsHeader ? this.#jwt.iss : undefined,
|
|
92
|
+
sub: this.#replicateSubjectAsHeader ? this.#jwt.sub : undefined,
|
|
93
|
+
aud: this.#replicateAudienceAsHeader ? this.#jwt.aud : undefined,
|
|
94
|
+
};
|
|
62
95
|
}
|
|
63
|
-
enc.setProtectedHeader(this
|
|
64
|
-
if (this
|
|
65
|
-
enc.setInitializationVector(this
|
|
96
|
+
enc.setProtectedHeader(this.#protectedHeader);
|
|
97
|
+
if (this.#iv) {
|
|
98
|
+
enc.setInitializationVector(this.#iv);
|
|
66
99
|
}
|
|
67
|
-
if (this
|
|
68
|
-
enc.setContentEncryptionKey(this
|
|
100
|
+
if (this.#cek) {
|
|
101
|
+
enc.setContentEncryptionKey(this.#cek);
|
|
69
102
|
}
|
|
70
|
-
if (this
|
|
71
|
-
enc.setKeyManagementParameters(this
|
|
103
|
+
if (this.#keyManagementParameters) {
|
|
104
|
+
enc.setKeyManagementParameters(this.#keyManagementParameters);
|
|
72
105
|
}
|
|
73
106
|
return enc.encrypt(key, options);
|
|
74
107
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import epoch from '../lib/epoch.js';
|
|
2
|
-
import isObject from '../lib/is_object.js';
|
|
3
2
|
import secs from '../lib/secs.js';
|
|
3
|
+
import isObject from '../lib/is_object.js';
|
|
4
|
+
import { encoder } from '../lib/buffer_utils.js';
|
|
4
5
|
function validateInput(label, input) {
|
|
5
6
|
if (!Number.isFinite(input)) {
|
|
6
7
|
throw new TypeError(`Invalid ${label} input`);
|
|
@@ -8,69 +9,83 @@ function validateInput(label, input) {
|
|
|
8
9
|
return input;
|
|
9
10
|
}
|
|
10
11
|
export class ProduceJWT {
|
|
11
|
-
|
|
12
|
-
constructor(payload
|
|
12
|
+
#payload;
|
|
13
|
+
constructor(payload) {
|
|
13
14
|
if (!isObject(payload)) {
|
|
14
15
|
throw new TypeError('JWT Claims Set MUST be an object');
|
|
15
16
|
}
|
|
16
|
-
this
|
|
17
|
+
this.#payload = structuredClone(payload);
|
|
18
|
+
}
|
|
19
|
+
data() {
|
|
20
|
+
return encoder.encode(JSON.stringify(this.#payload));
|
|
21
|
+
}
|
|
22
|
+
get iss() {
|
|
23
|
+
return this.#payload.iss;
|
|
24
|
+
}
|
|
25
|
+
set iss(value) {
|
|
26
|
+
this.#payload.iss = value;
|
|
17
27
|
}
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
return this;
|
|
28
|
+
get sub() {
|
|
29
|
+
return this.#payload.sub;
|
|
21
30
|
}
|
|
22
|
-
|
|
23
|
-
this.
|
|
24
|
-
return this;
|
|
31
|
+
set sub(value) {
|
|
32
|
+
this.#payload.sub = value;
|
|
25
33
|
}
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
return this;
|
|
34
|
+
get aud() {
|
|
35
|
+
return this.#payload.aud;
|
|
29
36
|
}
|
|
30
|
-
|
|
31
|
-
this.
|
|
32
|
-
return this;
|
|
37
|
+
set aud(value) {
|
|
38
|
+
this.#payload.aud = value;
|
|
33
39
|
}
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
40
|
+
get jti() {
|
|
41
|
+
return this.#payload.jti;
|
|
42
|
+
}
|
|
43
|
+
set jti(value) {
|
|
44
|
+
this.#payload.jti = value;
|
|
45
|
+
}
|
|
46
|
+
get nbf() {
|
|
47
|
+
return this.#payload.nbf;
|
|
48
|
+
}
|
|
49
|
+
set nbf(value) {
|
|
50
|
+
if (typeof value === 'number') {
|
|
51
|
+
this.#payload.nbf = validateInput('setNotBefore', value);
|
|
37
52
|
}
|
|
38
|
-
else if (
|
|
39
|
-
this.
|
|
53
|
+
else if (value instanceof Date) {
|
|
54
|
+
this.#payload.nbf = validateInput('setNotBefore', epoch(value));
|
|
40
55
|
}
|
|
41
56
|
else {
|
|
42
|
-
this.
|
|
57
|
+
this.#payload.nbf = epoch(new Date()) + secs(value);
|
|
43
58
|
}
|
|
44
|
-
return this;
|
|
45
59
|
}
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
60
|
+
get exp() {
|
|
61
|
+
return this.#payload.exp;
|
|
62
|
+
}
|
|
63
|
+
set exp(value) {
|
|
64
|
+
if (typeof value === 'number') {
|
|
65
|
+
this.#payload.exp = validateInput('setExpirationTime', value);
|
|
49
66
|
}
|
|
50
|
-
else if (
|
|
51
|
-
this.
|
|
67
|
+
else if (value instanceof Date) {
|
|
68
|
+
this.#payload.exp = validateInput('setExpirationTime', epoch(value));
|
|
52
69
|
}
|
|
53
70
|
else {
|
|
54
|
-
this.
|
|
71
|
+
this.#payload.exp = epoch(new Date()) + secs(value);
|
|
55
72
|
}
|
|
56
|
-
return this;
|
|
57
73
|
}
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
74
|
+
get iat() {
|
|
75
|
+
return this.#payload.iat;
|
|
76
|
+
}
|
|
77
|
+
set iat(value) {
|
|
78
|
+
if (typeof value === 'undefined') {
|
|
79
|
+
this.#payload.iat = epoch(new Date());
|
|
61
80
|
}
|
|
62
|
-
else if (
|
|
63
|
-
this.
|
|
81
|
+
else if (value instanceof Date) {
|
|
82
|
+
this.#payload.iat = validateInput('setIssuedAt', epoch(value));
|
|
64
83
|
}
|
|
65
|
-
else if (typeof
|
|
66
|
-
this.
|
|
67
|
-
...this._payload,
|
|
68
|
-
iat: validateInput('setIssuedAt', epoch(new Date()) + secs(input)),
|
|
69
|
-
};
|
|
84
|
+
else if (typeof value === 'string') {
|
|
85
|
+
this.#payload.iat = validateInput('setIssuedAt', epoch(new Date()) + secs(value));
|
|
70
86
|
}
|
|
71
87
|
else {
|
|
72
|
-
this.
|
|
88
|
+
this.#payload.iat = validateInput('setIssuedAt', value);
|
|
73
89
|
}
|
|
74
|
-
return this;
|
|
75
90
|
}
|
|
76
91
|
}
|
package/dist/webapi/jwt/sign.js
CHANGED
|
@@ -1,19 +1,50 @@
|
|
|
1
1
|
import { CompactSign } from '../jws/compact/sign.js';
|
|
2
2
|
import { JWTInvalid } from '../util/errors.js';
|
|
3
|
-
import { encoder } from '../lib/buffer_utils.js';
|
|
4
3
|
import { ProduceJWT } from './produce.js';
|
|
5
|
-
export class SignJWT
|
|
6
|
-
|
|
4
|
+
export class SignJWT {
|
|
5
|
+
#protectedHeader;
|
|
6
|
+
#jwt;
|
|
7
|
+
constructor(payload = {}) {
|
|
8
|
+
this.#jwt = new ProduceJWT(payload);
|
|
9
|
+
}
|
|
10
|
+
setIssuer(issuer) {
|
|
11
|
+
this.#jwt.iss = issuer;
|
|
12
|
+
return this;
|
|
13
|
+
}
|
|
14
|
+
setSubject(subject) {
|
|
15
|
+
this.#jwt.sub = subject;
|
|
16
|
+
return this;
|
|
17
|
+
}
|
|
18
|
+
setAudience(audience) {
|
|
19
|
+
this.#jwt.aud = audience;
|
|
20
|
+
return this;
|
|
21
|
+
}
|
|
22
|
+
setJti(jwtId) {
|
|
23
|
+
this.#jwt.jti = jwtId;
|
|
24
|
+
return this;
|
|
25
|
+
}
|
|
26
|
+
setNotBefore(input) {
|
|
27
|
+
this.#jwt.nbf = input;
|
|
28
|
+
return this;
|
|
29
|
+
}
|
|
30
|
+
setExpirationTime(input) {
|
|
31
|
+
this.#jwt.exp = input;
|
|
32
|
+
return this;
|
|
33
|
+
}
|
|
34
|
+
setIssuedAt(input) {
|
|
35
|
+
this.#jwt.iat = input;
|
|
36
|
+
return this;
|
|
37
|
+
}
|
|
7
38
|
setProtectedHeader(protectedHeader) {
|
|
8
|
-
this
|
|
39
|
+
this.#protectedHeader = protectedHeader;
|
|
9
40
|
return this;
|
|
10
41
|
}
|
|
11
42
|
async sign(key, options) {
|
|
12
|
-
const sig = new CompactSign(
|
|
13
|
-
sig.setProtectedHeader(this
|
|
14
|
-
if (Array.isArray(this
|
|
15
|
-
this.
|
|
16
|
-
this.
|
|
43
|
+
const sig = new CompactSign(this.#jwt.data());
|
|
44
|
+
sig.setProtectedHeader(this.#protectedHeader);
|
|
45
|
+
if (Array.isArray(this.#protectedHeader?.crit) &&
|
|
46
|
+
this.#protectedHeader.crit.includes('b64') &&
|
|
47
|
+
this.#protectedHeader.b64 === false) {
|
|
17
48
|
throw new JWTInvalid('JWTs MUST NOT use unencoded payload');
|
|
18
49
|
}
|
|
19
50
|
return sig.sign(key, options);
|
|
@@ -3,12 +3,44 @@ import { decoder } from '../lib/buffer_utils.js';
|
|
|
3
3
|
import { JWTInvalid } from '../util/errors.js';
|
|
4
4
|
import jwtPayload from '../lib/jwt_claims_set.js';
|
|
5
5
|
import { ProduceJWT } from './produce.js';
|
|
6
|
-
export class UnsecuredJWT
|
|
6
|
+
export class UnsecuredJWT {
|
|
7
|
+
#jwt;
|
|
8
|
+
constructor(payload = {}) {
|
|
9
|
+
this.#jwt = new ProduceJWT(payload);
|
|
10
|
+
}
|
|
7
11
|
encode() {
|
|
8
12
|
const header = b64u.encode(JSON.stringify({ alg: 'none' }));
|
|
9
|
-
const payload = b64u.encode(
|
|
13
|
+
const payload = b64u.encode(this.#jwt.data());
|
|
10
14
|
return `${header}.${payload}.`;
|
|
11
15
|
}
|
|
16
|
+
setIssuer(issuer) {
|
|
17
|
+
this.#jwt.iss = issuer;
|
|
18
|
+
return this;
|
|
19
|
+
}
|
|
20
|
+
setSubject(subject) {
|
|
21
|
+
this.#jwt.sub = subject;
|
|
22
|
+
return this;
|
|
23
|
+
}
|
|
24
|
+
setAudience(audience) {
|
|
25
|
+
this.#jwt.aud = audience;
|
|
26
|
+
return this;
|
|
27
|
+
}
|
|
28
|
+
setJti(jwtId) {
|
|
29
|
+
this.#jwt.jti = jwtId;
|
|
30
|
+
return this;
|
|
31
|
+
}
|
|
32
|
+
setNotBefore(input) {
|
|
33
|
+
this.#jwt.nbf = input;
|
|
34
|
+
return this;
|
|
35
|
+
}
|
|
36
|
+
setExpirationTime(input) {
|
|
37
|
+
this.#jwt.exp = input;
|
|
38
|
+
return this;
|
|
39
|
+
}
|
|
40
|
+
setIssuedAt(input) {
|
|
41
|
+
this.#jwt.iat = input;
|
|
42
|
+
return this;
|
|
43
|
+
}
|
|
12
44
|
static decode(jwt, options) {
|
|
13
45
|
if (typeof jwt !== 'string') {
|
|
14
46
|
throw new JWTInvalid('Unsecured JWT must be a string');
|