@zuplo/cli 6.74.2 → 6.74.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. package/dist/cmds/test.d.ts.map +1 -1
  2. package/dist/cmds/test.js +8 -0
  3. package/dist/cmds/test.js.map +1 -1
  4. package/dist/common/utils/pnpm-lifecycle.d.ts.map +1 -1
  5. package/dist/common/utils/pnpm-lifecycle.js +1 -4
  6. package/dist/common/utils/pnpm-lifecycle.js.map +1 -1
  7. package/dist/common/utils/pnpm-lifecycle.test.js +23 -4
  8. package/dist/common/utils/pnpm-lifecycle.test.js.map +1 -1
  9. package/dist/test/handler.d.ts +2 -1
  10. package/dist/test/handler.d.ts.map +1 -1
  11. package/dist/test/handler.js.map +1 -1
  12. package/dist/test/invoke-test.d.ts +3 -2
  13. package/dist/test/invoke-test.d.ts.map +1 -1
  14. package/dist/test/invoke-test.js +26 -0
  15. package/dist/test/invoke-test.js.map +1 -1
  16. package/dist/test/invoke-test.test.js +16 -0
  17. package/dist/test/invoke-test.test.js.map +1 -1
  18. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/jwe/compact/decrypt.js +2 -2
  19. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/jwe/flattened/encrypt.js +12 -12
  20. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/jwe/general/encrypt.js +50 -51
  21. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/jwks/local.js +10 -31
  22. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/jwks/remote.js +17 -26
  23. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/jws/compact/verify.js +2 -2
  24. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/jws/flattened/sign.js +1 -9
  25. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/jws/general/sign.js +12 -21
  26. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/jws/general/verify.js +13 -11
  27. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/jwt/decrypt.js +3 -3
  28. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/jwt/verify.js +4 -4
  29. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/key/export.js +3 -3
  30. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/key/generate_key_pair.js +7 -6
  31. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/lib/asn1.js +29 -62
  32. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/lib/content_encryption.js +16 -34
  33. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/lib/crypto_key.js +6 -0
  34. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/lib/invalid_key_input.js +0 -1
  35. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/lib/jwe_algorithms.js +44 -71
  36. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/lib/jwe_decrypt.js +46 -41
  37. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/lib/jwe_encrypt.js +14 -13
  38. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/lib/jwk_to_key.js +5 -10
  39. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/lib/jws_algorithms.js +20 -18
  40. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/lib/jws_sign.js +12 -6
  41. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/lib/jws_verify.js +26 -27
  42. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/lib/jwt_claims_set.js +60 -102
  43. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/lib/key.js +61 -99
  44. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/lib/key_algorithm.js +2 -8
  45. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/lib/key_descriptor.js +1 -1
  46. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/lib/key_management.js +74 -161
  47. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/lib/options.js +11 -14
  48. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/lib/signing.js +6 -16
  49. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/lib/type_checks.js +13 -18
  50. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/util/base64url.js +4 -3
  51. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/package.json +1 -1
  52. package/node_modules/@zuplo/core/package.json +1 -1
  53. package/node_modules/@zuplo/graphql/package.json +1 -1
  54. package/node_modules/@zuplo/openapi-tools/package.json +3 -3
  55. package/node_modules/@zuplo/otel/package.json +1 -1
  56. package/node_modules/@zuplo/runtime/out/esm/{chunk-B5LJC45G.js → chunk-CKGECOOJ.js} +88 -88
  57. package/node_modules/@zuplo/runtime/out/esm/chunk-CKGECOOJ.js.map +1 -0
  58. package/node_modules/@zuplo/runtime/out/esm/index.js +1 -1
  59. package/node_modules/@zuplo/runtime/out/esm/mcp-gateway/index.js +1 -1
  60. package/node_modules/@zuplo/runtime/out/types/index.d.ts +5 -1
  61. package/node_modules/@zuplo/runtime/package.json +1 -1
  62. package/package.json +6 -6
  63. package/node_modules/@zuplo/runtime/out/esm/chunk-B5LJC45G.js.map +0 -1
  64. /package/node_modules/@zuplo/runtime/out/esm/{chunk-B5LJC45G.js.LEGAL.txt → chunk-CKGECOOJ.js.LEGAL.txt} +0 -0
@@ -10,23 +10,19 @@ import { prepareKey } from '../../lib/key.js';
10
10
  import { jweAlgorithm } from '../../lib/jwe_algorithms.js';
11
11
  class IndividualRecipient {
12
12
  #parent;
13
- unprotectedHeader;
14
- keyManagementParameters;
15
- key;
16
- options;
17
- constructor(enc, key, options) {
13
+ state;
14
+ constructor(enc, key, crit) {
18
15
  this.#parent = enc;
19
- this.key = key;
20
- this.options = options;
16
+ this.state = [undefined, undefined, key, crit];
21
17
  }
22
18
  setUnprotectedHeader(unprotectedHeader) {
23
- assertNotSet(this.unprotectedHeader, 'setUnprotectedHeader');
24
- this.unprotectedHeader = unprotectedHeader;
19
+ assertNotSet(this.state[0], 'setUnprotectedHeader');
20
+ this.state[0] = unprotectedHeader;
25
21
  return this;
26
22
  }
27
23
  setKeyManagementParameters(parameters) {
28
- assertNotSet(this.keyManagementParameters, 'setKeyManagementParameters');
29
- this.keyManagementParameters = parameters;
24
+ assertNotSet(this.state[1], 'setKeyManagementParameters');
25
+ this.state[1] = parameters;
30
26
  return this;
31
27
  }
32
28
  addRecipient(...args) {
@@ -39,6 +35,17 @@ class IndividualRecipient {
39
35
  return this.#parent;
40
36
  }
41
37
  }
38
+ function copyOptionalMembers(flattened, jwe, recipient) {
39
+ const { aad, protected: protectedHeader, unprotected, header } = flattened;
40
+ if (aad)
41
+ jwe.aad = aad;
42
+ if (protectedHeader)
43
+ jwe.protected = protectedHeader;
44
+ if (unprotected)
45
+ jwe.unprotected = unprotected;
46
+ if (header)
47
+ recipient.header = header;
48
+ }
42
49
  export class GeneralEncrypt {
43
50
  #plaintext;
44
51
  #recipients = [];
@@ -49,7 +56,7 @@ export class GeneralEncrypt {
49
56
  this.#plaintext = plaintext;
50
57
  }
51
58
  addRecipient(key, options) {
52
- const recipient = new IndividualRecipient(this, key, { crit: options?.crit });
59
+ const recipient = new IndividualRecipient(this, key, options?.crit);
53
60
  this.#recipients.push(recipient);
54
61
  return recipient;
55
62
  }
@@ -76,29 +83,23 @@ export class GeneralEncrypt {
76
83
  }
77
84
  if (this.#recipients.length === 1) {
78
85
  const [recipient] = this.#recipients;
86
+ const [unprotectedHeader, keyManagementParameters, key, crit] = recipient.state;
79
87
  const flattened = await new FlattenedEncrypt(this.#plaintext)
80
88
  .setAdditionalAuthenticatedData(this.#aad)
81
89
  .setProtectedHeader(this.#protectedHeader)
82
90
  .setSharedUnprotectedHeader(this.#unprotectedHeader)
83
- .setUnprotectedHeader(recipient.unprotectedHeader)
84
- .setKeyManagementParameters(recipient.keyManagementParameters)
85
- .encrypt(recipient.key, { ...recipient.options });
91
+ .setUnprotectedHeader(unprotectedHeader)
92
+ .setKeyManagementParameters(keyManagementParameters)
93
+ .encrypt(key, { crit });
86
94
  const jwe = {
87
95
  ciphertext: flattened.ciphertext,
88
96
  iv: flattened.iv,
89
97
  recipients: [{}],
90
98
  tag: flattened.tag,
91
99
  };
92
- if (flattened.aad)
93
- jwe.aad = flattened.aad;
94
- if (flattened.protected)
95
- jwe.protected = flattened.protected;
96
- if (flattened.unprotected)
97
- jwe.unprotected = flattened.unprotected;
98
100
  if (flattened.encrypted_key)
99
101
  jwe.recipients[0].encrypted_key = flattened.encrypted_key;
100
- if (flattened.header)
101
- jwe.recipients[0].header = flattened.header;
102
+ copyOptionalMembers(flattened, jwe, jwe.recipients[0]);
102
103
  return jwe;
103
104
  }
104
105
  validateCritDuplicates(JWEInvalid, this.#protectedHeader);
@@ -107,60 +108,58 @@ export class GeneralEncrypt {
107
108
  const checked = [];
108
109
  for (let i = 0; i < this.#recipients.length; i++) {
109
110
  const recipient = this.#recipients[i];
110
- const input = {
111
- plaintext: this.#plaintext,
112
- protectedHeader: this.#protectedHeader,
113
- unprotectedHeader: recipient.unprotectedHeader,
114
- sharedUnprotectedHeader: this.#unprotectedHeader,
115
- aad: this.#aad,
116
- keyManagementParameters: recipient.keyManagementParameters,
117
- crit: recipient.options.crit,
118
- unprotectedParameters: true,
119
- };
111
+ const [unprotectedHeader, keyManagementParameters, , crit] = recipient.state;
112
+ const input = [
113
+ this.#plaintext,
114
+ this.#protectedHeader,
115
+ unprotectedHeader,
116
+ this.#unprotectedHeader,
117
+ this.#aad,
118
+ undefined,
119
+ undefined,
120
+ keyManagementParameters,
121
+ crit,
122
+ true,
123
+ ];
120
124
  const headers = checkEncryptHeaders(input);
121
125
  inputs.push(input);
122
126
  checked.push(headers);
123
- if (headers.alg === 'dir' || headers.alg === 'ECDH-ES') {
127
+ if (headers[1] === 'dir' || headers[1] === 'ECDH-ES') {
124
128
  throw new JWEInvalid('"dir" and "ECDH-ES" alg may only be used with a single recipient');
125
129
  }
126
130
  if (!enc) {
127
- enc = headers.enc;
131
+ enc = headers[2];
128
132
  }
129
- else if (enc !== headers.enc) {
133
+ else if (enc !== headers[2]) {
130
134
  throw new JWEInvalid('JWE "enc" (Encryption Algorithm) Header Parameter must be the same for all recipients');
131
135
  }
132
136
  }
133
- const cek = generateCek(checked[0].encEntry);
137
+ const cek = generateCek(checked[0][3]);
134
138
  const jwe = {
135
139
  ciphertext: '',
136
140
  recipients: [],
137
141
  };
138
142
  for (let i = 0; i < this.#recipients.length; i++) {
139
143
  const recipient = this.#recipients[i];
144
+ const [unprotectedHeader, keyManagementParameters, key] = recipient.state;
140
145
  const target = {};
141
146
  jwe.recipients.push(target);
142
147
  if (i === 0) {
143
- const flattened = await encryptJWE({ ...inputs[0], cek }, checked[0], recipient.key);
148
+ inputs[0][5] = cek;
149
+ const flattened = await encryptJWE(inputs[0], checked[0], key);
144
150
  jwe.ciphertext = flattened.ciphertext;
145
151
  jwe.iv = flattened.iv;
146
152
  jwe.tag = flattened.tag;
147
- if (flattened.aad)
148
- jwe.aad = flattened.aad;
149
- if (flattened.protected)
150
- jwe.protected = flattened.protected;
151
- if (flattened.unprotected)
152
- jwe.unprotected = flattened.unprotected;
153
153
  target.encrypted_key = flattened.encrypted_key;
154
- if (flattened.header)
155
- target.header = flattened.header;
154
+ copyOptionalMembers(flattened, jwe, target);
156
155
  continue;
157
156
  }
158
- const { alg } = checked[i];
159
- const k = await prepareKey(jweAlgorithm(alg), recipient.key, 'encrypt');
160
- const { encryptedKey, parameters } = await encryptKeyManagement(alg, checked[i].encEntry, k, cek, recipient.keyManagementParameters);
157
+ const [, alg, , encEntry] = checked[i];
158
+ const k = await prepareKey(jweAlgorithm(alg), key, 'encrypt');
159
+ const [, encryptedKey, parameters] = await encryptKeyManagement(alg, encEntry, k, cek, keyManagementParameters);
161
160
  target.encrypted_key = b64u(encryptedKey);
162
- if (recipient.unprotectedHeader || parameters)
163
- target.header = { ...recipient.unprotectedHeader, ...parameters };
161
+ if (unprotectedHeader || parameters)
162
+ target.header = { ...unprotectedHeader, ...parameters };
164
163
  }
165
164
  return jwe;
166
165
  }
@@ -4,7 +4,7 @@ import { JWKSInvalid, JOSENotSupported, JWKSNoMatchingKey, JWKSMultipleMatchingK
4
4
  import { isObject } from '../lib/type_checks.js';
5
5
  function signatureAlgorithm(alg) {
6
6
  const entry = typeof alg === 'string' ? maybeJWSAlgorithm(alg) : undefined;
7
- if (!entry || entry.symmetric) {
7
+ if (!entry || entry.secret) {
8
8
  throw new JOSENotSupported('Unsupported "alg" value for a JSON Web Key Set');
9
9
  }
10
10
  return entry;
@@ -14,10 +14,7 @@ function isJWKSLike(jwks) {
14
14
  return false;
15
15
  }
16
16
  const { keys } = jwks;
17
- return Array.isArray(keys) && keys.every(isJWKLike);
18
- }
19
- function isJWKLike(key) {
20
- return isObject(key);
17
+ return Array.isArray(keys) && keys.every((isObject));
21
18
  }
22
19
  class LocalJWKSetImpl {
23
20
  #jwks;
@@ -34,25 +31,12 @@ class LocalJWKSetImpl {
34
31
  async getKey(protectedHeader, token) {
35
32
  const { alg, kid } = { ...protectedHeader, ...token?.header };
36
33
  const entry = signatureAlgorithm(alg);
37
- const candidates = this.#jwks.keys.filter((jwk) => {
38
- let candidate = entry.kty.includes(jwk.kty);
39
- if (candidate && typeof kid === 'string') {
40
- candidate = kid === jwk.kid;
41
- }
42
- if (candidate && (typeof jwk.alg === 'string' || jwk.kty === 'AKP')) {
43
- candidate = alg === jwk.alg;
44
- }
45
- if (candidate && typeof jwk.use === 'string') {
46
- candidate = jwk.use === 'sig';
47
- }
48
- if (candidate && Array.isArray(jwk.key_ops)) {
49
- candidate = jwk.key_ops.includes('verify');
50
- }
51
- if (candidate && entry.crv) {
52
- candidate = jwk.crv === entry.crv;
53
- }
54
- return candidate;
55
- });
34
+ const candidates = this.#jwks.keys.filter((jwk) => entry.kty.includes(jwk.kty) &&
35
+ (typeof kid !== 'string' || kid === jwk.kid) &&
36
+ (!(typeof jwk.alg === 'string' || jwk.kty === 'AKP') || alg === jwk.alg) &&
37
+ (typeof jwk.use !== 'string' || jwk.use === 'sig') &&
38
+ (!Array.isArray(jwk.key_ops) || jwk.key_ops.includes('verify')) &&
39
+ (!entry.crv || jwk.crv === entry.crv));
56
40
  const { 0: jwk, length } = candidates;
57
41
  if (length === 0) {
58
42
  throw new JWKSNoMatchingKey();
@@ -87,13 +71,8 @@ async function importWithAlgCache(cache, jwk, entry) {
87
71
  export function createLocalJWKSet(jwks) {
88
72
  const set = new LocalJWKSetImpl(jwks);
89
73
  const localJWKSet = async (protectedHeader, token) => set.getKey(protectedHeader, token);
90
- Object.defineProperties(localJWKSet, {
91
- jwks: {
92
- value: () => structuredClone(set.jwks()),
93
- enumerable: false,
94
- configurable: false,
95
- writable: false,
96
- },
74
+ Object.defineProperty(localJWKSet, 'jwks', {
75
+ value: () => structuredClone(set.jwks()),
97
76
  });
98
77
  return localJWKSet;
99
78
  }
@@ -9,7 +9,7 @@ function isCloudflareWorkers() {
9
9
  let USER_AGENT;
10
10
  if (typeof navigator === 'undefined' || !navigator.userAgent?.startsWith?.('Mozilla/5.0 ')) {
11
11
  const NAME = 'jose';
12
- const VERSION = 'v6.2.6';
12
+ const VERSION = 'v6.2.7';
13
13
  USER_AGENT = `${NAME}/${VERSION}`;
14
14
  }
15
15
  export const customFetch = Symbol();
@@ -67,12 +67,12 @@ class RemoteJWKSetImpl {
67
67
  throw new TypeError('url must be an instance of URL');
68
68
  }
69
69
  this.#url = new URL(url.href);
70
- this.#timeoutDuration =
71
- typeof options?.timeoutDuration === 'number' ? options?.timeoutDuration : 5000;
70
+ const opts = options ?? {};
71
+ this.#timeoutDuration = typeof opts.timeoutDuration === 'number' ? opts.timeoutDuration : 5000;
72
72
  this.#cooldownDuration =
73
- typeof options?.cooldownDuration === 'number' ? options?.cooldownDuration : 30000;
74
- this.#cacheMaxAge = typeof options?.cacheMaxAge === 'number' ? options?.cacheMaxAge : 600000;
75
- this.#headers = new Headers(options?.headers);
73
+ typeof opts.cooldownDuration === 'number' ? opts.cooldownDuration : 30000;
74
+ this.#cacheMaxAge = typeof opts.cacheMaxAge === 'number' ? opts.cacheMaxAge : 600000;
75
+ this.#headers = new Headers(opts.headers);
76
76
  if (USER_AGENT && !this.#headers.has('User-Agent')) {
77
77
  this.#headers.set('User-Agent', USER_AGENT);
78
78
  }
@@ -80,10 +80,11 @@ class RemoteJWKSetImpl {
80
80
  this.#headers.set('accept', 'application/json');
81
81
  this.#headers.append('accept', 'application/jwk-set+json');
82
82
  }
83
- this.#customFetch = options?.[customFetch];
84
- if (options?.[jwksCache] !== undefined) {
85
- this.#cache = options?.[jwksCache];
86
- if (isFreshJwksCache(options?.[jwksCache], this.#cacheMaxAge)) {
83
+ this.#customFetch = opts[customFetch];
84
+ const cache = opts[jwksCache];
85
+ if (cache !== undefined) {
86
+ this.#cache = cache;
87
+ if (isFreshJwksCache(cache, this.#cacheMaxAge)) {
87
88
  this.#jwksTimestamp = this.#cache.uat;
88
89
  this.#local = createLocalJWKSet(this.#cache.jwks);
89
90
  }
@@ -92,15 +93,14 @@ class RemoteJWKSetImpl {
92
93
  pendingFetch() {
93
94
  return !!this.#pendingFetch;
94
95
  }
96
+ #validFor(duration) {
97
+ return typeof this.#jwksTimestamp === 'number' && Date.now() < this.#jwksTimestamp + duration;
98
+ }
95
99
  coolingDown() {
96
- return typeof this.#jwksTimestamp === 'number'
97
- ? Date.now() < this.#jwksTimestamp + this.#cooldownDuration
98
- : false;
100
+ return this.#validFor(this.#cooldownDuration);
99
101
  }
100
102
  fresh() {
101
- return typeof this.#jwksTimestamp === 'number'
102
- ? Date.now() < this.#jwksTimestamp + this.#cacheMaxAge
103
- : false;
103
+ return this.#validFor(this.#cacheMaxAge);
104
104
  }
105
105
  jwks() {
106
106
  return this.#local?.jwks();
@@ -134,11 +134,9 @@ class RemoteJWKSetImpl {
134
134
  this.#cache.jwks = json;
135
135
  }
136
136
  this.#jwksTimestamp = Date.now();
137
- this.#pendingFetch = undefined;
138
137
  })
139
- .catch((err) => {
138
+ .finally(() => {
140
139
  this.#pendingFetch = undefined;
141
- throw err;
142
140
  });
143
141
  await this.#pendingFetch;
144
142
  }
@@ -150,29 +148,22 @@ export function createRemoteJWKSet(url, options) {
150
148
  coolingDown: {
151
149
  get: () => set.coolingDown(),
152
150
  enumerable: true,
153
- configurable: false,
154
151
  },
155
152
  fresh: {
156
153
  get: () => set.fresh(),
157
154
  enumerable: true,
158
- configurable: false,
159
155
  },
160
156
  reload: {
161
157
  value: () => set.reload(),
162
158
  enumerable: true,
163
- configurable: false,
164
- writable: false,
165
159
  },
166
160
  reloading: {
167
161
  get: () => set.pendingFetch(),
168
162
  enumerable: true,
169
- configurable: false,
170
163
  },
171
164
  jwks: {
172
165
  value: () => set.jwks(),
173
166
  enumerable: true,
174
- configurable: false,
175
- writable: false,
176
167
  },
177
168
  });
178
169
  return remoteJWKSet;
@@ -1,9 +1,9 @@
1
1
  import { prepareVerify, verifyCompact } from '../../lib/jws_verify.js';
2
2
  export async function compactVerify(jws, key, options) {
3
3
  const verified = await verifyCompact(jws, prepareVerify(options), key);
4
- const result = { payload: verified.payload, protectedHeader: verified.parsedProt };
4
+ const result = { payload: verified[0], protectedHeader: verified[1] };
5
5
  if (typeof key === 'function') {
6
- return { ...result, key: verified.key };
6
+ return { ...result, key: verified[3] };
7
7
  }
8
8
  return result;
9
9
  }
@@ -1,4 +1,3 @@
1
- import { JWSInvalid } from '../../util/errors.js';
2
1
  import { createSignature } from '../../lib/jws_sign.js';
3
2
  import { assertNotSet } from '../../lib/helpers.js';
4
3
  export class FlattenedSign {
@@ -22,18 +21,11 @@ export class FlattenedSign {
22
21
  return this;
23
22
  }
24
23
  async sign(key, options) {
25
- if (!this.#protectedHeader && !this.#unprotectedHeader) {
26
- throw new JWSInvalid('either setProtectedHeader or setUnprotectedHeader must be called before #sign()');
27
- }
28
- const jws = await createSignature({
24
+ return createSignature({
29
25
  payload: this.#payload,
30
26
  protectedHeader: this.#protectedHeader,
31
27
  unprotectedHeader: this.#unprotectedHeader,
32
28
  crit: options?.crit,
33
29
  }, key);
34
- if (this.#unprotectedHeader) {
35
- jws.header = this.#unprotectedHeader;
36
- }
37
- return jws;
38
30
  }
39
31
  }
@@ -3,23 +3,19 @@ import { JWSInvalid } from '../../util/errors.js';
3
3
  import { assertNotSet } from '../../lib/helpers.js';
4
4
  class IndividualSignature {
5
5
  #parent;
6
- protectedHeader;
7
- unprotectedHeader;
8
- options;
9
- key;
6
+ state;
10
7
  constructor(sig, key, options) {
11
8
  this.#parent = sig;
12
- this.key = key;
13
- this.options = options;
9
+ this.state = [undefined, undefined, key, options?.crit];
14
10
  }
15
11
  setProtectedHeader(protectedHeader) {
16
- assertNotSet(this.protectedHeader, 'setProtectedHeader');
17
- this.protectedHeader = protectedHeader;
12
+ assertNotSet(this.state[0], 'setProtectedHeader');
13
+ this.state[0] = protectedHeader;
18
14
  return this;
19
15
  }
20
16
  setUnprotectedHeader(unprotectedHeader) {
21
- assertNotSet(this.unprotectedHeader, 'setUnprotectedHeader');
22
- this.unprotectedHeader = unprotectedHeader;
17
+ assertNotSet(this.state[1], 'setUnprotectedHeader');
18
+ this.state[1] = unprotectedHeader;
23
19
  return this;
24
20
  }
25
21
  addSignature(...args) {
@@ -54,22 +50,17 @@ export class GeneralSign {
54
50
  signatures: [],
55
51
  payload: '',
56
52
  };
57
- const encoded = {};
53
+ const encoded = [];
58
54
  for (let i = 0; i < this.#signatures.length; i++) {
59
55
  const signature = this.#signatures[i];
60
- if (!signature.protectedHeader && !signature.unprotectedHeader) {
61
- throw new JWSInvalid('either setProtectedHeader or setUnprotectedHeader must be called before #sign()');
62
- }
56
+ const [protectedHeader, unprotectedHeader, key, crit] = signature.state;
63
57
  const { payload, ...rest } = await createSignature({
64
58
  payload: this.#payload,
65
- protectedHeader: signature.protectedHeader,
66
- unprotectedHeader: signature.unprotectedHeader,
67
- crit: signature.options?.crit,
59
+ protectedHeader,
60
+ unprotectedHeader,
61
+ crit,
68
62
  encoded,
69
- }, signature.key);
70
- if (signature.unprotectedHeader) {
71
- rest.header = signature.unprotectedHeader;
72
- }
63
+ }, key);
73
64
  if (i === 0) {
74
65
  jws.payload = payload;
75
66
  }
@@ -5,34 +5,36 @@ export async function generalVerify(jws, key, options) {
5
5
  if (!isObject(jws)) {
6
6
  throw new JWSInvalid('General JWS must be an object');
7
7
  }
8
- if (!Array.isArray(jws.signatures) || !jws.signatures.every(isObject)) {
8
+ const { signatures, payload } = jws;
9
+ if (!Array.isArray(signatures) || !signatures.every(isObject)) {
9
10
  throw new JWSInvalid('JWS Signatures missing or incorrect type');
10
11
  }
11
12
  let shared;
12
13
  try {
13
- if (jws.payload === undefined)
14
+ if (payload === undefined)
14
15
  throw new Error();
15
16
  shared = prepareVerify(options);
16
17
  }
17
18
  catch {
18
19
  throw new JWSSignatureVerificationFailed();
19
20
  }
20
- for (const signature of jws.signatures) {
21
+ for (const signature of signatures) {
21
22
  try {
22
- if (signature.protected === undefined && signature.header === undefined)
23
+ const { protected: encodedProtected, header, signature: encodedSignature } = signature;
24
+ if (encodedProtected === undefined && header === undefined)
23
25
  throw new Error();
24
- if (signature.protected !== undefined && typeof signature.protected !== 'string') {
26
+ if (encodedProtected !== undefined && typeof encodedProtected !== 'string') {
25
27
  throw new Error();
26
28
  }
27
- if (typeof signature.signature !== 'string')
29
+ if (typeof encodedSignature !== 'string')
28
30
  throw new Error();
29
- if (signature.header !== undefined && !isObject(signature.header))
31
+ if (header !== undefined && !isObject(header))
30
32
  throw new Error();
31
33
  return verifyResult(signature, await verifySignature({
32
- header: signature.header,
33
- payload: jws.payload,
34
- protected: signature.protected,
35
- signature: signature.signature,
34
+ header,
35
+ payload,
36
+ protected: encodedProtected,
37
+ signature: encodedSignature,
36
38
  }, shared, key));
37
39
  }
38
40
  catch {
@@ -3,8 +3,8 @@ import { validateClaimsSet } from '../lib/jwt_claims_set.js';
3
3
  import { JWTClaimValidationFailed } from '../util/errors.js';
4
4
  export async function jwtDecrypt(jwt, key, options) {
5
5
  const decrypted = await decryptCompact(jwt, prepareDecrypt(options), key);
6
- const protectedHeader = decrypted.parsedProt;
7
- const payload = validateClaimsSet(protectedHeader, decrypted.plaintext, options);
6
+ const protectedHeader = decrypted[1];
7
+ const payload = validateClaimsSet(protectedHeader, decrypted[0], options);
8
8
  if (protectedHeader.iss !== undefined && protectedHeader.iss !== payload.iss) {
9
9
  throw new JWTClaimValidationFailed('replicated "iss" claim header parameter mismatch', payload, 'iss', 'mismatch');
10
10
  }
@@ -17,7 +17,7 @@ export async function jwtDecrypt(jwt, key, options) {
17
17
  }
18
18
  const result = { payload, protectedHeader };
19
19
  if (typeof key === 'function') {
20
- return { ...result, key: decrypted.key };
20
+ return { ...result, key: decrypted[2] };
21
21
  }
22
22
  return result;
23
23
  }
@@ -3,13 +3,13 @@ import { validateClaimsSet } from '../lib/jwt_claims_set.js';
3
3
  import { JWTInvalid } from '../util/errors.js';
4
4
  export async function jwtVerify(jwt, key, options) {
5
5
  const verified = await verifyCompact(jwt, prepareVerify(options), key);
6
- if (!verified.b64) {
6
+ if (!verified[2]) {
7
7
  throw new JWTInvalid('JWTs MUST NOT use unencoded payload');
8
8
  }
9
- const payload = validateClaimsSet(verified.parsedProt, verified.payload, options);
10
- const result = { payload, protectedHeader: verified.parsedProt };
9
+ const payload = validateClaimsSet(verified[1], verified[0], options);
10
+ const result = { payload, protectedHeader: verified[1] };
11
11
  if (typeof key === 'function') {
12
- return { ...result, key: verified.key };
12
+ return { ...result, key: verified[3] };
13
13
  }
14
14
  return result;
15
15
  }
@@ -33,12 +33,12 @@ async function keyToJWK(key) {
33
33
  }
34
34
  return jwk;
35
35
  }
36
- export async function exportSPKI(key) {
36
+ export function exportSPKI(key) {
37
37
  return exportPublic(key);
38
38
  }
39
- export async function exportPKCS8(key) {
39
+ export function exportPKCS8(key) {
40
40
  return exportPrivate(key);
41
41
  }
42
- export async function exportJWK(key) {
42
+ export function exportJWK(key) {
43
43
  return keyToJWK(key);
44
44
  }
@@ -9,16 +9,17 @@ function getModulusLengthOption(options) {
9
9
  }
10
10
  export async function generateKeyPair(alg, options) {
11
11
  const entry = keyAlgorithm(alg);
12
- if (entry.symmetric) {
12
+ if (entry.secret) {
13
13
  throw new JOSENotSupported('Invalid or unsupported JWK "alg" (Algorithm) Parameter value');
14
14
  }
15
15
  let algorithm;
16
- if (entry.subtleFor) {
17
- switch (options?.crv ?? 'P-256') {
16
+ if (entry.resolve) {
17
+ const crv = options?.crv ?? 'P-256';
18
+ switch (crv) {
18
19
  case 'P-256':
19
20
  case 'P-384':
20
21
  case 'P-521':
21
- algorithm = { name: 'ECDH', namedCurve: options?.crv ?? 'P-256' };
22
+ algorithm = { name: 'ECDH', namedCurve: crv };
22
23
  break;
23
24
  case 'X25519':
24
25
  algorithm = { name: 'X25519' };
@@ -41,7 +42,7 @@ export async function generateKeyPair(alg, options) {
41
42
  : entry.subtle;
42
43
  }
43
44
  return crypto.subtle.generateKey(algorithm, options?.extractable ?? false, [
44
- ...entry.usages.private,
45
- ...entry.usages.public,
45
+ ...entry.usages[1],
46
+ ...entry.usages[0],
46
47
  ]);
47
48
  }