jose 4.2.1 → 4.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -25,6 +25,21 @@ If you or your business use `jose`, please consider becoming a [sponsor][support
25
25
 
26
26
  ## Documentation
27
27
 
28
+ **`example`** ESM import
29
+ ```js
30
+ import * as jose from 'jose'
31
+ ```
32
+
33
+ **`example`** CJS require
34
+ ```js
35
+ const jose = require('jose')
36
+ ```
37
+
38
+ **`example`** Deno import
39
+ ```js
40
+ import * as jose from 'https://deno.land/x/jose/index.ts'
41
+ ```
42
+
28
43
  - JSON Web Tokens (JWT)
29
44
  - [Signing](docs/classes/jwt_sign.SignJWT.md#readme)
30
45
  - [Verification & Claims Set Validation](docs/functions/jwt_verify.jwtVerify.md#readme)
@@ -5,16 +5,28 @@ import isDisjoint from '../../lib/is_disjoint.js';
5
5
  import encryptKeyManagement from '../../lib/encrypt_key_management.js';
6
6
  import { encode as base64url } from '../../runtime/base64url.js';
7
7
  import validateCrit from '../../lib/validate_crit.js';
8
- const recipientRef = new WeakMap();
9
8
  class IndividualRecipient {
9
+ constructor(enc, key, options) {
10
+ this.parent = enc;
11
+ this.key = key;
12
+ this.options = options;
13
+ }
10
14
  setUnprotectedHeader(unprotectedHeader) {
11
- const ref = recipientRef.get(this);
12
- if (ref.unprotectedHeader) {
15
+ if (this.unprotectedHeader) {
13
16
  throw new TypeError('setUnprotectedHeader can only be called once');
14
17
  }
15
- ref.unprotectedHeader = unprotectedHeader;
18
+ this.unprotectedHeader = unprotectedHeader;
16
19
  return this;
17
20
  }
21
+ addRecipient(...args) {
22
+ return this.parent.addRecipient(...args);
23
+ }
24
+ encrypt(...args) {
25
+ return this.parent.encrypt(...args);
26
+ }
27
+ done() {
28
+ return this.parent;
29
+ }
18
30
  }
19
31
  export class GeneralEncrypt {
20
32
  constructor(plaintext) {
@@ -22,8 +34,7 @@ export class GeneralEncrypt {
22
34
  this._plaintext = plaintext;
23
35
  }
24
36
  addRecipient(key, options) {
25
- const recipient = new IndividualRecipient();
26
- recipientRef.set(recipient, { key, options: { crit: options === null || options === void 0 ? void 0 : options.crit } });
37
+ const recipient = new IndividualRecipient(this, key, { crit: options === null || options === void 0 ? void 0 : options.crit });
27
38
  this._recipients.push(recipient);
28
39
  return recipient;
29
40
  }
@@ -46,19 +57,19 @@ export class GeneralEncrypt {
46
57
  return this;
47
58
  }
48
59
  async encrypt(options) {
49
- var _a, _b;
60
+ var _a, _b, _c;
50
61
  if (!this._recipients.length) {
51
62
  throw new JWEInvalid('at least one recipient must be added');
52
63
  }
53
64
  options = { deflateRaw: options === null || options === void 0 ? void 0 : options.deflateRaw };
54
65
  if (this._recipients.length === 1) {
55
- const { unprotectedHeader, options: recipientOpts, key, } = recipientRef.get(this._recipients[0]);
66
+ const [recipient] = this._recipients;
56
67
  const flattened = await new FlattenedEncrypt(this._plaintext)
57
68
  .setAdditionalAuthenticatedData(this._aad)
58
69
  .setProtectedHeader(this._protectedHeader)
59
70
  .setSharedUnprotectedHeader(this._unprotectedHeader)
60
- .setUnprotectedHeader(unprotectedHeader)
61
- .encrypt(key, { ...recipientOpts, ...options });
71
+ .setUnprotectedHeader(recipient.unprotectedHeader)
72
+ .encrypt(recipient.key, { ...recipient.options, ...options });
62
73
  let jwe = {
63
74
  ciphertext: flattened.ciphertext,
64
75
  iv: flattened.iv,
@@ -80,14 +91,13 @@ export class GeneralEncrypt {
80
91
  let enc;
81
92
  for (let i = 0; i < this._recipients.length; i++) {
82
93
  const recipient = this._recipients[i];
83
- const { unprotectedHeader, options: recipientOpts } = recipientRef.get(recipient);
84
- if (!isDisjoint(this._protectedHeader, this._unprotectedHeader, unprotectedHeader)) {
94
+ if (!isDisjoint(this._protectedHeader, this._unprotectedHeader, recipient.unprotectedHeader)) {
85
95
  throw new JWEInvalid('JWE Protected, JWE Shared Unprotected and JWE Per-Recipient Header Parameter names must be disjoint');
86
96
  }
87
97
  const joseHeader = {
88
98
  ...this._protectedHeader,
89
99
  ...this._unprotectedHeader,
90
- ...unprotectedHeader,
100
+ ...recipient.unprotectedHeader,
91
101
  };
92
102
  const { alg } = joseHeader;
93
103
  if (typeof alg !== 'string' || !alg) {
@@ -105,7 +115,7 @@ export class GeneralEncrypt {
105
115
  else if (enc !== joseHeader.enc) {
106
116
  throw new JWEInvalid('JWE "enc" (Encryption Algorithm) Header Parameter must be the same for all recipients');
107
117
  }
108
- validateCrit(JWEInvalid, new Map(), recipientOpts === null || recipientOpts === void 0 ? void 0 : recipientOpts.crit, this._protectedHeader, joseHeader);
118
+ validateCrit(JWEInvalid, new Map(), recipient.options.crit, this._protectedHeader, joseHeader);
109
119
  if (joseHeader.zip !== undefined) {
110
120
  if (!this._protectedHeader || !this._protectedHeader.zip) {
111
121
  throw new JWEInvalid('JWE "zip" (Compression Algorithm) Header MUST be integrity protected');
@@ -123,15 +133,18 @@ export class GeneralEncrypt {
123
133
  const recipient = this._recipients[i];
124
134
  const target = {};
125
135
  jwe.recipients.push(target);
126
- const { unprotectedHeader, options: recipientOpts, key } = recipientRef.get(recipient);
127
136
  if (i === 0) {
128
137
  const flattened = await new FlattenedEncrypt(this._plaintext)
129
138
  .setAdditionalAuthenticatedData(this._aad)
130
139
  .setContentEncryptionKey(cek)
131
140
  .setProtectedHeader(this._protectedHeader)
132
141
  .setSharedUnprotectedHeader(this._unprotectedHeader)
133
- .setUnprotectedHeader(unprotectedHeader)
134
- .encrypt(key, { ...recipientOpts, ...options, [unprotected]: true });
142
+ .setUnprotectedHeader(recipient.unprotectedHeader)
143
+ .encrypt(recipient.key, {
144
+ ...recipient.options,
145
+ ...options,
146
+ [unprotected]: true,
147
+ });
135
148
  jwe.ciphertext = flattened.ciphertext;
136
149
  jwe.iv = flattened.iv;
137
150
  jwe.tag = flattened.tag;
@@ -146,10 +159,12 @@ export class GeneralEncrypt {
146
159
  target.header = flattened.header;
147
160
  continue;
148
161
  }
149
- const { encryptedKey, parameters } = await encryptKeyManagement((unprotectedHeader === null || unprotectedHeader === void 0 ? void 0 : unprotectedHeader.alg) || ((_a = this._protectedHeader) === null || _a === void 0 ? void 0 : _a.alg) || ((_b = this._unprotectedHeader) === null || _b === void 0 ? void 0 : _b.alg), enc, key, cek);
162
+ const { encryptedKey, parameters } = await encryptKeyManagement(((_a = recipient.unprotectedHeader) === null || _a === void 0 ? void 0 : _a.alg) ||
163
+ ((_b = this._protectedHeader) === null || _b === void 0 ? void 0 : _b.alg) ||
164
+ ((_c = this._unprotectedHeader) === null || _c === void 0 ? void 0 : _c.alg), enc, recipient.key, cek);
150
165
  target.encrypted_key = base64url(encryptedKey);
151
- if (unprotectedHeader || parameters)
152
- target.header = { ...unprotectedHeader, ...parameters };
166
+ if (recipient.unprotectedHeader || parameters)
167
+ target.header = { ...recipient.unprotectedHeader, ...parameters };
153
168
  }
154
169
  return jwe;
155
170
  }
@@ -1,23 +1,34 @@
1
1
  import { FlattenedSign } from '../flattened/sign.js';
2
2
  import { JWSInvalid } from '../../util/errors.js';
3
- const signatureRef = new WeakMap();
4
3
  class IndividualSignature {
4
+ constructor(sig, key, options) {
5
+ this.parent = sig;
6
+ this.key = key;
7
+ this.options = options;
8
+ }
5
9
  setProtectedHeader(protectedHeader) {
6
- const ref = signatureRef.get(this);
7
- if (ref.protectedHeader) {
10
+ if (this.protectedHeader) {
8
11
  throw new TypeError('setProtectedHeader can only be called once');
9
12
  }
10
- ref.protectedHeader = protectedHeader;
13
+ this.protectedHeader = protectedHeader;
11
14
  return this;
12
15
  }
13
16
  setUnprotectedHeader(unprotectedHeader) {
14
- const ref = signatureRef.get(this);
15
- if (ref.unprotectedHeader) {
17
+ if (this.unprotectedHeader) {
16
18
  throw new TypeError('setUnprotectedHeader can only be called once');
17
19
  }
18
- ref.unprotectedHeader = unprotectedHeader;
20
+ this.unprotectedHeader = unprotectedHeader;
19
21
  return this;
20
22
  }
23
+ addSignature(...args) {
24
+ return this.parent.addSignature(...args);
25
+ }
26
+ sign(...args) {
27
+ return this.parent.sign(...args);
28
+ }
29
+ done() {
30
+ return this.parent;
31
+ }
21
32
  }
22
33
  export class GeneralSign {
23
34
  constructor(payload) {
@@ -25,8 +36,7 @@ export class GeneralSign {
25
36
  this._payload = payload;
26
37
  }
27
38
  addSignature(key, options) {
28
- const signature = new IndividualSignature();
29
- signatureRef.set(signature, { key, options });
39
+ const signature = new IndividualSignature(this, key, options);
30
40
  this._signatures.push(signature);
31
41
  return signature;
32
42
  }
@@ -38,23 +48,19 @@ export class GeneralSign {
38
48
  signatures: [],
39
49
  payload: '',
40
50
  };
41
- let payloads = new Set();
42
- await Promise.all(this._signatures.map(async (sig) => {
43
- const { protectedHeader, unprotectedHeader, options, key } = signatureRef.get(sig);
51
+ for (let i = 0; i < this._signatures.length; i++) {
52
+ const signature = this._signatures[i];
44
53
  const flattened = new FlattenedSign(this._payload);
45
- if (protectedHeader) {
46
- flattened.setProtectedHeader(protectedHeader);
54
+ flattened.setProtectedHeader(signature.protectedHeader);
55
+ flattened.setUnprotectedHeader(signature.unprotectedHeader);
56
+ const { payload, ...rest } = await flattened.sign(signature.key, signature.options);
57
+ if (i === 0) {
58
+ jws.payload = payload;
47
59
  }
48
- if (unprotectedHeader) {
49
- flattened.setUnprotectedHeader(unprotectedHeader);
60
+ else if (jws.payload !== payload) {
61
+ throw new JWSInvalid('inconsistent use of JWS Unencoded Payload Option (RFC7797)');
50
62
  }
51
- const { payload, ...rest } = await flattened.sign(key, options);
52
- payloads.add(payload);
53
- jws.payload = payload;
54
63
  jws.signatures.push(rest);
55
- }));
56
- if (payloads.size !== 1) {
57
- throw new JWSInvalid('inconsistent use of JWS Unencoded Payload Option (RFC7797)');
58
64
  }
59
65
  return jws;
60
66
  }
@@ -8,16 +8,28 @@ const is_disjoint_js_1 = require("../../lib/is_disjoint.js");
8
8
  const encrypt_key_management_js_1 = require("../../lib/encrypt_key_management.js");
9
9
  const base64url_js_1 = require("../../runtime/base64url.js");
10
10
  const validate_crit_js_1 = require("../../lib/validate_crit.js");
11
- const recipientRef = new WeakMap();
12
11
  class IndividualRecipient {
12
+ constructor(enc, key, options) {
13
+ this.parent = enc;
14
+ this.key = key;
15
+ this.options = options;
16
+ }
13
17
  setUnprotectedHeader(unprotectedHeader) {
14
- const ref = recipientRef.get(this);
15
- if (ref.unprotectedHeader) {
18
+ if (this.unprotectedHeader) {
16
19
  throw new TypeError('setUnprotectedHeader can only be called once');
17
20
  }
18
- ref.unprotectedHeader = unprotectedHeader;
21
+ this.unprotectedHeader = unprotectedHeader;
19
22
  return this;
20
23
  }
24
+ addRecipient(...args) {
25
+ return this.parent.addRecipient(...args);
26
+ }
27
+ encrypt(...args) {
28
+ return this.parent.encrypt(...args);
29
+ }
30
+ done() {
31
+ return this.parent;
32
+ }
21
33
  }
22
34
  class GeneralEncrypt {
23
35
  constructor(plaintext) {
@@ -25,8 +37,7 @@ class GeneralEncrypt {
25
37
  this._plaintext = plaintext;
26
38
  }
27
39
  addRecipient(key, options) {
28
- const recipient = new IndividualRecipient();
29
- recipientRef.set(recipient, { key, options: { crit: options === null || options === void 0 ? void 0 : options.crit } });
40
+ const recipient = new IndividualRecipient(this, key, { crit: options === null || options === void 0 ? void 0 : options.crit });
30
41
  this._recipients.push(recipient);
31
42
  return recipient;
32
43
  }
@@ -49,19 +60,19 @@ class GeneralEncrypt {
49
60
  return this;
50
61
  }
51
62
  async encrypt(options) {
52
- var _a, _b;
63
+ var _a, _b, _c;
53
64
  if (!this._recipients.length) {
54
65
  throw new errors_js_1.JWEInvalid('at least one recipient must be added');
55
66
  }
56
67
  options = { deflateRaw: options === null || options === void 0 ? void 0 : options.deflateRaw };
57
68
  if (this._recipients.length === 1) {
58
- const { unprotectedHeader, options: recipientOpts, key, } = recipientRef.get(this._recipients[0]);
69
+ const [recipient] = this._recipients;
59
70
  const flattened = await new encrypt_js_1.FlattenedEncrypt(this._plaintext)
60
71
  .setAdditionalAuthenticatedData(this._aad)
61
72
  .setProtectedHeader(this._protectedHeader)
62
73
  .setSharedUnprotectedHeader(this._unprotectedHeader)
63
- .setUnprotectedHeader(unprotectedHeader)
64
- .encrypt(key, { ...recipientOpts, ...options });
74
+ .setUnprotectedHeader(recipient.unprotectedHeader)
75
+ .encrypt(recipient.key, { ...recipient.options, ...options });
65
76
  let jwe = {
66
77
  ciphertext: flattened.ciphertext,
67
78
  iv: flattened.iv,
@@ -83,14 +94,13 @@ class GeneralEncrypt {
83
94
  let enc;
84
95
  for (let i = 0; i < this._recipients.length; i++) {
85
96
  const recipient = this._recipients[i];
86
- const { unprotectedHeader, options: recipientOpts } = recipientRef.get(recipient);
87
- if (!(0, is_disjoint_js_1.default)(this._protectedHeader, this._unprotectedHeader, unprotectedHeader)) {
97
+ if (!(0, is_disjoint_js_1.default)(this._protectedHeader, this._unprotectedHeader, recipient.unprotectedHeader)) {
88
98
  throw new errors_js_1.JWEInvalid('JWE Protected, JWE Shared Unprotected and JWE Per-Recipient Header Parameter names must be disjoint');
89
99
  }
90
100
  const joseHeader = {
91
101
  ...this._protectedHeader,
92
102
  ...this._unprotectedHeader,
93
- ...unprotectedHeader,
103
+ ...recipient.unprotectedHeader,
94
104
  };
95
105
  const { alg } = joseHeader;
96
106
  if (typeof alg !== 'string' || !alg) {
@@ -108,7 +118,7 @@ class GeneralEncrypt {
108
118
  else if (enc !== joseHeader.enc) {
109
119
  throw new errors_js_1.JWEInvalid('JWE "enc" (Encryption Algorithm) Header Parameter must be the same for all recipients');
110
120
  }
111
- (0, validate_crit_js_1.default)(errors_js_1.JWEInvalid, new Map(), recipientOpts === null || recipientOpts === void 0 ? void 0 : recipientOpts.crit, this._protectedHeader, joseHeader);
121
+ (0, validate_crit_js_1.default)(errors_js_1.JWEInvalid, new Map(), recipient.options.crit, this._protectedHeader, joseHeader);
112
122
  if (joseHeader.zip !== undefined) {
113
123
  if (!this._protectedHeader || !this._protectedHeader.zip) {
114
124
  throw new errors_js_1.JWEInvalid('JWE "zip" (Compression Algorithm) Header MUST be integrity protected');
@@ -126,15 +136,18 @@ class GeneralEncrypt {
126
136
  const recipient = this._recipients[i];
127
137
  const target = {};
128
138
  jwe.recipients.push(target);
129
- const { unprotectedHeader, options: recipientOpts, key } = recipientRef.get(recipient);
130
139
  if (i === 0) {
131
140
  const flattened = await new encrypt_js_1.FlattenedEncrypt(this._plaintext)
132
141
  .setAdditionalAuthenticatedData(this._aad)
133
142
  .setContentEncryptionKey(cek)
134
143
  .setProtectedHeader(this._protectedHeader)
135
144
  .setSharedUnprotectedHeader(this._unprotectedHeader)
136
- .setUnprotectedHeader(unprotectedHeader)
137
- .encrypt(key, { ...recipientOpts, ...options, [encrypt_js_1.unprotected]: true });
145
+ .setUnprotectedHeader(recipient.unprotectedHeader)
146
+ .encrypt(recipient.key, {
147
+ ...recipient.options,
148
+ ...options,
149
+ [encrypt_js_1.unprotected]: true,
150
+ });
138
151
  jwe.ciphertext = flattened.ciphertext;
139
152
  jwe.iv = flattened.iv;
140
153
  jwe.tag = flattened.tag;
@@ -149,10 +162,12 @@ class GeneralEncrypt {
149
162
  target.header = flattened.header;
150
163
  continue;
151
164
  }
152
- const { encryptedKey, parameters } = await (0, encrypt_key_management_js_1.default)((unprotectedHeader === null || unprotectedHeader === void 0 ? void 0 : unprotectedHeader.alg) || ((_a = this._protectedHeader) === null || _a === void 0 ? void 0 : _a.alg) || ((_b = this._unprotectedHeader) === null || _b === void 0 ? void 0 : _b.alg), enc, key, cek);
165
+ const { encryptedKey, parameters } = await (0, encrypt_key_management_js_1.default)(((_a = recipient.unprotectedHeader) === null || _a === void 0 ? void 0 : _a.alg) ||
166
+ ((_b = this._protectedHeader) === null || _b === void 0 ? void 0 : _b.alg) ||
167
+ ((_c = this._unprotectedHeader) === null || _c === void 0 ? void 0 : _c.alg), enc, recipient.key, cek);
153
168
  target.encrypted_key = (0, base64url_js_1.encode)(encryptedKey);
154
- if (unprotectedHeader || parameters)
155
- target.header = { ...unprotectedHeader, ...parameters };
169
+ if (recipient.unprotectedHeader || parameters)
170
+ target.header = { ...recipient.unprotectedHeader, ...parameters };
156
171
  }
157
172
  return jwe;
158
173
  }
@@ -3,24 +3,35 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.GeneralSign = void 0;
4
4
  const sign_js_1 = require("../flattened/sign.js");
5
5
  const errors_js_1 = require("../../util/errors.js");
6
- const signatureRef = new WeakMap();
7
6
  class IndividualSignature {
7
+ constructor(sig, key, options) {
8
+ this.parent = sig;
9
+ this.key = key;
10
+ this.options = options;
11
+ }
8
12
  setProtectedHeader(protectedHeader) {
9
- const ref = signatureRef.get(this);
10
- if (ref.protectedHeader) {
13
+ if (this.protectedHeader) {
11
14
  throw new TypeError('setProtectedHeader can only be called once');
12
15
  }
13
- ref.protectedHeader = protectedHeader;
16
+ this.protectedHeader = protectedHeader;
14
17
  return this;
15
18
  }
16
19
  setUnprotectedHeader(unprotectedHeader) {
17
- const ref = signatureRef.get(this);
18
- if (ref.unprotectedHeader) {
20
+ if (this.unprotectedHeader) {
19
21
  throw new TypeError('setUnprotectedHeader can only be called once');
20
22
  }
21
- ref.unprotectedHeader = unprotectedHeader;
23
+ this.unprotectedHeader = unprotectedHeader;
22
24
  return this;
23
25
  }
26
+ addSignature(...args) {
27
+ return this.parent.addSignature(...args);
28
+ }
29
+ sign(...args) {
30
+ return this.parent.sign(...args);
31
+ }
32
+ done() {
33
+ return this.parent;
34
+ }
24
35
  }
25
36
  class GeneralSign {
26
37
  constructor(payload) {
@@ -28,8 +39,7 @@ class GeneralSign {
28
39
  this._payload = payload;
29
40
  }
30
41
  addSignature(key, options) {
31
- const signature = new IndividualSignature();
32
- signatureRef.set(signature, { key, options });
42
+ const signature = new IndividualSignature(this, key, options);
33
43
  this._signatures.push(signature);
34
44
  return signature;
35
45
  }
@@ -41,23 +51,19 @@ class GeneralSign {
41
51
  signatures: [],
42
52
  payload: '',
43
53
  };
44
- let payloads = new Set();
45
- await Promise.all(this._signatures.map(async (sig) => {
46
- const { protectedHeader, unprotectedHeader, options, key } = signatureRef.get(sig);
54
+ for (let i = 0; i < this._signatures.length; i++) {
55
+ const signature = this._signatures[i];
47
56
  const flattened = new sign_js_1.FlattenedSign(this._payload);
48
- if (protectedHeader) {
49
- flattened.setProtectedHeader(protectedHeader);
57
+ flattened.setProtectedHeader(signature.protectedHeader);
58
+ flattened.setUnprotectedHeader(signature.unprotectedHeader);
59
+ const { payload, ...rest } = await flattened.sign(signature.key, signature.options);
60
+ if (i === 0) {
61
+ jws.payload = payload;
50
62
  }
51
- if (unprotectedHeader) {
52
- flattened.setUnprotectedHeader(unprotectedHeader);
63
+ else if (jws.payload !== payload) {
64
+ throw new errors_js_1.JWSInvalid('inconsistent use of JWS Unencoded Payload Option (RFC7797)');
53
65
  }
54
- const { payload, ...rest } = await flattened.sign(key, options);
55
- payloads.add(payload);
56
- jws.payload = payload;
57
66
  jws.signatures.push(rest);
58
- }));
59
- if (payloads.size !== 1) {
60
- throw new errors_js_1.JWSInvalid('inconsistent use of JWS Unencoded Payload Option (RFC7797)');
61
67
  }
62
68
  return jws;
63
69
  }
@@ -5,16 +5,28 @@ import isDisjoint from '../../lib/is_disjoint.js';
5
5
  import encryptKeyManagement from '../../lib/encrypt_key_management.js';
6
6
  import { encode as base64url } from '../../runtime/base64url.js';
7
7
  import validateCrit from '../../lib/validate_crit.js';
8
- const recipientRef = new WeakMap();
9
8
  class IndividualRecipient {
9
+ constructor(enc, key, options) {
10
+ this.parent = enc;
11
+ this.key = key;
12
+ this.options = options;
13
+ }
10
14
  setUnprotectedHeader(unprotectedHeader) {
11
- const ref = recipientRef.get(this);
12
- if (ref.unprotectedHeader) {
15
+ if (this.unprotectedHeader) {
13
16
  throw new TypeError('setUnprotectedHeader can only be called once');
14
17
  }
15
- ref.unprotectedHeader = unprotectedHeader;
18
+ this.unprotectedHeader = unprotectedHeader;
16
19
  return this;
17
20
  }
21
+ addRecipient(...args) {
22
+ return this.parent.addRecipient(...args);
23
+ }
24
+ encrypt(...args) {
25
+ return this.parent.encrypt(...args);
26
+ }
27
+ done() {
28
+ return this.parent;
29
+ }
18
30
  }
19
31
  export class GeneralEncrypt {
20
32
  constructor(plaintext) {
@@ -22,8 +34,7 @@ export class GeneralEncrypt {
22
34
  this._plaintext = plaintext;
23
35
  }
24
36
  addRecipient(key, options) {
25
- const recipient = new IndividualRecipient();
26
- recipientRef.set(recipient, { key, options: { crit: options === null || options === void 0 ? void 0 : options.crit } });
37
+ const recipient = new IndividualRecipient(this, key, { crit: options === null || options === void 0 ? void 0 : options.crit });
27
38
  this._recipients.push(recipient);
28
39
  return recipient;
29
40
  }
@@ -46,19 +57,19 @@ export class GeneralEncrypt {
46
57
  return this;
47
58
  }
48
59
  async encrypt(options) {
49
- var _a, _b;
60
+ var _a, _b, _c;
50
61
  if (!this._recipients.length) {
51
62
  throw new JWEInvalid('at least one recipient must be added');
52
63
  }
53
64
  options = { deflateRaw: options === null || options === void 0 ? void 0 : options.deflateRaw };
54
65
  if (this._recipients.length === 1) {
55
- const { unprotectedHeader, options: recipientOpts, key, } = recipientRef.get(this._recipients[0]);
66
+ const [recipient] = this._recipients;
56
67
  const flattened = await new FlattenedEncrypt(this._plaintext)
57
68
  .setAdditionalAuthenticatedData(this._aad)
58
69
  .setProtectedHeader(this._protectedHeader)
59
70
  .setSharedUnprotectedHeader(this._unprotectedHeader)
60
- .setUnprotectedHeader(unprotectedHeader)
61
- .encrypt(key, { ...recipientOpts, ...options });
71
+ .setUnprotectedHeader(recipient.unprotectedHeader)
72
+ .encrypt(recipient.key, { ...recipient.options, ...options });
62
73
  let jwe = {
63
74
  ciphertext: flattened.ciphertext,
64
75
  iv: flattened.iv,
@@ -80,14 +91,13 @@ export class GeneralEncrypt {
80
91
  let enc;
81
92
  for (let i = 0; i < this._recipients.length; i++) {
82
93
  const recipient = this._recipients[i];
83
- const { unprotectedHeader, options: recipientOpts } = recipientRef.get(recipient);
84
- if (!isDisjoint(this._protectedHeader, this._unprotectedHeader, unprotectedHeader)) {
94
+ if (!isDisjoint(this._protectedHeader, this._unprotectedHeader, recipient.unprotectedHeader)) {
85
95
  throw new JWEInvalid('JWE Protected, JWE Shared Unprotected and JWE Per-Recipient Header Parameter names must be disjoint');
86
96
  }
87
97
  const joseHeader = {
88
98
  ...this._protectedHeader,
89
99
  ...this._unprotectedHeader,
90
- ...unprotectedHeader,
100
+ ...recipient.unprotectedHeader,
91
101
  };
92
102
  const { alg } = joseHeader;
93
103
  if (typeof alg !== 'string' || !alg) {
@@ -105,7 +115,7 @@ export class GeneralEncrypt {
105
115
  else if (enc !== joseHeader.enc) {
106
116
  throw new JWEInvalid('JWE "enc" (Encryption Algorithm) Header Parameter must be the same for all recipients');
107
117
  }
108
- validateCrit(JWEInvalid, new Map(), recipientOpts === null || recipientOpts === void 0 ? void 0 : recipientOpts.crit, this._protectedHeader, joseHeader);
118
+ validateCrit(JWEInvalid, new Map(), recipient.options.crit, this._protectedHeader, joseHeader);
109
119
  if (joseHeader.zip !== undefined) {
110
120
  if (!this._protectedHeader || !this._protectedHeader.zip) {
111
121
  throw new JWEInvalid('JWE "zip" (Compression Algorithm) Header MUST be integrity protected');
@@ -123,15 +133,18 @@ export class GeneralEncrypt {
123
133
  const recipient = this._recipients[i];
124
134
  const target = {};
125
135
  jwe.recipients.push(target);
126
- const { unprotectedHeader, options: recipientOpts, key } = recipientRef.get(recipient);
127
136
  if (i === 0) {
128
137
  const flattened = await new FlattenedEncrypt(this._plaintext)
129
138
  .setAdditionalAuthenticatedData(this._aad)
130
139
  .setContentEncryptionKey(cek)
131
140
  .setProtectedHeader(this._protectedHeader)
132
141
  .setSharedUnprotectedHeader(this._unprotectedHeader)
133
- .setUnprotectedHeader(unprotectedHeader)
134
- .encrypt(key, { ...recipientOpts, ...options, [unprotected]: true });
142
+ .setUnprotectedHeader(recipient.unprotectedHeader)
143
+ .encrypt(recipient.key, {
144
+ ...recipient.options,
145
+ ...options,
146
+ [unprotected]: true,
147
+ });
135
148
  jwe.ciphertext = flattened.ciphertext;
136
149
  jwe.iv = flattened.iv;
137
150
  jwe.tag = flattened.tag;
@@ -146,10 +159,12 @@ export class GeneralEncrypt {
146
159
  target.header = flattened.header;
147
160
  continue;
148
161
  }
149
- const { encryptedKey, parameters } = await encryptKeyManagement((unprotectedHeader === null || unprotectedHeader === void 0 ? void 0 : unprotectedHeader.alg) || ((_a = this._protectedHeader) === null || _a === void 0 ? void 0 : _a.alg) || ((_b = this._unprotectedHeader) === null || _b === void 0 ? void 0 : _b.alg), enc, key, cek);
162
+ const { encryptedKey, parameters } = await encryptKeyManagement(((_a = recipient.unprotectedHeader) === null || _a === void 0 ? void 0 : _a.alg) ||
163
+ ((_b = this._protectedHeader) === null || _b === void 0 ? void 0 : _b.alg) ||
164
+ ((_c = this._unprotectedHeader) === null || _c === void 0 ? void 0 : _c.alg), enc, recipient.key, cek);
150
165
  target.encrypted_key = base64url(encryptedKey);
151
- if (unprotectedHeader || parameters)
152
- target.header = { ...unprotectedHeader, ...parameters };
166
+ if (recipient.unprotectedHeader || parameters)
167
+ target.header = { ...recipient.unprotectedHeader, ...parameters };
153
168
  }
154
169
  return jwe;
155
170
  }
@@ -1,23 +1,34 @@
1
1
  import { FlattenedSign } from '../flattened/sign.js';
2
2
  import { JWSInvalid } from '../../util/errors.js';
3
- const signatureRef = new WeakMap();
4
3
  class IndividualSignature {
4
+ constructor(sig, key, options) {
5
+ this.parent = sig;
6
+ this.key = key;
7
+ this.options = options;
8
+ }
5
9
  setProtectedHeader(protectedHeader) {
6
- const ref = signatureRef.get(this);
7
- if (ref.protectedHeader) {
10
+ if (this.protectedHeader) {
8
11
  throw new TypeError('setProtectedHeader can only be called once');
9
12
  }
10
- ref.protectedHeader = protectedHeader;
13
+ this.protectedHeader = protectedHeader;
11
14
  return this;
12
15
  }
13
16
  setUnprotectedHeader(unprotectedHeader) {
14
- const ref = signatureRef.get(this);
15
- if (ref.unprotectedHeader) {
17
+ if (this.unprotectedHeader) {
16
18
  throw new TypeError('setUnprotectedHeader can only be called once');
17
19
  }
18
- ref.unprotectedHeader = unprotectedHeader;
20
+ this.unprotectedHeader = unprotectedHeader;
19
21
  return this;
20
22
  }
23
+ addSignature(...args) {
24
+ return this.parent.addSignature(...args);
25
+ }
26
+ sign(...args) {
27
+ return this.parent.sign(...args);
28
+ }
29
+ done() {
30
+ return this.parent;
31
+ }
21
32
  }
22
33
  export class GeneralSign {
23
34
  constructor(payload) {
@@ -25,8 +36,7 @@ export class GeneralSign {
25
36
  this._payload = payload;
26
37
  }
27
38
  addSignature(key, options) {
28
- const signature = new IndividualSignature();
29
- signatureRef.set(signature, { key, options });
39
+ const signature = new IndividualSignature(this, key, options);
30
40
  this._signatures.push(signature);
31
41
  return signature;
32
42
  }
@@ -38,23 +48,19 @@ export class GeneralSign {
38
48
  signatures: [],
39
49
  payload: '',
40
50
  };
41
- let payloads = new Set();
42
- await Promise.all(this._signatures.map(async (sig) => {
43
- const { protectedHeader, unprotectedHeader, options, key } = signatureRef.get(sig);
51
+ for (let i = 0; i < this._signatures.length; i++) {
52
+ const signature = this._signatures[i];
44
53
  const flattened = new FlattenedSign(this._payload);
45
- if (protectedHeader) {
46
- flattened.setProtectedHeader(protectedHeader);
54
+ flattened.setProtectedHeader(signature.protectedHeader);
55
+ flattened.setUnprotectedHeader(signature.unprotectedHeader);
56
+ const { payload, ...rest } = await flattened.sign(signature.key, signature.options);
57
+ if (i === 0) {
58
+ jws.payload = payload;
47
59
  }
48
- if (unprotectedHeader) {
49
- flattened.setUnprotectedHeader(unprotectedHeader);
60
+ else if (jws.payload !== payload) {
61
+ throw new JWSInvalid('inconsistent use of JWS Unencoded Payload Option (RFC7797)');
50
62
  }
51
- const { payload, ...rest } = await flattened.sign(key, options);
52
- payloads.add(payload);
53
- jws.payload = payload;
54
63
  jws.signatures.push(rest);
55
- }));
56
- if (payloads.size !== 1) {
57
- throw new JWSInvalid('inconsistent use of JWS Unencoded Payload Option (RFC7797)');
58
64
  }
59
65
  return jws;
60
66
  }
@@ -1,6 +1,9 @@
1
1
  import type { KeyLike, GeneralJWE, JWEHeaderParameters, CritOption, DeflateOption } from '../../types';
2
2
  export interface Recipient {
3
3
  setUnprotectedHeader(unprotectedHeader: JWEHeaderParameters): Recipient;
4
+ addRecipient(...args: Parameters<GeneralEncrypt['addRecipient']>): Recipient;
5
+ encrypt(...args: Parameters<GeneralEncrypt['encrypt']>): Promise<GeneralJWE>;
6
+ done(): GeneralEncrypt;
4
7
  }
5
8
  export declare class GeneralEncrypt {
6
9
  private _plaintext;
@@ -2,6 +2,9 @@ import type { KeyLike, GeneralJWS, JWSHeaderParameters, SignOptions } from '../.
2
2
  export interface Signature {
3
3
  setProtectedHeader(protectedHeader: JWSHeaderParameters): Signature;
4
4
  setUnprotectedHeader(unprotectedHeader: JWSHeaderParameters): Signature;
5
+ addSignature(...args: Parameters<GeneralSign['addSignature']>): Signature;
6
+ sign(...args: Parameters<GeneralSign['sign']>): Promise<GeneralJWS>;
7
+ done(): GeneralSign;
5
8
  }
6
9
  export declare class GeneralSign {
7
10
  private _payload;
@@ -35,20 +35,16 @@
35
35
  *
36
36
  * @example Import a PEM-encoded SPKI Public Key
37
37
  * ```js
38
- * import { importSPKI } from 'jose'
39
- *
40
38
  * const algorithm = 'ES256'
41
39
  * const spki = `-----BEGIN PUBLIC KEY-----
42
40
  * MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEFlHHWfLk0gLBbsLTcuCrbCqoHqmM
43
41
  * YJepMC+Q+Dd6RBmBiA41evUsNMwLeN+PNFqib+xwi9JkJ8qhZkq8Y/IzGg==
44
42
  * -----END PUBLIC KEY-----`
45
- * const ecPublicKey = await importSPKI(spki, algorithm)
43
+ * const ecPublicKey = await jose.importSPKI(spki, algorithm)
46
44
  * ```
47
45
  *
48
46
  * @example Import a X.509 Certificate
49
47
  * ```js
50
- * import { importX509 } from 'jose'
51
- *
52
48
  * const algorithm = 'ES256'
53
49
  * const x509 = `-----BEGIN CERTIFICATE-----
54
50
  * MIIBXjCCAQSgAwIBAgIGAXvykuMKMAoGCCqGSM49BAMCMDYxNDAyBgNVBAMMK3Np
@@ -60,34 +56,30 @@
60
56
  * 1yyMTRe66MhEXID9+uVub7woMkNYd0LhSHwKSPMUUTkCIFQGsfm1ecXOpeGOufAh
61
57
  * v+A1QWZMuTWqYt+uh/YSRNDn
62
58
  * -----END CERTIFICATE-----`
63
- * const ecPublicKey = await importX509(x509, algorithm)
59
+ * const ecPublicKey = await jose.importX509(x509, algorithm)
64
60
  * ```
65
61
  *
66
62
  * @example Import a PEM-encoded PKCS8 Private Key
67
63
  * ```js
68
- * import { importPKCS8 } from 'jose'
69
- *
70
64
  * const algorithm = 'ES256'
71
65
  * const pkcs8 = `-----BEGIN PRIVATE KEY-----
72
66
  * MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgiyvo0X+VQ0yIrOaN
73
67
  * nlrnUclopnvuuMfoc8HHly3505OhRANCAAQWUcdZ8uTSAsFuwtNy4KtsKqgeqYxg
74
68
  * l6kwL5D4N3pEGYGIDjV69Sw0zAt43480WqJv7HCL0mQnyqFmSrxj8jMa
75
69
  * -----END PRIVATE KEY-----`
76
- * const ecPrivateKey = await importPKCS8(pkcs8, algorithm)
70
+ * const ecPrivateKey = await jose.importPKCS8(pkcs8, algorithm)
77
71
  * ```
78
72
  *
79
73
  * @example Import a JSON Web Key (JWK)
80
74
  * ```js
81
- * import { importJWK } from 'jose'
82
- *
83
- * const ecPublicKey = await importJWK({
75
+ * const ecPublicKey = await jose.importJWK({
84
76
  * crv: 'P-256',
85
77
  * kty: 'EC',
86
78
  * x: 'ySK38C1jBdLwDsNWKzzBHqKYEE5Cgv-qjWvorUXk9fw',
87
79
  * y: '_LeQBw07cf5t57Iavn4j-BqJsAD1dpoz8gokd3sBsOo'
88
80
  * }, 'ES256')
89
81
  *
90
- * const rsaPublicKey = await importJWK({
82
+ * const rsaPublicKey = await jose.importJWK({
91
83
  * kty: 'RSA',
92
84
  * e: 'AQAB',
93
85
  * n: '12oBZRhCiZFJLcPg59LkZZ9mdhSMTKAQZYq32k_ti5SBB6jerkh-WzOMAO664r_qyLkqHUSp3u5SbXtseZEpN3XPWGKSxjsy-1JyEFTdLSYe6f9gfrmxkUF_7DTpq0gn6rntP05g2-wFW50YO7mosfdslfrTJYWHFhJALabAeYirYD7-9kqq9ebfFMF4sRRELbv9oi36As6Q9B3Qb5_C1rAzqfao_PCsf9EPsTZsVVVkA5qoIAr47lo1ipfiBPxUCCNSdvkmDTYgvvRm6ZoMjFbvOtgyts55fXKdMWv7I9HMD5HwE9uW839PWA514qhbcIsXEYSFMPMV6fnlsiZvQQ'
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jose",
3
- "version": "4.2.1",
3
+ "version": "4.3.0",
4
4
  "description": "'JSON Web Almost Everything' - JWA, JWS, JWE, JWT, JWK, JWKS with no dependencies using runtime's native crypto",
5
5
  "keywords": [
6
6
  "browser",