unjwt 0.7.0 → 0.7.2

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.
@@ -27,8 +27,12 @@ type JWKLookupFunctionHeader = {
27
27
  *
28
28
  * Returning a `string` is meaningful for JWE only (PBES2 password); for JWS
29
29
  * a string return is encoded to bytes and used as a raw symmetric key.
30
+ *
31
+ * The optional `TReturn` generic lets callers who always hand back a specific
32
+ * key shape (e.g. a `JWK_EC_Public<"ES256">`) preserve that narrowing all the
33
+ * way into the `verify` / `decrypt` key resolution path.
30
34
  */
31
- type JWKLookupFunction = (header: JWKLookupFunctionHeader, token: string) => CryptoKey | JWK | JWKSet | string | Uint8Array<ArrayBuffer> | Promise<CryptoKey | JWK | JWKSet | string | Uint8Array<ArrayBuffer>>;
35
+ type JWKLookupFunction<TReturn = CryptoKey | JWK | JWKSet | string | Uint8Array<ArrayBuffer>> = (header: JWKLookupFunctionHeader, token: string) => TReturn | Promise<TReturn>;
32
36
  /**
33
37
  * Interface for custom JWK import cache implementations.
34
38
  *
@@ -62,7 +66,12 @@ type GenerateKeyAlgorithm = Exclude<JWKAlgorithm, "none" | "dir" | JWK_PBES2>;
62
66
  interface GenerateKeyOptions {
63
67
  /** Key usages for the generated key(s). Note: For composite keys (CBC), default usages are applied separately. */
64
68
  keyUsage?: KeyUsage[];
65
- /** Mark the key(s) as extractable. Defaults to true. */
69
+ /**
70
+ * Mark the key(s) as extractable. Defaults to true. Ignored when `toJWK` is set —
71
+ * the JWK output requires exporting the intermediate key. For long-lived asymmetric
72
+ * private keys that should never leave the runtime, prefer `false` (and omit `toJWK`):
73
+ * the key still signs/decrypts but its material cannot be exported.
74
+ */
66
75
  extractable?: boolean;
67
76
  /** RSA modulus length. Defaults to 2048. */
68
77
  modulusLength?: number;
@@ -77,25 +86,10 @@ interface GenerateKeyOptions {
77
86
  */
78
87
  toJWK?: boolean;
79
88
  }
80
- type GenerateKeyReturnJWK<TAlg extends GenerateKeyAlgorithm> = TAlg extends JWK_Asymmetric_Algorithm ? TAlg extends JWK_RSA_SIGN | JWK_RSA_PSS | JWK_RSA_ENC ? {
81
- privateKey: JWK_RSA_Private;
82
- publicKey: JWK_RSA_Public;
83
- } : TAlg extends JWK_ECDSA ? {
84
- privateKey: JWK_EC_Private;
85
- publicKey: JWK_EC_Public;
86
- } : TAlg extends JWK_ECDH_ES ? {
87
- privateKey: JWK_EC_Private;
88
- publicKey: JWK_EC_Public;
89
- } | {
90
- privateKey: JWK_OKP_Private;
91
- publicKey: JWK_OKP_Public;
92
- } : TAlg extends JWK_OKP_SIGN ? {
93
- privateKey: JWK_OKP_Private;
94
- publicKey: JWK_OKP_Public;
95
- } : never : TAlg extends JWK_AES_CBC_HMAC | JWK_Symmetric_Algorithm ? JWK_oct : never;
89
+ type GenerateKeyReturnJWK<TAlg extends GenerateKeyAlgorithm> = TAlg extends JWK_Asymmetric_Algorithm ? JWK_Pair<TAlg> : TAlg extends JWK_AES_CBC_HMAC | JWK_Symmetric_Algorithm ? JWK_oct<TAlg> : never;
96
90
  type GenerateKeyReturnCrypto<TAlg extends GenerateKeyAlgorithm> = TAlg extends JWK_AES_CBC_HMAC ? Uint8Array<ArrayBuffer> : TAlg extends JWK_Asymmetric_Algorithm ? CryptoKeyPair : CryptoKey;
97
91
  type GenerateKeyReturn<TAlg extends GenerateKeyAlgorithm, TOptions extends GenerateKeyOptions> = TOptions["toJWK"] extends true ? GenerateKeyReturnJWK<TAlg> : GenerateKeyReturnCrypto<TAlg>;
98
- type GenerateJWKOptions = Omit<GenerateKeyOptions, "toJWK">;
92
+ type GenerateJWKOptions = Omit<GenerateKeyOptions, "toJWK" | "extractable">;
99
93
  type GenerateJWKReturn<TAlg extends GenerateKeyAlgorithm> = GenerateKeyReturnJWK<TAlg>;
100
94
  /** Options for the deriveKeyFromPassword function. */
101
95
  interface DeriveKeyOptions {
@@ -105,7 +99,7 @@ interface DeriveKeyOptions {
105
99
  iterations: number;
106
100
  /** Key usages for the derived key. Defaults to ["wrapKey", "unwrapKey"]. */
107
101
  keyUsage?: KeyUsage[];
108
- /** Mark the derived key as extractable. Defaults to false. */
102
+ /** Mark the derived key as extractable. Defaults to false. Ignored when `toJWK` is set — the JWK output requires exporting the derived key. */
109
103
  extractable?: boolean;
110
104
  /**
111
105
  * Export the derived key as JWK_oct. When `true`, returns the derived key in
@@ -114,12 +108,38 @@ interface DeriveKeyOptions {
114
108
  */
115
109
  toJWK?: boolean;
116
110
  }
117
- type DeriveKeyReturn<TOptions extends DeriveKeyOptions> = TOptions["toJWK"] extends true ? JWK_oct : TOptions["toJWK"] extends object ? JWK_oct : CryptoKey;
111
+ /** PBES2 → AES-KW alg that ends up stamped on the derived JWK's `alg`. */
112
+ type DerivedJWKAlg<TAlg extends JWK_PBES2> = TAlg extends "PBES2-HS256+A128KW" ? "A128KW" : TAlg extends "PBES2-HS384+A192KW" ? "A192KW" : TAlg extends "PBES2-HS512+A256KW" ? "A256KW" : JWK_AES_KW;
113
+ type DeriveKeyReturn<TOptions extends DeriveKeyOptions, TAlg extends JWK_PBES2 = JWK_PBES2> = TOptions["toJWK"] extends true ? JWK_oct<DerivedJWKAlg<TAlg>> : TOptions["toJWK"] extends object ? JWK_oct<DerivedJWKAlg<TAlg>> : CryptoKey;
118
114
  type KeyManagementAlgorithm = JWK_RSA_ENC | JWK_AES_KW | JWK_AES_GCM | JWK_AES_GCM_KW | JWK_PBES2 | JWK_ECDH_ES | "dir";
119
115
  type ContentEncryptionAlgorithm = JWK_AES_GCM | JWK_AES_CBC_HMAC;
116
+ /**
117
+ * Keys admissible as the `wrappingKey` argument of {@link wrapKey}, narrowed
118
+ * by the key management algorithm. Mirrors the runtime branches in
119
+ * `jwk.wrapKey` and the inference in `inferJWEAllowedAlgorithms`.
120
+ *
121
+ * - `dir` accepts any symmetric JWK (the key _is_ the CEK).
122
+ * - AES-GCMKW tolerates a JWK whose `alg` is the bare `A*GCM` counterpart —
123
+ * matches the `jweAlgsFromOctJWK` aliasing rule.
124
+ */
125
+ type WrappingKeyFor<A extends KeyManagementAlgorithm> = A extends JWK_RSA_ENC ? CryptoKey | JWK_RSA_Public<A> : A extends JWK_ECDH_ES ? CryptoKey | JWK_EC_Public<A> | JWK_OKP_Public<A> : A extends JWK_PBES2 ? string | Uint8Array<ArrayBuffer> | JWK_oct<A> : A extends JWK_AES_KW ? CryptoKey | JWK_oct<A> : A extends JWK_AES_GCM_KW ? CryptoKey | JWK_oct<A | `A${"128" | "192" | "256"}GCM`> : A extends "dir" ? CryptoKey | JWK_oct | Uint8Array<ArrayBuffer> : never;
126
+ /**
127
+ * Keys admissible as the `unwrappingKey` argument of {@link unwrapKey}.
128
+ * The private-side counterpart of {@link WrappingKeyFor} — symmetric branches
129
+ * are identical; asymmetric branches use the `_Private` variants.
130
+ */
131
+ type UnwrappingKeyFor<A extends KeyManagementAlgorithm> = A extends JWK_RSA_ENC ? CryptoKey | JWK_RSA_Private<A> : A extends JWK_ECDH_ES ? CryptoKey | JWK_EC_Private<A> | JWK_OKP_Private<A> : A extends JWK_PBES2 ? string | Uint8Array<ArrayBuffer> | JWK_oct<A> : A extends JWK_AES_KW ? CryptoKey | JWK_oct<A> : A extends JWK_AES_GCM_KW ? CryptoKey | JWK_oct<A | `A${"128" | "192" | "256"}GCM`> : A extends "dir" ? CryptoKey | JWK_oct | Uint8Array<ArrayBuffer> : never;
120
132
  /** Options for the wrapKey function. */
121
133
  interface WrapKeyOptions {
122
- /** Initialization Vector for AES-GCMKW. Generated if not provided. */
134
+ /**
135
+ * Initialization Vector for AES-GCMKW. A fresh random IV is generated when
136
+ * not provided — production code should always omit this option.
137
+ *
138
+ * **Never reuse an IV and never derive it from external input.** A single
139
+ * IV reused under the same wrapping key breaks AES-GCM entirely (plaintext
140
+ * recovery and forgery). Provided only for tests and reproduction of known
141
+ * vectors in security research.
142
+ */
123
143
  iv?: Uint8Array<ArrayBuffer>;
124
144
  /** PBES2 Salt value (p2s). Required for PBES2 algorithms. */
125
145
  p2s?: Uint8Array<ArrayBuffer>;
@@ -211,8 +231,15 @@ interface UnwrapKeyOptions {
211
231
  * Copyright (c) 2018 Filip Skokan.
212
232
  * LICENSE: https://github.com/panva/jose/blob/v6.0.10/LICENSE.md
213
233
  */
214
- /** Generic JSON Web Key Parameters. */
215
- interface JWKParameters {
234
+ /**
235
+ * Generic JSON Web Key Parameters.
236
+ *
237
+ * The `Alg` type parameter constrains the JWK's `alg` field. Each concrete JWK
238
+ * interface below tightens `Alg` to the algorithm family admissible for that key
239
+ * type — e.g. a `JWK_oct<JWK_HMAC>` can only hold `"HS256" | "HS384" | "HS512"`
240
+ * in `alg`.
241
+ */
242
+ interface JWKParameters<Alg extends string = string> {
216
243
  /** JWK "kty" (Key Type) Parameter */
217
244
  kty: string;
218
245
  /**
@@ -220,7 +247,7 @@ interface JWKParameters {
220
247
  *
221
248
  * @see {@link https://github.com/panva/jose/issues/210 Algorithm Key Requirements}
222
249
  */
223
- alg?: string;
250
+ alg?: Alg;
224
251
  /** JWK "key_ops" (Key Operations) Parameter */
225
252
  key_ops?: KeyUsage[];
226
253
  /** JWK "ext" (Extractable) Parameter */
@@ -245,7 +272,7 @@ interface JWKParameters {
245
272
  enc?: ContentEncryptionAlgorithm;
246
273
  }
247
274
  /** Public EC JSON Web Keys */
248
- interface JWK_EC_Public extends JWKParameters {
275
+ interface JWK_EC_Public<Alg extends JWK_ECDSA | JWK_ECDH_ES | (string & {}) = string> extends JWKParameters<Alg> {
249
276
  /** EC JWK "kty" (Key Type) Parameter */
250
277
  kty: "EC";
251
278
  /** EC JWK "crv" (Curve) Parameter */
@@ -256,14 +283,14 @@ interface JWK_EC_Public extends JWKParameters {
256
283
  y: string;
257
284
  }
258
285
  /** Private EC JSON Web Keys */
259
- interface JWK_EC_Private extends JWK_EC_Public {
286
+ interface JWK_EC_Private<Alg extends JWK_ECDSA | JWK_ECDH_ES | (string & {}) = string> extends JWK_EC_Public<Alg> {
260
287
  /** EC JWK "d" (ECC Private Key) Parameter */
261
288
  d: string;
262
289
  }
263
290
  /** EC JSON Web Keys */
264
- type JWK_EC = JWK_EC_Public | JWK_EC_Private;
291
+ type JWK_EC<Alg extends JWK_ECDSA | JWK_ECDH_ES | (string & {}) = string> = JWK_EC_Public<Alg> | JWK_EC_Private<Alg>;
265
292
  /** Public RSA JSON Web Keys */
266
- interface JWK_RSA_Public extends JWKParameters {
293
+ interface JWK_RSA_Public<Alg extends JWK_RSA_SIGN | JWK_RSA_PSS | JWK_RSA_ENC | (string & {}) = string> extends JWKParameters<Alg> {
267
294
  /** RSA JWK "kty" (Key Type) Parameter */
268
295
  kty: "RSA";
269
296
  /** RSA JWK "e" (Exponent) Parameter */
@@ -273,7 +300,7 @@ interface JWK_RSA_Public extends JWKParameters {
273
300
  oth?: RsaOtherPrimesInfo[];
274
301
  }
275
302
  /** Private RSA JSON Web Keys */
276
- interface JWK_RSA_Private extends JWK_RSA_Public {
303
+ interface JWK_RSA_Private<Alg extends JWK_RSA_SIGN | JWK_RSA_PSS | JWK_RSA_ENC | (string & {}) = string> extends JWK_RSA_Public<Alg> {
277
304
  /** RSA JWK "d" (Private Exponent) Parameter */
278
305
  d: string;
279
306
  /** RSA JWK "dp" (First Factor CRT Exponent) Parameter */
@@ -288,9 +315,9 @@ interface JWK_RSA_Private extends JWK_RSA_Public {
288
315
  qi: string;
289
316
  }
290
317
  /** RSA JSON Web Keys */
291
- type JWK_RSA = JWK_RSA_Public | JWK_RSA_Private;
318
+ type JWK_RSA<Alg extends JWK_RSA_SIGN | JWK_RSA_PSS | JWK_RSA_ENC | (string & {}) = string> = JWK_RSA_Public<Alg> | JWK_RSA_Private<Alg>;
292
319
  /** Public ED JSON Web Keys */
293
- interface JWK_OKP_Public extends JWKParameters {
320
+ interface JWK_OKP_Public<Alg extends JWK_OKP_SIGN | JWK_ECDH_ES | (string & {}) = string> extends JWKParameters<Alg> {
294
321
  /** ED JWK "kty" (Key Type) Parameter */
295
322
  kty: "OKP";
296
323
  /** ED JWK "crv" (Curve) Parameter */
@@ -299,48 +326,78 @@ interface JWK_OKP_Public extends JWKParameters {
299
326
  x: string;
300
327
  }
301
328
  /** Private ED JSON Web Keys */
302
- interface JWK_OKP_Private extends JWK_OKP_Public {
329
+ interface JWK_OKP_Private<Alg extends JWK_OKP_SIGN | JWK_ECDH_ES | (string & {}) = string> extends JWK_OKP_Public<Alg> {
303
330
  /** ED JWK "d" (Private Key) Parameter */
304
331
  d: string;
305
332
  }
306
333
  /** OKP JSON Web Keys */
307
- type JWK_OKP = JWK_OKP_Public | JWK_OKP_Private;
334
+ type JWK_OKP<Alg extends JWK_OKP_SIGN | JWK_ECDH_ES | (string & {}) = string> = JWK_OKP_Public<Alg> | JWK_OKP_Private<Alg>;
308
335
  /** oct JSON Web Keys */
309
- interface JWK_oct extends JWKParameters {
336
+ interface JWK_oct<Alg extends JWK_HMAC | JWK_AES_KW | JWK_AES_GCM | JWK_AES_GCM_KW | JWK_AES_CBC_HMAC | JWK_PBES2 | "dir" | (string & {}) = string> extends JWKParameters<Alg> {
310
337
  /** Oct JWK "k" (Key Value) Parameter */
311
338
  k: string;
312
339
  }
313
340
  /** Symmetric JSON Web Keys */
314
- type JWK_Symmetric = JWK_oct;
341
+ type JWK_Symmetric<Alg extends JWK_HMAC | JWK_AES_KW | JWK_AES_GCM | JWK_AES_GCM_KW | JWK_AES_CBC_HMAC | JWK_PBES2 | "dir" | (string & {}) = string> = JWK_oct<Alg>;
315
342
  /** Asymmetric JSON Web Keys */
316
- type JWK_Asymmetric = JWK_RSA | JWK_EC | JWK_OKP;
343
+ type JWK_Asymmetric<Alg extends string = string> = JWK_RSA<Alg> | JWK_EC<Alg> | JWK_OKP<Alg>;
317
344
  /** Public JSON Web Keys */
318
- type JWK_Public = JWK_RSA_Public | JWK_EC_Public | JWK_OKP_Public;
345
+ type JWK_Public<Alg extends string = string> = JWK_RSA_Public<Alg> | JWK_EC_Public<Alg> | JWK_OKP_Public<Alg>;
319
346
  /** Private JSON Web Keys */
320
- type JWK_Private = JWK_RSA_Private | JWK_EC_Private | JWK_OKP_Private;
347
+ type JWK_Private<Alg extends string = string> = JWK_RSA_Private<Alg> | JWK_EC_Private<Alg> | JWK_OKP_Private<Alg>;
321
348
  /**
322
349
  * JSON Web Key ({@link https://www.rfc-editor.org/rfc/rfc7517 JWK}). "RSA", "EC", "OKP" and "oct" key types are supported.
323
350
  */
324
- type JWK = JWK_oct | JWK_RSA | JWK_EC | JWK_OKP;
351
+ type JWK<Alg extends string = string> = JWK_oct<Alg> | JWK_RSA<Alg> | JWK_EC<Alg> | JWK_OKP<Alg>;
325
352
  /**
326
- * A pair of public and private JSON Web Keys.
353
+ * A pair of public and private JSON Web Keys, narrowed by `Alg` when that
354
+ * uniquely identifies the key family:
355
+ *
356
+ * - `JWK_Pair<"RS256">` → RSA pair only
357
+ * - `JWK_Pair<"ES256">` → EC pair only
358
+ * - `JWK_Pair<"ECDH-ES+A256KW">` → EC pair **or** OKP pair (curve decides at runtime)
359
+ * - `JWK_Pair<"Ed25519">` / `JWK_Pair<"EdDSA">` → OKP pair only
360
+ *
361
+ * The final branch is a generic fallback (`Alg = string`, or any custom /
362
+ * forward-compat algorithm that doesn't match a known family) — it yields
363
+ * the permissive three-branch union.
327
364
  */
328
- type JWK_Pair = {
329
- publicKey: JWK_RSA_Public;
330
- privateKey: JWK_RSA_Private;
365
+ type JWK_Pair<Alg extends string = string> = Alg extends JWK_RSA_SIGN | JWK_RSA_PSS | JWK_RSA_ENC ? {
366
+ publicKey: JWK_RSA_Public<Alg>;
367
+ privateKey: JWK_RSA_Private<Alg>;
368
+ } : Alg extends JWK_ECDSA ? {
369
+ publicKey: JWK_EC_Public<Alg>;
370
+ privateKey: JWK_EC_Private<Alg>;
371
+ } : Alg extends JWK_ECDH_ES ? {
372
+ publicKey: JWK_EC_Public<Alg>;
373
+ privateKey: JWK_EC_Private<Alg>;
331
374
  } | {
332
- publicKey: JWK_EC_Public;
333
- privateKey: JWK_EC_Private;
375
+ publicKey: JWK_OKP_Public<Alg>;
376
+ privateKey: JWK_OKP_Private<Alg>;
377
+ } : Alg extends JWK_OKP_SIGN ? {
378
+ publicKey: JWK_OKP_Public<Alg>;
379
+ privateKey: JWK_OKP_Private<Alg>;
380
+ } : {
381
+ publicKey: JWK_RSA_Public<Alg>;
382
+ privateKey: JWK_RSA_Private<Alg>;
334
383
  } | {
335
- publicKey: JWK_OKP_Public;
336
- privateKey: JWK_OKP_Private;
384
+ publicKey: JWK_EC_Public<Alg>;
385
+ privateKey: JWK_EC_Private<Alg>;
386
+ } | {
387
+ publicKey: JWK_OKP_Public<Alg>;
388
+ privateKey: JWK_OKP_Private<Alg>;
337
389
  };
338
390
  /**
339
391
  * JSON Web Key Set ({@link https://www.rfc-editor.org/rfc/rfc7517 JWK Set}). "RSA", "EC" and "oct" key types are supported.
392
+ *
393
+ * The optional `T` generic preserves the precise key tuple when constructed
394
+ * in TS — e.g. `JWKSet<[JWK_oct<"HS256">, JWK_EC_Public<"ES256">]>` — while the
395
+ * default `JWK[]` keeps the permissive behavior expected for JWKS fetched from
396
+ * external sources (runtime trials each candidate).
340
397
  */
341
- interface JWKSet {
398
+ interface JWKSet<T extends readonly JWK[] = JWK[]> {
342
399
  /** JWK Set "keys" Parameter */
343
- keys: JWK[];
400
+ keys: T;
344
401
  [parameter: string]: unknown;
345
402
  }
346
403
  /** JWK Key Algorithms */
@@ -512,6 +569,32 @@ declare function isJWTError(error: unknown): error is JWTError;
512
569
  type StrictOmit<T, K extends keyof T | (string & {}) | (number & {}) | (symbol & {})> = { [P in keyof T as P extends K ? never : P]: T[P] };
513
570
  /** JWS Signing Algorithm Identifier. */
514
571
  type JWSAlgorithm = JWK_HMAC | JWK_RSA_SIGN | JWK_RSA_PSS | JWK_ECDSA | JWK_OKP_SIGN;
572
+ /**
573
+ * Asymmetric private JWKs admissible as a signing key. RSA keys carry a
574
+ * signing `alg` (RS* or PS*); EC keys carry an ECDSA alg; OKP keys carry an Ed
575
+ * signing alg.
576
+ */
577
+ type JWSAsymmetricPrivateJWK = JWK_RSA_Private<JWK_RSA_SIGN | JWK_RSA_PSS> | JWK_EC_Private<JWK_ECDSA> | JWK_OKP_Private<JWK_OKP_SIGN>;
578
+ /**
579
+ * Asymmetric public JWKs admissible as a verification key. RSA keys carry a
580
+ * signing `alg` (RS* or PS*); EC keys carry an ECDSA alg; OKP keys carry an Ed
581
+ * signing alg.
582
+ */
583
+ type JWSAsymmetricPublicJWK = JWK_RSA_Public<JWK_RSA_SIGN | JWK_RSA_PSS> | JWK_EC_Public<JWK_ECDSA> | JWK_OKP_Public<JWK_OKP_SIGN>;
584
+ /**
585
+ * JWKs admissible as the `key` argument of {@link sign}. HMAC oct keys carry a
586
+ * {@link JWK_HMAC} alg; asymmetric private keys carry their family's signing alg.
587
+ * A JWK whose `alg` points at a non-signing family (e.g. `"RSA-OAEP"`) is
588
+ * rejected at the type level.
589
+ */
590
+ type JWSSignJWK = JWK_oct<JWK_HMAC> | JWSAsymmetricPrivateJWK;
591
+ /**
592
+ * JWKs admissible as a `key` for {@link verify}. HMAC oct keys carry a
593
+ * {@link JWK_HMAC} alg; asymmetric public keys carry their family's signing alg.
594
+ * A JWK whose `alg` points at a non-signing family (e.g. `"RSA-OAEP"`) is
595
+ * rejected at the type level.
596
+ */
597
+ type JWSVerifyJWK = JWK_oct<JWK_HMAC> | JWSAsymmetricPublicJWK;
515
598
  /** Recognized JWS Header Parameters, any other Header Members may also be present. */
516
599
  interface JWSHeaderParameters extends JoseHeaderParameters {
517
600
  /** JWS "alg" (Algorithm) Header Parameter */
@@ -584,7 +667,12 @@ interface JWSVerifyResult<T extends JOSEPayload = JOSEPayload> {
584
667
  }
585
668
  /** Options for JWS verification */
586
669
  interface JWSVerifyOptions extends JWTClaimValidationOptions {
587
- /** List of allowed algorithms. If provided, the JWS `alg` must be in this list. */
670
+ /**
671
+ * List of allowed algorithms. If provided, the JWS `alg` must be in this list.
672
+ * When omitted, the allowlist is inferred from the key's shape — keys without
673
+ * usable metadata (raw `Uint8Array`/string, alg-less JWKs, lookup functions)
674
+ * cannot be inferred and require this option explicitly.
675
+ */
588
676
  algorithms?: JWSAlgorithm[];
589
677
  /** If true, forces the payload to be returned as a Uint8Array, otherwise type is inferred. */
590
678
  forceUint8Array?: boolean;
@@ -635,7 +723,7 @@ type JWSGeneralSignature = Pick<JWSFlattenedSerialization, "protected" | "header
635
723
  */
636
724
  interface JWSMultiSigner {
637
725
  /** Signing key (JWK-first; `alg` inferred from `key.alg`). */
638
- key: JWK;
726
+ key: JWSSignJWK;
639
727
  /**
640
728
  * Extra per-signer JWS Protected Header parameters (RFC 7515 §7.2.1).
641
729
  * `alg` is always derived from the JWK and cannot be set here. `b64`
@@ -710,6 +798,33 @@ type JWSMultiVerifyOutcome<T extends JOSEPayload = JOSEPayload> = {
710
798
  protectedHeader?: JWSProtectedHeader;
711
799
  signerHeader?: JWSHeaderParameters;
712
800
  };
801
+ /**
802
+ * Algorithms admissible on an `oct` JWK used for JWE key management. Mirrors
803
+ * the runtime aliasing table in `jweAlgsFromOctJWK` — HMAC algs intentionally
804
+ * excluded (they don't resolve to any JWE `alg`).
805
+ */
806
+ type _JWEOctAlg = JWK_AES_KW | JWK_AES_GCM | JWK_AES_GCM_KW | JWK_AES_CBC_HMAC | JWK_PBES2 | "dir";
807
+ /**
808
+ * Asymmetric public JWKs admissible for JWE encryption. RSA keys carry an
809
+ * RSA-OAEP alg; EC/OKP keys carry an ECDH-ES alg.
810
+ */
811
+ type JWEAsymmetricPublicJWK = JWK_RSA_Public<JWK_RSA_ENC> | JWK_EC_Public<JWK_ECDH_ES> | JWK_OKP_Public<JWK_ECDH_ES>;
812
+ /**
813
+ * Asymmetric private JWKs admissible for JWE decryption. RSA keys carry an
814
+ * RSA-OAEP alg; EC/OKP keys carry an ECDH-ES alg.
815
+ */
816
+ type JWEAsymmetricPrivateJWK = JWK_RSA_Private<JWK_RSA_ENC> | JWK_EC_Private<JWK_ECDH_ES> | JWK_OKP_Private<JWK_ECDH_ES>;
817
+ /**
818
+ * JWKs admissible as the `key` argument of {@link encrypt}. A JWK whose `alg`
819
+ * points at a non-JWE family (e.g. `"HS256"`, `"RS256"`) is rejected at the
820
+ * type level.
821
+ */
822
+ type JWEEncryptJWK = JWK_oct<_JWEOctAlg> | JWEAsymmetricPublicJWK;
823
+ /**
824
+ * JWKs admissible as a `key` for {@link decrypt}. A JWK whose `alg` points at
825
+ * a non-JWE family (e.g. `"HS256"`, `"RS256"`) is rejected at the type level.
826
+ */
827
+ type JWEDecryptJWK = JWK_oct<_JWEOctAlg> | JWEAsymmetricPrivateJWK;
713
828
  /** Recognized JWE Header Parameters, any other Header Members may also be present. */
714
829
  interface JWEHeaderParameters extends JoseHeaderParameters {
715
830
  /**
@@ -852,7 +967,12 @@ interface JWEEncryptOptions {
852
967
  * JWE (JSON Web Encryption) decryption options
853
968
  */
854
969
  interface JWEDecryptOptions extends JWTClaimValidationOptions {
855
- /** A list of allowed JWE "alg" (Algorithm) Header Parameter values for key management. */
970
+ /**
971
+ * A list of allowed JWE "alg" (Algorithm) Header Parameter values for key management.
972
+ * When omitted, the allowlist is inferred from the key's shape — password strings
973
+ * and raw `Uint8Array` keys infer the PBES2 family plus `dir`; lookup functions
974
+ * cannot be inferred and require this option explicitly.
975
+ */
856
976
  algorithms?: KeyManagementAlgorithm[];
857
977
  /** A list of allowed JWE "enc" (Encryption Algorithm) Header Parameter values for content encryption. */
858
978
  encryptionAlgorithms?: ContentEncryptionAlgorithm[];
@@ -946,7 +1066,7 @@ interface JWEGeneralRecipient {
946
1066
  */
947
1067
  interface JWEMultiRecipient {
948
1068
  /** Recipient key (JWK-first; `alg` inferred if absent from JWK). */
949
- key: JWK;
1069
+ key: JWEEncryptJWK;
950
1070
  /**
951
1071
  * Extra per-recipient JWE Unprotected Header parameters (RFC 7516 §7.2.1).
952
1072
  * Excludes fields the library writes automatically: `alg`, `enc`, `iv`,
@@ -1019,4 +1139,4 @@ type ExpiresIn = Duration;
1019
1139
  type NotBeforeIn = Duration;
1020
1140
  /** Duration for `maxTokenAge` validation on {@link verify} / {@link decrypt}. */
1021
1141
  type MaxTokenAge = Duration;
1022
- export { JWKAlgorithm as $, JWSSignOptions as A, JWK_RSA_Public as At, JWTClaimValidationOptions as B, JWSMultiSignOptions as C, JWK_Pair as Ct, JWSMultiVerifyOutcome as D, JWK_RSA_ENC as Dt, JWSMultiVerifyOptions as E, JWK_RSA as Et, JWTErrorCauseMap as F, KeyManagementAlgorithm as Ft, DeriveKeyOptions as G, JoseHeaderParameters as H, JWTErrorCode as I, UnwrapKeyOptions as It, GenerateJWKReturn as J, DeriveKeyReturn as K, isJWTError as L, WrapKeyOptions as Lt, JWSVerifyResult as M, JWK_Symmetric as Mt, StrictOmit as N, JWK_Symmetric_Algorithm as Nt, JWSMultiVerifyResult as O, JWK_RSA_PSS as Ot, JWTError as P, JWK_oct as Pt, JWK as Q, JOSEPayload as R, WrapKeyResult as Rt, JWSHeaderParameters as S, JWK_PBES2 as St, JWSMultiVerifyAllOptions as T, JWK_Public as Tt, CompositeKey as U, JWTClaims as V, ContentEncryptionAlgorithm as W, GenerateKeyOptions as X, GenerateKeyAlgorithm as Y, GenerateKeyReturn as Z, JWEProtectedHeader as _, JWK_HMAC as _t, JWEDecryptOptions as a, JWKSet as at, JWSGeneralSerialization as b, JWK_OKP_Public as bt, JWEFlattenedSerialization as c, JWK_AES_GCM_KW as ct, JWEHeaderParameters as d, JWK_Asymmetric_Algorithm as dt, JWKCacheAdapter as et, JWEKeyManagementHeaderParameters as f, JWK_EC as ft, JWEMultiRecipient as g, JWK_EC_Public as gt, JWEMultiEncryptOptions as h, JWK_EC_Private as ht, NotBeforeIn as i, JWKParameters as it, JWSVerifyOptions as j, JWK_RSA_SIGN as jt, JWSProtectedHeader as k, JWK_RSA_Private as kt, JWEGeneralRecipient as l, JWK_AES_KW as lt, JWEMultiDecryptResult as m, JWK_ECDSA as mt, ExpiresIn as n, JWKLookupFunctionHeader as nt, JWEDecryptResult as o, JWK_AES_CBC_HMAC as ot, JWEMultiDecryptOptions as p, JWK_ECDH_ES as pt, GenerateJWKOptions as q, MaxTokenAge as r, JWKPEMAlgorithm as rt, JWEEncryptOptions as s, JWK_AES_GCM as st, Duration as t, JWKLookupFunction as tt, JWEGeneralSerialization as u, JWK_Asymmetric as ut, JWSAlgorithm as v, JWK_OKP as vt, JWSMultiSigner as w, JWK_Private as wt, JWSGeneralSignature as x, JWK_OKP_SIGN as xt, JWSFlattenedSerialization as y, JWK_OKP_Private as yt, JWT as z };
1142
+ export { CompositeKey, ContentEncryptionAlgorithm, DeriveKeyOptions, DeriveKeyReturn, Duration, ExpiresIn, GenerateJWKOptions, GenerateJWKReturn, GenerateKeyAlgorithm, GenerateKeyOptions, GenerateKeyReturn, JOSEPayload, JWEAsymmetricPrivateJWK, JWEAsymmetricPublicJWK, JWEDecryptJWK, JWEDecryptOptions, JWEDecryptResult, JWEEncryptJWK, JWEEncryptOptions, JWEFlattenedSerialization, JWEGeneralRecipient, JWEGeneralSerialization, JWEHeaderParameters, JWEKeyManagementHeaderParameters, JWEMultiDecryptOptions, JWEMultiDecryptResult, JWEMultiEncryptOptions, JWEMultiRecipient, JWEProtectedHeader, JWK, JWKAlgorithm, JWKCacheAdapter, JWKLookupFunction, JWKLookupFunctionHeader, JWKPEMAlgorithm, JWKParameters, JWKSet, JWK_AES_CBC_HMAC, JWK_AES_GCM, JWK_AES_GCM_KW, JWK_AES_KW, JWK_Asymmetric, JWK_Asymmetric_Algorithm, JWK_EC, JWK_ECDH_ES, JWK_ECDSA, JWK_EC_Private, JWK_EC_Public, JWK_HMAC, JWK_OKP, JWK_OKP_Private, JWK_OKP_Public, JWK_OKP_SIGN, JWK_PBES2, JWK_Pair, JWK_Private, JWK_Public, JWK_RSA, JWK_RSA_ENC, JWK_RSA_PSS, JWK_RSA_Private, JWK_RSA_Public, JWK_RSA_SIGN, JWK_Symmetric, JWK_Symmetric_Algorithm, JWK_oct, JWSAlgorithm, JWSAsymmetricPrivateJWK, JWSAsymmetricPublicJWK, JWSFlattenedSerialization, JWSGeneralSerialization, JWSGeneralSignature, JWSHeaderParameters, JWSMultiSignOptions, JWSMultiSigner, JWSMultiVerifyAllOptions, JWSMultiVerifyOptions, JWSMultiVerifyOutcome, JWSMultiVerifyResult, JWSProtectedHeader, JWSSignJWK, JWSSignOptions, JWSVerifyJWK, JWSVerifyOptions, JWSVerifyResult, JWT, JWTClaimValidationOptions, JWTClaims, JWTError, JWTErrorCauseMap, JWTErrorCode, JoseHeaderParameters, KeyManagementAlgorithm, MaxTokenAge, NotBeforeIn, StrictOmit, UnwrapKeyOptions, UnwrappingKeyFor, WrapKeyOptions, WrapKeyResult, WrappingKeyFor, isJWTError };
@@ -1,4 +1,4 @@
1
- import { Ft as KeyManagementAlgorithm, Mt as JWK_Symmetric, Q as JWK, R as JOSEPayload, W as ContentEncryptionAlgorithm, a as JWEDecryptOptions, at as JWKSet, c as JWEFlattenedSerialization, g as JWEMultiRecipient, h as JWEMultiEncryptOptions, m as JWEMultiDecryptResult, o as JWEDecryptResult, p as JWEMultiDecryptOptions, s as JWEEncryptOptions, tt as JWKLookupFunction, u as JWEGeneralSerialization, wt as JWK_Private } from "./index.mjs";
1
+ import { ContentEncryptionAlgorithm, JOSEPayload, JWEDecryptJWK, JWEDecryptOptions, JWEDecryptResult, JWEEncryptJWK, JWEEncryptOptions, JWEFlattenedSerialization, JWEGeneralSerialization, JWEMultiDecryptOptions, JWEMultiDecryptResult, JWEMultiEncryptOptions, JWEMultiRecipient, JWKLookupFunction, JWKSet, KeyManagementAlgorithm } from "./index.mjs";
2
2
  /**
3
3
  * Encrypt a payload to multiple recipients using JWE General JSON Serialization
4
4
  * (RFC 7516 §7.2.1).
@@ -29,7 +29,7 @@ declare function encryptMulti(payload: JOSEPayload, recipients: JWEMultiRecipien
29
29
  *
30
30
  * For compact (string) tokens, use {@link decrypt}.
31
31
  */
32
- declare function decryptMulti<T extends JOSEPayload = JOSEPayload>(jwe: JWEGeneralSerialization | JWEFlattenedSerialization, keyOrLookup: CryptoKey | JWKSet | JWK_Private | JWK_Symmetric | string | Uint8Array<ArrayBuffer> | JWKLookupFunction, options?: JWEMultiDecryptOptions): Promise<JWEMultiDecryptResult<T>>;
32
+ declare function decryptMulti<T extends JOSEPayload = JOSEPayload>(jwe: JWEGeneralSerialization | JWEFlattenedSerialization, keyOrLookup: CryptoKey | JWKSet | JWEDecryptJWK | string | Uint8Array<ArrayBuffer> | JWKLookupFunction, options?: JWEMultiDecryptOptions): Promise<JWEMultiDecryptResult<T>>;
33
33
  /**
34
34
  * Convert a {@link JWEGeneralSerialization} with exactly one recipient into
35
35
  * the {@link JWEFlattenedSerialization} form (RFC 7516 §7.2.2). Throws
@@ -53,8 +53,10 @@ declare function generalToFlattened(jwe: JWEGeneralSerialization): JWEFlattenedS
53
53
  * @param options JWE encryption options, including `alg` (key management algorithm) and `enc` (content encryption algorithm).
54
54
  * @returns A Promise resolving to the JWE Compact Serialization string.
55
55
  */
56
- declare function encrypt(payload: JOSEPayload, key: JWK | string | Uint8Array<ArrayBuffer>, options?: JWEEncryptOptions): Promise<string>;
57
- declare function encrypt(payload: JOSEPayload, key: CryptoKey | JWK_Symmetric | Uint8Array<ArrayBuffer>, options: JWEEncryptOptions & {
56
+ declare function encrypt(payload: JOSEPayload, key: JWEEncryptJWK | string | Uint8Array<ArrayBuffer>, options?: JWEEncryptOptions): Promise<string>;
57
+ declare function encrypt(payload: JOSEPayload, key: CryptoKey | Extract<JWEEncryptJWK, {
58
+ kty: "oct";
59
+ }> | Uint8Array<ArrayBuffer>, options: JWEEncryptOptions & {
58
60
  alg: "dir";
59
61
  enc: ContentEncryptionAlgorithm;
60
62
  }): Promise<string>;
@@ -62,7 +64,7 @@ declare function encrypt(payload: JOSEPayload, key: CryptoKey, options: JWEEncry
62
64
  alg: KeyManagementAlgorithm;
63
65
  enc: ContentEncryptionAlgorithm;
64
66
  }): Promise<string>;
65
- declare function encrypt(payload: JOSEPayload, key: CryptoKey | JWK | string | Uint8Array<ArrayBuffer>, options: JWEEncryptOptions & {
67
+ declare function encrypt(payload: JOSEPayload, key: CryptoKey | JWEEncryptJWK | string | Uint8Array<ArrayBuffer>, options: JWEEncryptOptions & {
66
68
  alg: KeyManagementAlgorithm;
67
69
  enc: ContentEncryptionAlgorithm;
68
70
  }): Promise<string>;
@@ -75,8 +77,8 @@ declare function encrypt(payload: JOSEPayload, key: CryptoKey | JWK | string | U
75
77
  * @returns A Promise resolving to an object containing the decrypted plaintext, protected header, CEK, and AAD.
76
78
  * @throws If JWE is invalid, decryption fails, or options are not met.
77
79
  */
78
- declare function decrypt<T extends JOSEPayload>(jwe: string, key: CryptoKey | JWKSet | JWK_Private | JWK_Symmetric | string | Uint8Array<ArrayBuffer> | JWKLookupFunction, options?: JWEDecryptOptions): Promise<JWEDecryptResult<T>>;
79
- declare function decrypt(jwe: string, key: CryptoKey | JWKSet | JWK_Private | JWK_Symmetric | string | Uint8Array<ArrayBuffer> | JWKLookupFunction, options: JWEDecryptOptions & {
80
+ declare function decrypt<T extends JOSEPayload>(jwe: string, key: CryptoKey | JWKSet | JWEDecryptJWK | string | Uint8Array<ArrayBuffer> | JWKLookupFunction, options?: JWEDecryptOptions): Promise<JWEDecryptResult<T>>;
81
+ declare function decrypt(jwe: string, key: CryptoKey | JWKSet | JWEDecryptJWK | string | Uint8Array<ArrayBuffer> | JWKLookupFunction, options: JWEDecryptOptions & {
80
82
  forceUint8Array: true;
81
83
  }): Promise<JWEDecryptResult<Uint8Array<ArrayBuffer>>>;
82
- export { generalToFlattened as a, encryptMulti as i, encrypt as n, decryptMulti as r, decrypt as t };
84
+ export { decrypt, decryptMulti, encrypt, encryptMulti, generalToFlattened };
@@ -1,7 +1,7 @@
1
- import { D as JWTError, S as validateCriticalHeadersJWE, b as getPlaintextBytes, f as applyTypCtyDefaults, h as computeJwtTimeClaims, i as isCryptoKey, o as isJWK, s as isJWKSet, y as decodePayloadFromBytes } from "./utils.mjs";
2
- import { a as base64UrlEncode, i as base64UrlDecode, s as textEncoder, t as secureRandomBytes, u as sanitizeObjectCopy } from "./libs/unsecure.mjs";
3
- import { C as generateIV, S as generateCEK, _ as unwrapKey, b as decrypt$1, h as importKey, p as getJWKsFromSet, x as encrypt$1, y as encryptKey } from "./jwk.mjs";
4
- import { i as checkAlgAllowed, l as validateJwtClaimsIfJsonPayload, o as decodeProtectedHeader, r as buildJWKSetFilter, s as parseEphemeralKey, t as JWE_ALG_CTX } from "./_internal.mjs";
1
+ import { JWTError, applyTypCtyDefaults, computeJwtTimeClaims, decodePayloadFromBytes, getPlaintextBytes, isCryptoKey, isJWK, isJWKSet, validateCriticalHeadersJWE } from "./utils.mjs";
2
+ import { base64UrlDecode, base64UrlEncode, sanitizeObjectCopy, secureRandomBytes, textEncoder } from "./libs/unsecure.mjs";
3
+ import { decrypt as decrypt$1, encrypt as encrypt$1, encryptKey, generateCEK, generateIV, getJWKsFromSet, importKey, unwrapKey } from "./jwk.mjs";
4
+ import { JWE_ALG_CTX, buildJWKSetFilter, checkAlgAllowed, decodeProtectedHeader, parseEphemeralKey, validateJwtClaimsIfJsonPayload } from "./_internal.mjs";
5
5
  const DIRECT_ALGS = /* @__PURE__ */ new Set(["dir", "ECDH-ES"]);
6
6
  async function encryptMulti(payload, recipients, options = {}) {
7
7
  if (!Array.isArray(recipients) || recipients.length === 0) throw new JWTError("encryptMulti requires at least one recipient.", "ERR_JWE_INVALID");
@@ -404,4 +404,4 @@ function _buildJWEHeader(alg, enc, key, userHeader, keyManagementParams, payload
404
404
  header.enc = enc;
405
405
  return applyTypCtyDefaults(header, payload);
406
406
  }
407
- export { generalToFlattened as a, encryptMulti as i, encrypt as n, decryptMulti as r, decrypt as t };
407
+ export { decrypt, decryptMulti, encrypt, encryptMulti, generalToFlattened };
@@ -1,5 +1,5 @@
1
- import { D as JWTError, a as isCryptoKeyPair, i as isCryptoKey, n as concatUint8Arrays, o as isJWK, r as isAsymmetricJWK, s as isJWKSet, t as assertCryptoKey } from "./utils.mjs";
2
- import { a as base64UrlEncode, i as base64UrlDecode, n as base64Decode, r as base64Encode, s as textEncoder, t as secureRandomBytes, u as sanitizeObjectCopy } from "./libs/unsecure.mjs";
1
+ import { JWTError, assertCryptoKey, concatUint8Arrays, isAsymmetricJWK, isCryptoKey, isCryptoKeyPair, isJWK, isJWKSet } from "./utils.mjs";
2
+ import { base64Decode, base64Encode, base64UrlDecode, base64UrlEncode, sanitizeObjectCopy, secureRandomBytes, textEncoder } from "./libs/unsecure.mjs";
3
3
  async function sign(alg, key, data) {
4
4
  checkSigCryptoKey(key, alg, "sign");
5
5
  const signature = await crypto.subtle.sign(subtleAlgorithm(alg, key.algorithm), key, data);
@@ -151,6 +151,16 @@ function checkCEKLength(cek, expected) {
151
151
  const actual = cek.byteLength << 3;
152
152
  if (actual !== expected) throw new Error(`Invalid Content Encryption Key length. Expected ${expected} bits, got ${actual} bits`);
153
153
  }
154
+ function assertOctKeyLength(bytes, alg) {
155
+ if (!alg) return;
156
+ if (alg === "HS256" || alg === "HS384" || alg === "HS512") {
157
+ const minBytes = Number.parseInt(alg.slice(2), 10) >> 3;
158
+ if (bytes.length < minBytes) throw new JWTError(`${alg} requires a key of at least ${minBytes} bytes (got ${bytes.length})`, "ERR_JWK_INVALID");
159
+ return;
160
+ }
161
+ const exactBits = /^A(128|192|256)(GCM)?KW$/.test(alg) ? Number.parseInt(alg.slice(1, 4), 10) : CEK_BIT_LENGTHS[alg];
162
+ if (exactBits !== void 0 && bytes.length << 3 !== exactBits) throw new JWTError(`${alg} requires a key of exactly ${exactBits >> 3} bytes (got ${bytes.length})`, "ERR_JWK_INVALID");
163
+ }
154
164
  function checkAESCryptoKey(key, alg, usage) {
155
165
  switch (alg) {
156
166
  case "A128GCM":
@@ -1011,7 +1021,7 @@ const getSPKI = (x509) => {
1011
1021
  };
1012
1022
  async function generateKey(alg, options = {}) {
1013
1023
  const exportToJWK = options.toJWK !== void 0 && options.toJWK !== false;
1014
- const defaultExtractable = options.extractable !== false;
1024
+ const defaultExtractable = exportToJWK || options.extractable !== false;
1015
1025
  if (alg === "A128CBC-HS256" || alg === "A192CBC-HS384" || alg === "A256CBC-HS512") {
1016
1026
  const keyBytes = secureRandomBytes(bitLengthCEK(alg) >> 3);
1017
1027
  if (exportToJWK) return keyToJWK(keyBytes);
@@ -1039,7 +1049,7 @@ async function generateKey(alg, options = {}) {
1039
1049
  return key;
1040
1050
  }
1041
1051
  async function generateJWK(alg, options) {
1042
- const { keyUsage, extractable, modulusLength, publicExponent, namedCurve, ...jwkParams } = options ?? {};
1052
+ const { keyUsage, modulusLength, publicExponent, namedCurve, ...jwkParams } = options ?? {};
1043
1053
  const kid = typeof jwkParams.kid === "string" ? jwkParams.kid : crypto.randomUUID();
1044
1054
  const extraParams = {
1045
1055
  ...jwkParams,
@@ -1047,7 +1057,6 @@ async function generateJWK(alg, options) {
1047
1057
  };
1048
1058
  const result = await generateKey(alg, {
1049
1059
  keyUsage,
1050
- extractable,
1051
1060
  modulusLength,
1052
1061
  publicExponent,
1053
1062
  namedCurve,
@@ -1089,12 +1098,11 @@ async function deriveKeyFromPassword(password, alg, options) {
1089
1098
  return derivedKey;
1090
1099
  }
1091
1100
  async function deriveJWKFromPassword(password, alg, options) {
1092
- const { salt, iterations, keyUsage, extractable, ...jwkParams } = options;
1101
+ const { salt, iterations, keyUsage, ...jwkParams } = options;
1093
1102
  const result = await deriveKeyFromPassword(password, alg, {
1094
1103
  salt,
1095
1104
  iterations,
1096
1105
  keyUsage,
1097
- extractable,
1098
1106
  toJWK: true
1099
1107
  });
1100
1108
  return Object.keys(jwkParams).length > 0 ? {
@@ -1131,9 +1139,16 @@ async function importKey(key, algOrOptions) {
1131
1139
  }
1132
1140
  if (isJWK(key)) if ("k" in key && typeof key.k === "string") {
1133
1141
  const rawBytes = base64UrlDecode(key.k, { returnAs: "uint8array" });
1142
+ assertOctKeyLength(rawBytes, key.alg || alg);
1134
1143
  if (typeof algOrOptions === "object" && algOrOptions.asCryptoKey) {
1135
1144
  const { algorithm, usage, extractable = false } = algOrOptions;
1136
1145
  if (!algorithm || !usage) throw new JWTError("asCryptoKey option requires `algorithm` and `usage` to be provided.", "ERR_JWK_INVALID");
1146
+ if (typeof algorithm === "object" && algorithm.name === "HMAC") {
1147
+ const hash = algorithm.hash;
1148
+ const hashName = typeof hash === "string" ? hash : hash?.name;
1149
+ const minBytes = Number.parseInt(hashName?.slice(-3) ?? "", 10) / 8;
1150
+ if (minBytes && rawBytes.length < minBytes) throw new JWTError(`HMAC with ${hashName} requires a key of at least ${minBytes} bytes (got ${rawBytes.length})`, "ERR_JWK_INVALID");
1151
+ }
1137
1152
  return crypto.subtle.importKey("raw", rawBytes, algorithm, extractable, usage);
1138
1153
  }
1139
1154
  return rawBytes;
@@ -1310,7 +1325,7 @@ async function unwrapKey(alg, wrappedKey, unwrappingKey, options = {}) {
1310
1325
  return await crypto.subtle.importKey("raw", unwrappedCekBytes, options.unwrappedKeyAlgorithm || { name: "AES-GCM" }, defaultExtractable, options.keyUsage || ["encrypt", "decrypt"]);
1311
1326
  }
1312
1327
  async function importPEM(pem, alg, options) {
1313
- const extractable = options?.extractable !== false;
1328
+ const extractable = true;
1314
1329
  const pemType = options?.pemType ?? inferPEMType(pem);
1315
1330
  if (!pemType) throw new JWTError("Cannot infer PEM type from the input; pass \"options.pemType\" explicitly.", "ERR_JWK_INVALID");
1316
1331
  let cryptoKey;
@@ -1622,4 +1637,4 @@ function inferAesImportAlgorithm(enc, cekLengthBytes) {
1622
1637
  length: bitLength
1623
1638
  };
1624
1639
  }
1625
- export { generateIV as C, generateCEK as S, verify as T, unwrapKey as _, deriveKeyFromPassword as a, decrypt as b, exportPEM as c, generateKey as d, getJWKFromSet as f, importPEM as g, importKey as h, deriveJWKFromPassword as i, exportToPEM as l, importFromPEM as m, clearJWKCache as n, deriveSharedSecret as o, getJWKsFromSet as p, configureJWKCache as r, exportKey as s, WeakMapJWKCache as t, generateJWK as u, wrapKey as v, sign as w, encrypt as x, encryptKey as y };
1640
+ export { WeakMapJWKCache, assertOctKeyLength, clearJWKCache, configureJWKCache, decrypt, deriveJWKFromPassword, deriveKeyFromPassword, deriveSharedSecret, encrypt, encryptKey, exportKey, exportPEM, exportToPEM, generateCEK, generateIV, generateJWK, generateKey, getJWKFromSet, getJWKsFromSet, importFromPEM, importKey, importPEM, sign, unwrapKey, verify, wrapKey };
@@ -1,4 +1,4 @@
1
- import { A as JWSSignOptions, C as JWSMultiSignOptions, D as JWSMultiVerifyOutcome, E as JWSMultiVerifyOptions, M as JWSVerifyResult, Mt as JWK_Symmetric, O as JWSMultiVerifyResult, R as JOSEPayload, T as JWSMultiVerifyAllOptions, Tt as JWK_Public, at as JWKSet, b as JWSGeneralSerialization, j as JWSVerifyOptions, tt as JWKLookupFunction, v as JWSAlgorithm, w as JWSMultiSigner, wt as JWK_Private, y as JWSFlattenedSerialization } from "./index.mjs";
1
+ import { JOSEPayload, JWKLookupFunction, JWKSet, JWSAlgorithm, JWSFlattenedSerialization, JWSGeneralSerialization, JWSMultiSignOptions, JWSMultiSigner, JWSMultiVerifyAllOptions, JWSMultiVerifyOptions, JWSMultiVerifyOutcome, JWSMultiVerifyResult, JWSSignJWK, JWSSignOptions, JWSVerifyJWK, JWSVerifyOptions, JWSVerifyResult } from "./index.mjs";
2
2
  /**
3
3
  * Sign a payload with multiple signers using JWS General JSON Serialization
4
4
  * (RFC 7515 §7.2.1).
@@ -30,7 +30,7 @@ declare function signMulti(payload: JOSEPayload, signers: JWSMultiSigner[], opti
30
30
  *
31
31
  * For compact (string) tokens, use {@link verify}.
32
32
  */
33
- declare function verifyMulti<T extends JOSEPayload = JOSEPayload>(jws: JWSGeneralSerialization | JWSFlattenedSerialization, keyOrLookup: CryptoKey | JWKSet | JWK_Public | JWK_Symmetric | Uint8Array<ArrayBuffer> | JWKLookupFunction, options?: JWSMultiVerifyOptions): Promise<JWSMultiVerifyResult<T>>;
33
+ declare function verifyMulti<T extends JOSEPayload = JOSEPayload>(jws: JWSGeneralSerialization | JWSFlattenedSerialization, keyOrLookup: CryptoKey | JWKSet | JWSVerifyJWK | Uint8Array<ArrayBuffer> | JWKLookupFunction, options?: JWSMultiVerifyOptions): Promise<JWSMultiVerifyResult<T>>;
34
34
  /**
35
35
  * Verify every signature in a JWS independently and return a per-signature
36
36
  * outcome array — the caller applies their own policy (all-must-verify,
@@ -91,7 +91,7 @@ declare function generalToFlattenedJWS(jws: JWSGeneralSerialization): JWSFlatten
91
91
  * @param options Signing options, including the algorithm (`alg`) and protected header parameters.
92
92
  * @returns A Promise resolving to the JWS Compact Serialization string.
93
93
  */
94
- declare function sign(payload: JOSEPayload, key: JWK_Symmetric | JWK_Private, options?: JWSSignOptions): Promise<string>;
94
+ declare function sign(payload: JOSEPayload, key: JWSSignJWK, options?: JWSSignOptions): Promise<string>;
95
95
  declare function sign(payload: JOSEPayload, key: CryptoKey | Uint8Array<ArrayBuffer>, options: JWSSignOptions & {
96
96
  alg: JWSAlgorithm;
97
97
  }): Promise<string>;
@@ -104,8 +104,8 @@ declare function sign(payload: JOSEPayload, key: CryptoKey | Uint8Array<ArrayBuf
104
104
  * @returns A Promise resolving to an object containing the verified payload and protected header.
105
105
  * @throws If the JWS is invalid, signature verification fails, or options are not met.
106
106
  */
107
- declare function verify<T extends JOSEPayload>(jws: string, key: CryptoKey | JWKSet | JWK_Public | JWK_Symmetric | Uint8Array<ArrayBuffer> | JWKLookupFunction, options?: JWSVerifyOptions): Promise<JWSVerifyResult<T>>;
108
- declare function verify(jws: string, key: CryptoKey | JWKSet | JWK_Public | JWK_Symmetric | Uint8Array<ArrayBuffer> | JWKLookupFunction, options: JWSVerifyOptions & {
107
+ declare function verify<T extends JOSEPayload>(jws: string, key: CryptoKey | JWKSet | JWSVerifyJWK | Uint8Array<ArrayBuffer> | JWKLookupFunction, options?: JWSVerifyOptions): Promise<JWSVerifyResult<T>>;
108
+ declare function verify(jws: string, key: CryptoKey | JWKSet | JWSVerifyJWK | Uint8Array<ArrayBuffer> | JWKLookupFunction, options: JWSVerifyOptions & {
109
109
  forceUint8Array: true;
110
110
  }): Promise<JWSVerifyResult<Uint8Array<ArrayBuffer>>>;
111
- export { verifyMulti as a, signMulti as i, verify as n, verifyMultiAll as o, generalToFlattenedJWS as r, sign as t };
111
+ export { generalToFlattenedJWS, sign, signMulti, verify, verifyMulti, verifyMultiAll };
@@ -1,7 +1,7 @@
1
- import { C as validateCriticalHeadersJWS, D as JWTError, b as getPlaintextBytes, f as applyTypCtyDefaults, h as computeJwtTimeClaims, o as isJWK, s as isJWKSet } from "./utils.mjs";
2
- import { a as base64UrlEncode, i as base64UrlDecode, o as textDecoder, s as textEncoder, u as sanitizeObjectCopy } from "./libs/unsecure.mjs";
3
- import { T as verify$1, h as importKey, p as getJWKsFromSet, w as sign$1 } from "./jwk.mjs";
4
- import { a as decodeJWSPayload, c as resolveSigningKey, i as checkAlgAllowed, l as validateJwtClaimsIfJsonPayload, n as JWS_ALG_CTX, o as decodeProtectedHeader, r as buildJWKSetFilter } from "./_internal.mjs";
1
+ import { JWTError, applyTypCtyDefaults, computeJwtTimeClaims, getPlaintextBytes, isJWK, isJWKSet, validateCriticalHeadersJWS } from "./utils.mjs";
2
+ import { base64UrlDecode, base64UrlEncode, sanitizeObjectCopy, textDecoder, textEncoder } from "./libs/unsecure.mjs";
3
+ import { getJWKsFromSet, importKey, sign as sign$1, verify as verify$1 } from "./jwk.mjs";
4
+ import { JWS_ALG_CTX, buildJWKSetFilter, checkAlgAllowed, decodeJWSPayload, decodeProtectedHeader, resolveSigningKey, validateJwtClaimsIfJsonPayload } from "./_internal.mjs";
5
5
  async function signMulti(payload, signers, options = {}) {
6
6
  if (!Array.isArray(signers) || signers.length === 0) throw new JWTError("signMulti requires at least one signer.", "ERR_JWS_INVALID");
7
7
  const resolvedAlgs = signers.map((s, i) => _resolveSignerAlg(s.key, i));
@@ -346,4 +346,4 @@ function _buildJWSHeader(alg, key, userHeader, payload) {
346
346
  if (header.b64 === true) delete header.b64;
347
347
  return header;
348
348
  }
349
- export { verifyMulti as a, signMulti as i, verify as n, verifyMultiAll as o, generalToFlattenedJWS as r, sign as t };
349
+ export { generalToFlattenedJWS, sign, signMulti, verify, verifyMulti, verifyMultiAll };