unjwt 0.7.2 → 0.8.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.
Files changed (39) hide show
  1. package/README.md +4 -4
  2. package/dist/THIRD-PARTY-LICENSES.md.gz +0 -0
  3. package/dist/_chunks/_codec-jwe.d.mts +170 -0
  4. package/dist/_chunks/_codec-jws.mjs +878 -0
  5. package/dist/_chunks/_internal.d.mts +7 -0
  6. package/dist/_chunks/_jwt-internal.mjs +388 -0
  7. package/dist/_chunks/algorithms.mjs +186 -0
  8. package/dist/_chunks/index.d.mts +512 -818
  9. package/dist/_chunks/index2.d.mts +11 -0
  10. package/dist/_chunks/index3.d.mts +108 -0
  11. package/dist/_chunks/jwe.d.mts +43 -66
  12. package/dist/_chunks/jwe.mjs +384 -252
  13. package/dist/_chunks/jwk.mjs +1390 -622
  14. package/dist/_chunks/jws.d.mts +48 -103
  15. package/dist/_chunks/jws.mjs +372 -184
  16. package/dist/_chunks/jwt.d.mts +56 -0
  17. package/dist/_chunks/libs/unsecure.d.mts +164 -85
  18. package/dist/_chunks/libs/unsecure.mjs +390 -123
  19. package/dist/adapters/elysia/index.d.mts +33 -171
  20. package/dist/adapters/elysia/index.mjs +106 -575
  21. package/dist/adapters/h3v1/index.d.mts +59 -344
  22. package/dist/adapters/h3v1/index.mjs +114 -619
  23. package/dist/adapters/h3v2/index.d.mts +58 -326
  24. package/dist/adapters/h3v2/index.mjs +108 -611
  25. package/dist/core/internal.d.mts +2 -0
  26. package/dist/core/internal.mjs +1 -0
  27. package/dist/core/jwe.d.mts +4 -2
  28. package/dist/core/jwe.mjs +4 -2
  29. package/dist/core/jwk.d.mts +183 -371
  30. package/dist/core/jwk.mjs +4 -3
  31. package/dist/core/jws.d.mts +4 -2
  32. package/dist/core/jws.mjs +4 -2
  33. package/dist/core/utils/index.d.mts +5 -155
  34. package/dist/core/utils/index.mjs +12 -3
  35. package/dist/index.d.mts +8 -4
  36. package/dist/index.mjs +6 -3
  37. package/package.json +39 -36
  38. package/dist/_chunks/_internal.mjs +0 -88
  39. package/dist/_chunks/utils.mjs +0 -390
@@ -1,14 +1,107 @@
1
+ import { UnsecureError, UnsecureErrorCode } from "./libs/unsecure.mjs";
2
+ /**
3
+ * The closed union of error codes unjwt itself throws.
4
+ *
5
+ * Code naming follows the JOSE spec hierarchy:
6
+ * ERR_JWT_* — RFC 7519 JSON Web Token claim validation
7
+ * ERR_JWS_* — RFC 7515 JSON Web Signature
8
+ * ERR_JWE_* — RFC 7516 JSON Web Encryption
9
+ * ERR_JWK_* — RFC 7517 JSON Web Key
10
+ * ERR_SESSION_* — the framework session adapters
11
+ *
12
+ * Use this type where a typo must not compile — {@link isJWTError} takes it,
13
+ * so `isJWTError(err, "ERR_JWS_INVALD")` is a type error rather than a check
14
+ * that silently never matches. Use {@link JWTErrorCode} for values that may
15
+ * legitimately carry a code this version does not know about.
16
+ */
17
+ export type KnownJWTErrorCode = "ERR_JWT_EXPIRED" | "ERR_JWT_NBF" | "ERR_JWT_CLAIM_INVALID" | "ERR_JWT_CLAIM_MISSING" | "ERR_JWS_INVALID" | "ERR_JWS_INVALID_SERIALIZATION" | "ERR_JWS_SIGNATURE_INVALID" | "ERR_JWS_ALG_NOT_ALLOWED" | "ERR_JWS_ALG_MISSING" | "ERR_JWS_SIGNER_ALG_INFERENCE" | "ERR_JWS_NO_MATCHING_SIGNER" | "ERR_JWS_HEADER_PARAMS_NOT_DISJOINT" | "ERR_JWS_B64_INCONSISTENT" | "ERR_JWE_INVALID" | "ERR_JWE_INVALID_SERIALIZATION" | "ERR_JWE_DECRYPTION_FAILED" | "ERR_JWE_ALG_NOT_ALLOWED" | "ERR_JWE_ALG_MISSING" | "ERR_JWE_ALG_FORBIDDEN_IN_MULTI" | "ERR_JWE_ENC_MISSING" | "ERR_JWE_RECIPIENT_ALG_INFERENCE" | "ERR_JWE_NO_MATCHING_RECIPIENT" | "ERR_JWE_HEADER_PARAMS_NOT_DISJOINT" | "ERR_JWK_INVALID" | "ERR_JWK_KEY_NOT_FOUND" | "ERR_JWK_UNSUPPORTED" | "ERR_SESSION_TOKEN_INVALID" | "ERR_SESSION_READONLY_EVENT" | "ERR_SESSION_KEY_INVALID" | "ERR_SESSION_CONFIG_INVALID" | "ERR_INVALID_OPTION";
18
+ /**
19
+ * A {@link JWTError} `code`: every {@link KnownJWTErrorCode}, plus any other
20
+ * string for forward compatibility — a newer unjwt (or a caller constructing
21
+ * its own `JWTError`) may carry a code this version's union does not list.
22
+ */
23
+ export type JWTErrorCode = KnownJWTErrorCode | (string & {});
24
+ /**
25
+ * Maps known error codes to their structured `cause` shapes.
26
+ * Only codes that carry decoded context beyond the message appear here.
27
+ * Extend this interface when new structured causes are introduced.
28
+ */
29
+ export interface JWTErrorCauseMap {
30
+ /** Decoded claims available at the point the lifetime check failed. */
31
+ ERR_JWT_EXPIRED: {
32
+ jti?: string;
33
+ iat?: number;
34
+ exp?: number;
35
+ };
36
+ }
37
+ /**
38
+ * Base error class for all unjwt errors. Every error thrown by the library is
39
+ * an instance of `JWTError`, so a single `instanceof` check is sufficient to
40
+ * distinguish library errors from other thrown values. Use the `code` property
41
+ * (or the `isJWTError` type guard) to narrow to a specific error condition.
42
+ *
43
+ * @example
44
+ * import { JWTError, isJWTError } from "unjwt/jws";
45
+ *
46
+ * try {
47
+ * await verify(token, key);
48
+ * } catch (err) {
49
+ * if (isJWTError(err, "ERR_JWT_EXPIRED")) {
50
+ * console.log(err.cause.jti); // string | undefined
51
+ * }
52
+ * }
53
+ */
54
+ export declare class JWTError<TCode extends JWTErrorCode = JWTErrorCode> extends Error {
55
+ readonly code: TCode;
56
+ override readonly cause?: unknown;
57
+ constructor(message: string, code: TCode, cause?: unknown);
58
+ }
1
59
  /**
2
- * The decoded JOSE protected header received by a {@link JWKLookupFunction}.
3
- *
4
- * The most commonly inspected fields are explicitly typed; additional
5
- * algorithm-specific parameters (`epk`, `p2s`, `p2c`, `apu`, `apv`, …) are
6
- * accessible through the index signature.
7
- *
8
- * `alg` is always present on both JWS and JWE tokens. `enc` is only present
9
- * on JWE tokens.
10
- */
11
- type JWKLookupFunctionHeader = {
60
+ * Type guard that narrows `error` to `JWTError`.
61
+ *
62
+ * When called with a code that is a key of `JWTErrorCauseMap`, the return
63
+ * type is additionally narrowed to include the structured `cause` shape for
64
+ * that code. When called with any other `KnownJWTErrorCode`, `code` is narrowed
65
+ * but `cause` remains `unknown`. When called without a code, narrows only to
66
+ * `JWTError`.
67
+ *
68
+ * `code` is a {@link KnownJWTErrorCode}, so a misspelled code fails to
69
+ * type-check instead of silently never matching.
70
+ *
71
+ * @example
72
+ * if (isJWTError(err, "ERR_JWT_EXPIRED")) {
73
+ * err.cause.jti // string | undefined ✓
74
+ * }
75
+ */
76
+ export declare function isJWTError<T extends keyof JWTErrorCauseMap>(error: unknown, code: T): error is JWTError<T> & {
77
+ cause: JWTErrorCauseMap[T];
78
+ };
79
+ export declare function isJWTError<T extends KnownJWTErrorCode>(error: unknown, code: T): error is JWTError<T>;
80
+ export declare function isJWTError(error: unknown): error is JWTError;
81
+ /**
82
+ * Type guard that narrows `error` to the bundled {@link UnsecureError}, the
83
+ * class thrown by unjwt's codec / JSON / random primitives and carried as the
84
+ * `cause` of a {@link JWTError} when a wire segment or key field fails to
85
+ * decode. Pass a `code` to narrow further.
86
+ *
87
+ * Check against this export rather than a `UnsecureError` imported from a
88
+ * consumer-installed `unsecure`: unjwt bundles its own copy, so the two classes
89
+ * are distinct and `instanceof` against the latter is always `false`.
90
+ *
91
+ * @example
92
+ * import { isJWTError, isUnsecureError } from "unjwt/jws";
93
+ *
94
+ * const error = await verify(token, key).catch((e) => e);
95
+ * if (isJWTError(error, "ERR_JWS_INVALID") && isUnsecureError(error.cause, "MALFORMED")) {
96
+ * // a segment of the token is not canonical base64url
97
+ * }
98
+ */
99
+ export declare function isUnsecureError<T extends UnsecureErrorCode>(error: unknown, code: T): error is UnsecureError & {
100
+ code: T;
101
+ };
102
+ export declare function isUnsecureError(error: unknown): error is UnsecureError;
103
+ /** Decoded protected header passed to a `JWKLookupFunction`; `enc` is present on JWE only. */
104
+ export type JWKLookupFunctionHeader = {
12
105
  kid?: string;
13
106
  alg?: string;
14
107
  enc?: string;
@@ -16,264 +109,186 @@ type JWKLookupFunctionHeader = {
16
109
  crit?: string[];
17
110
  [propName: string]: unknown;
18
111
  };
19
- /**
20
- * A callback that resolves the decryption or verification key from a token's
21
- * decoded protected header and the raw compact token string.
22
- *
23
- * Accepted by both {@link verify} (JWS) and {@link decrypt} (JWE). When a
24
- * {@link JWKSet} is returned, the library tries each key whose `kid` and `alg`
25
- * are compatible with the header in order, stopping at the first that succeeds
26
- * — see {@link getJWKsFromSet} for the selection logic.
27
- *
28
- * Returning a `string` is meaningful for JWE only (PBES2 password); for JWS
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.
34
- */
35
- type JWKLookupFunction<TReturn = CryptoKey | JWK | JWKSet | string | Uint8Array<ArrayBuffer>> = (header: JWKLookupFunctionHeader, token: string) => TReturn | Promise<TReturn>;
36
- /**
37
- * Interface for custom JWK import cache implementations.
38
- *
39
- * The adapter receives the full JWK object so each implementation can choose
40
- * its own keying strategy:
41
- * - {@link WeakMapJWKCache} uses the object reference (GC-friendly, no string hashing needed)
42
- * - A `kid`-keyed cache extracts `jwk.kid` and uses it as a string key
43
- * - A content-hash cache hashes `jwk.k` or `jwk.n`+`jwk.e`
44
- *
45
- * @example Use a custom kid-keyed cache:
46
- * ```ts
47
- * import { configureJWKCache } from 'unjwt/jwk';
48
- * const map = new Map<string, CryptoKey>();
49
- * configureJWKCache({
50
- * get: (jwk, alg) => map.get(`${jwk.kid}:${alg}`),
51
- * set: (jwk, alg, key) => map.set(`${jwk.kid}:${alg}`, key),
52
- * });
53
- * ```
54
- */
55
- interface JWKCacheAdapter {
56
- get(jwk: JWK, alg: string): CryptoKey | undefined;
57
- set(jwk: JWK, alg: string, key: CryptoKey): void;
112
+ /** Resolves the verify/decrypt key from the protected header and compact token; a string is a PBES2 password (JWE) or raw key bytes (JWS); `undefined`, `null` or a throw is `ERR_JWK_KEY_NOT_FOUND`. */
113
+ export type JWKLookupFunction<TReturn = CryptoKey | JWK | JWKSet | string | Uint8Array<ArrayBuffer>> = (header: JWKLookupFunctionHeader, token: string) => TReturn | undefined | null | Promise<TReturn | undefined | null>;
114
+ /** Custom JWK import cache; key on the JWK `thumbprint` plus private/public half and `alg`, never on `kid`. Both methods may return a promise. */
115
+ export interface JWKCacheAdapter {
116
+ get(jwk: JWK, alg: string): CryptoKey | undefined | Promise<CryptoKey | undefined>;
117
+ set(jwk: JWK, alg: string, key: CryptoKey): void | Promise<void>;
58
118
  }
59
119
  /** Structure returned for composite AES-CBC + HMAC keys. */
60
- type CompositeKey = {
61
- /** The AES-CBC encryption/decryption key. */encryptionKey: CryptoKey; /** The HMAC key for integrity/authentication. */
120
+ export type CompositeKey = {
121
+ encryptionKey: CryptoKey;
62
122
  macKey: CryptoKey;
63
123
  };
64
- type GenerateKeyAlgorithm = Exclude<JWKAlgorithm, "none" | "dir" | JWK_PBES2>;
65
- /** Options for the generateKey function. */
66
- interface GenerateKeyOptions {
67
- /** Key usages for the generated key(s). Note: For composite keys (CBC), default usages are applied separately. */
124
+ export type GenerateKeyAlgorithm = Exclude<JWKAlgorithm, "none" | "dir" | JWK_PBES2>;
125
+ /** Options for `generateJWK`; `Kid` is the `kid` option that types the generated `kid`. */
126
+ export interface GenerateJWKOptions<Kid extends string | false = string | false> {
127
+ /** Key usages; composite (CBC) keys get their default usages separately. */
68
128
  keyUsage?: KeyUsage[];
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
- */
75
- extractable?: boolean;
76
- /** RSA modulus length. Defaults to 2048. */
129
+ /** RSA modulus length. Default: `2048`. */
77
130
  modulusLength?: number;
78
- /** RSA public exponent. Defaults to 65537 (0x010001). */
131
+ /** RSA public exponent. Default: `65537`. */
79
132
  publicExponent?: Uint8Array<ArrayBuffer>;
80
- /** Named curve for EC or OKP keys. Defaults to "P-256" for EC and "Ed25519" for OKP. */
81
- namedCurve?: "P-256" | "P-384" | "P-521" | "X25519" | "Ed25519" | "Ed448";
82
- /**
83
- * Export the generated key(s) as JWK. When `true`, keys are returned in JWK
84
- * format with a generated `kid`. To include additional JWK parameters
85
- * (e.g. a custom `kid`), use {@link generateJWK} instead.
86
- */
87
- toJWK?: boolean;
88
- }
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;
90
- type GenerateKeyReturnCrypto<TAlg extends GenerateKeyAlgorithm> = TAlg extends JWK_AES_CBC_HMAC ? Uint8Array<ArrayBuffer> : TAlg extends JWK_Asymmetric_Algorithm ? CryptoKeyPair : CryptoKey;
91
- type GenerateKeyReturn<TAlg extends GenerateKeyAlgorithm, TOptions extends GenerateKeyOptions> = TOptions["toJWK"] extends true ? GenerateKeyReturnJWK<TAlg> : GenerateKeyReturnCrypto<TAlg>;
92
- type GenerateJWKOptions = Omit<GenerateKeyOptions, "toJWK" | "extractable">;
93
- type GenerateJWKReturn<TAlg extends GenerateKeyAlgorithm> = GenerateKeyReturnJWK<TAlg>;
94
- /** Options for the deriveKeyFromPassword function. */
95
- interface DeriveKeyOptions {
96
- /** Salt value (p2s). Must be at least 8 bytes. */
97
- salt: Uint8Array<ArrayBuffer>;
98
- /** Iteration count (p2c). Must be a positive integer. */
133
+ /** EC/OKP curve. Default: `"P-256"` (EC), `"Ed25519"` (OKP). */
134
+ namedCurve?: "P-256" | "P-384" | "P-521" | "X25519" | "Ed25519";
135
+ /** `kid` to set verbatim, or `false` for none. Default: the RFC 7638 thumbprint, a SHA-256 digest per key. */
136
+ kid?: Kid;
137
+ }
138
+ /** Options for `generateKey`; `ToJWK` is the `toJWK` literal that picks key objects or JWKs. */
139
+ export interface GenerateKeyOptions<ToJWK extends boolean = boolean, Kid extends string | false = string | false> extends GenerateJWKOptions<Kid> {
140
+ /** Mark the key(s) extractable; ignored when `toJWK` is set. Default: `true`. */
141
+ extractable?: boolean;
142
+ /** Return JWKs instead of key objects. */
143
+ toJWK?: ToJWK;
144
+ /** Read only with `toJWK`: `kid` to set verbatim, or `false` for none. Default: the RFC 7638 thumbprint, a SHA-256 digest per key. */
145
+ kid?: Kid;
146
+ }
147
+ /** `generateKey` result per algorithm without `toJWK`: `CryptoKey` (symmetric), raw bytes (`A*CBC-HS*`), `CryptoKeyPair` (asymmetric). */
148
+ export type GeneratedKeyMap = { [A in GenerateKeyAlgorithm]: A extends JWK_AES_CBC_HMAC ? Uint8Array<ArrayBuffer> : A extends JWK_Asymmetric_Algorithm ? CryptoKeyPair : CryptoKey; };
149
+ /** `generateJWK` result per algorithm: an `oct` JWK or a JWK pair, each carrying `alg`, and `kid` unless `Kid` is `false`. */
150
+ export type GeneratedJWKMap<Kid extends string | false = string> = { [A in GenerateKeyAlgorithm]: A extends JWK_Asymmetric_Algorithm ? GeneratedJWKPair<JWK_Pair<A>, A, Kid> : JWK_oct<A> & GeneratedJWKMembers<A, Kid>; };
151
+ /** `generateKey` return type for `TAlg` under `TOptions`; JWKs when `toJWK` is `true`. */
152
+ export type GenerateKeyReturn<TAlg extends GenerateKeyAlgorithm, TOptions extends GenerateKeyOptions> = GeneratedKeyShape<TAlg, Exclude<TOptions["toJWK"], undefined>, GeneratedKid<TOptions>>;
153
+ /** `generateJWK` return type for `TAlg` under the `kid` option `Kid`. */
154
+ export type GenerateJWKReturn<TAlg extends GenerateKeyAlgorithm, Kid extends string | false = string> = GeneratedJWKMap<Kid>[TAlg];
155
+ /** What `importKey` resolves to per input: bytes and `oct` JWKs to raw bytes, a `CryptoKey` as is, asymmetric JWKs to a `CryptoKey`. */
156
+ export interface ImportedKeyMap {
157
+ bytes: Uint8Array<ArrayBuffer>;
158
+ oct: Uint8Array<ArrayBuffer>;
159
+ cryptoKey: CryptoKey;
160
+ asymmetric: CryptoKey;
161
+ }
162
+ /** `ImportedKeyMap` entry for key input `K`; a union input yields a union. */
163
+ export type ImportedKey<K> = ImportedKeyMap[K extends Uint8Array ? "bytes" : K extends CryptoKey ? "cryptoKey" : K extends JWK_oct ? "oct" : "asymmetric"];
164
+ /** Options for `deriveKeyFromPassword`. */
165
+ export interface DeriveKeyOptions {
166
+ alg: JWK_PBES2;
167
+ /** Salt (p2s), bytes or UTF-8 text; at least 8 octets (RFC 7518 §4.8.1.1). */
168
+ salt: string | Uint8Array<ArrayBuffer>;
169
+ /** Iteration count (p2c), a positive integer. */
99
170
  iterations: number;
100
- /** Key usages for the derived key. Defaults to ["wrapKey", "unwrapKey"]. */
171
+ /** Key usages. Default: `["wrapKey", "unwrapKey"]`. */
101
172
  keyUsage?: KeyUsage[];
102
- /** Mark the derived key as extractable. Defaults to false. Ignored when `toJWK` is set — the JWK output requires exporting the derived key. */
173
+ /** Mark the derived key extractable; ignored when `toJWK` is set. Default: `false`. */
103
174
  extractable?: boolean;
104
- /**
105
- * Export the derived key as JWK_oct. When `true`, returns the derived key in
106
- * JWK format. To include additional JWK parameters (e.g. a custom `kid`),
107
- * use {@link deriveJWKFromPassword} instead.
108
- */
175
+ /** Return the derived key as a `JWK_oct`. */
109
176
  toJWK?: boolean;
110
177
  }
111
- /** PBES2 → AES-KW alg that ends up stamped on the derived JWK's `alg`. */
178
+ /** PBES2 → AES-KW `alg` stamped on the derived JWK. */
112
179
  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;
114
- type KeyManagementAlgorithm = JWK_RSA_ENC | JWK_AES_KW | JWK_AES_GCM | JWK_AES_GCM_KW | JWK_PBES2 | JWK_ECDH_ES | "dir";
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;
132
- /** Options for the wrapKey function. */
133
- interface WrapKeyOptions {
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
- */
180
+ export 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;
181
+ export type KeyManagementAlgorithm = JWK_RSA_ENC | JWK_AES_KW | JWK_AES_GCM | JWK_AES_GCM_KW | JWK_PBES2 | JWK_ECDH_ES | "dir";
182
+ export type ContentEncryptionAlgorithm = JWK_AES_GCM | JWK_AES_CBC_HMAC;
183
+ /** Keys admissible as the `wrappingKey` of `wrapKey` for algorithm `A`; `dir` takes any symmetric key. */
184
+ export 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 extends "dir" ? CryptoKey | JWK_oct | Uint8Array<ArrayBuffer> : never;
185
+ /** Private-side counterpart of `WrappingKeyFor`, for the `unwrappingKey` of `unwrapKey`. */
186
+ export 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 extends "dir" ? CryptoKey | JWK_oct | Uint8Array<ArrayBuffer> : never;
187
+ /** Options for `wrapKey`. */
188
+ export interface WrapKeyOptions<TAlg extends KeyManagementAlgorithm = KeyManagementAlgorithm> {
189
+ alg: TAlg;
190
+ /** AES-GCMKW IV, random when omitted; never reuse one under the same key (tests and known vectors only). */
143
191
  iv?: Uint8Array<ArrayBuffer>;
144
192
  /** PBES2 Salt value (p2s). Required for PBES2 algorithms. */
145
193
  p2s?: Uint8Array<ArrayBuffer>;
146
194
  /** PBES2 Iteration count (p2c). Required for PBES2 algorithms. */
147
195
  p2c?: number;
148
- /** ECDH-ES specific options. */
149
196
  ecdh?: {
150
- /**
151
- * ECDH-ES ephemeral key material. A fresh ephemeral key pair is generated
152
- * automatically when this is not provided.
153
- */
154
- ephemeralKey?: CryptoKey | JWK_EC_Private | CryptoKeyPair | {
155
- publicKey: CryptoKey | JWK_EC_Public;
156
- privateKey: CryptoKey | JWK_EC_Private;
157
- }; /** Agreement PartyUInfo (apu). */
158
- partyUInfo?: Uint8Array<ArrayBuffer>; /** Agreement PartyVInfo (apv). */
197
+ /** Ephemeral key material. Generated when omitted. */
198
+ ephemeralKey?: ECDHEphemeralKeyInput;
199
+ /** Agreement PartyUInfo (apu). */
200
+ partyUInfo?: Uint8Array<ArrayBuffer>;
201
+ /** Agreement PartyVInfo (apv). */
159
202
  partyVInfo?: Uint8Array<ArrayBuffer>;
160
- /**
161
- * Content encryption algorithm used for key-length derivation.
162
- * Required only when `alg` is `"ECDH-ES"` (direct key agreement).
163
- * Not needed for `ECDH-ES+A128KW`, `+A192KW`, or `+A256KW`.
164
- */
203
+ /** Required only for direct `"ECDH-ES"` key agreement. */
165
204
  enc?: ContentEncryptionAlgorithm;
166
205
  };
167
206
  }
168
- /**
169
- * Result of {@link wrapKey}, discriminated by key management algorithm family.
170
- *
171
- * Narrow the shape by passing a literal `alg` to `wrapKey`:
172
- * - PBES2 → `{ encryptedKey, p2s, p2c }`
173
- * - AES-GCMKW → `{ encryptedKey, iv, tag }`
174
- * - ECDH-ES / ECDH-ES+A*KW → `{ encryptedKey, epk, apu?, apv? }`
175
- * - dir / AES-KW / RSA-OAEP → `{ encryptedKey }`
176
- */
177
- type WrapKeyResult<TAlg extends KeyManagementAlgorithm = KeyManagementAlgorithm> = TAlg extends JWK_PBES2 ? {
178
- encryptedKey: Uint8Array<ArrayBuffer>; /** PBES2 Salt value (p2s). Base64URL encoded. */
179
- p2s: string; /** PBES2 Iteration count (p2c). */
207
+ /** Result of `wrapKey`, shaped by the `alg` family; string members are base64url. */
208
+ export type WrapKeyResult<TAlg extends KeyManagementAlgorithm = KeyManagementAlgorithm> = TAlg extends JWK_PBES2 ? {
209
+ encryptedKey: Uint8Array<ArrayBuffer>;
210
+ p2s: string;
180
211
  p2c: number;
181
212
  } : TAlg extends JWK_AES_GCM_KW ? {
182
- encryptedKey: Uint8Array<ArrayBuffer>; /** AES-GCMKW Initialization Vector. Base64URL encoded. */
183
- iv: string; /** AES-GCMKW Authentication Tag. Base64URL encoded. */
213
+ encryptedKey: Uint8Array<ArrayBuffer>;
214
+ iv: string;
184
215
  tag: string;
185
216
  } : TAlg extends JWK_ECDH_ES ? {
186
- encryptedKey: Uint8Array<ArrayBuffer>; /** Ephemeral Public Key. */
187
- epk: JWK_EC_Public; /** Agreement PartyUInfo. Base64URL encoded. Present only when supplied. */
188
- apu?: string; /** Agreement PartyVInfo. Base64URL encoded. Present only when supplied. */
217
+ encryptedKey: Uint8Array<ArrayBuffer>;
218
+ epk: JWK_EC_Public | JWK_OKP_Public;
219
+ apu?: string;
189
220
  apv?: string;
190
221
  } : {
191
222
  encryptedKey: Uint8Array<ArrayBuffer>;
192
223
  };
193
- /** Options for the unwrapKey function. */
194
- interface UnwrapKeyOptions {
195
- /**
196
- * Output format of the unwrapped key.
197
- * - `"cryptokey"` (default) — returns a `CryptoKey` ready for use with WebCrypto.
198
- * - `"raw"` — returns the raw key bytes as `Uint8Array` (useful for
199
- * interoperability or when the algorithm is not directly importable).
200
- */
224
+ /** Options for `unwrapKey`. */
225
+ export interface UnwrapKeyOptions<TAlg extends KeyManagementAlgorithm = KeyManagementAlgorithm> {
226
+ alg: TAlg;
227
+ /** `"cryptokey"` returns a `CryptoKey`, `"raw"` the key bytes. Default: `"cryptokey"`. */
201
228
  format?: "cryptokey" | "raw";
202
- /** Initialization Vector (required for AES-GCMKW). Base64URL encoded or Uint8Array. */
229
+ /** Required for AES-GCMKW; base64url or bytes. */
203
230
  iv?: Uint8Array<ArrayBuffer> | string;
204
- /** Authentication Tag (required for AES-GCMKW). Base64URL encoded or Uint8Array. */
231
+ /** Required for AES-GCMKW; base64url or bytes. */
205
232
  tag?: Uint8Array<ArrayBuffer> | string;
206
- /** PBES2 Salt value (required for PBES2). Base64URL encoded or Uint8Array. */
233
+ /** Required for PBES2; base64url or bytes. */
207
234
  p2s?: Uint8Array<ArrayBuffer> | string;
208
- /** PBES2 Iteration count (required for PBES2). */
235
+ /** Required for PBES2. */
209
236
  p2c?: number;
210
237
  /** Minimum accepted PBES2 `p2c` on unwrap. Defaults to 1000 (RFC 7518 §4.8.1.2). */
211
238
  minIterations?: number;
212
- /** Maximum accepted PBES2 `p2c` on unwrap. Defaults to 1_000_000 to cap PBKDF2 DoS potential. */
239
+ /** Maximum accepted PBES2 `p2c` on unwrap. Default: `600_000`. */
213
240
  maxIterations?: number;
214
- /** ECDH-ES Ephemeral Public Key (required for ECDH-ES). */
215
- epk?: JWK_EC_Public | CryptoKey;
216
- /** ECDH-ES Agreement PartyUInfo. Base64URL encoded or Uint8Array. */
241
+ /** Required for ECDH-ES. */
242
+ epk?: JWK_EC_Public | JWK_OKP_Public | CryptoKey;
217
243
  apu?: Uint8Array<ArrayBuffer> | string;
218
- /** ECDH-ES Agreement PartyVInfo. Base64URL encoded or Uint8Array. */
219
244
  apv?: Uint8Array<ArrayBuffer> | string;
220
- /** Content Encryption Algorithm used with ECDH-ES (required for direct key agreement). */
245
+ /** Required for direct ECDH-ES key agreement. */
221
246
  enc?: ContentEncryptionAlgorithm;
222
- /** Expected unwrapped key algorithm (e.g., 'AES-GCM', 'AES-CBC'). Used by crypto.subtle.unwrapKey. */
247
+ /** Algorithm to import the unwrapped key as. */
223
248
  unwrappedKeyAlgorithm?: string | Algorithm | RsaOaepParams | AesCtrParams | AesCbcParams | AesGcmParams;
224
- /** Expected key usages for the unwrapped key. */
225
249
  keyUsage?: KeyUsage[];
226
- /** Mark the unwrapped key as extractable. Defaults to true. */
250
+ /** Mark the unwrapped key extractable. Default: `true`. */
227
251
  extractable?: boolean;
228
252
  }
229
- /**
230
- * Forked from https://github.com/panva/jose/tree/v6.0.10
231
- * Copyright (c) 2018 Filip Skokan.
232
- * LICENSE: https://github.com/panva/jose/blob/v6.0.10/LICENSE.md
233
- */
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> {
253
+ /** Result of `unwrapKey`: bytes for `format: "raw"`, else a `CryptoKey`; a non-literal `format` keeps both. */
254
+ export type UnwrapKeyResult<TOptions extends {
255
+ format?: "cryptokey" | "raw";
256
+ }> = "format" extends keyof TOptions ? [TOptions["format"]] extends ["raw"] ? Uint8Array<ArrayBuffer> : [TOptions["format"]] extends ["cryptokey" | undefined] ? CryptoKey : CryptoKey | Uint8Array<ArrayBuffer> : CryptoKey;
257
+ /** Forked from https://github.com/panva/jose/tree/v6.0.10, Copyright (c) 2018 Filip Skokan, LICENSE: https://github.com/panva/jose/blob/v6.0.10/LICENSE.md */
258
+ /** Generic JWK parameters; `Alg` constrains the `alg` member. */
259
+ export interface JWKParameters<Alg extends string = string> {
243
260
  /** JWK "kty" (Key Type) Parameter */
244
- kty: string;
245
- /**
246
- * JWK "alg" (Algorithm) Parameter
247
- *
248
- * @see {@link https://github.com/panva/jose/issues/210 Algorithm Key Requirements}
249
- */
250
- alg?: Alg;
261
+ "kty": string;
262
+ /** JWK "alg" (Algorithm) Parameter */
263
+ "alg"?: Alg;
251
264
  /** JWK "key_ops" (Key Operations) Parameter */
252
- key_ops?: KeyUsage[];
265
+ "key_ops"?: KeyUsage[];
253
266
  /** JWK "ext" (Extractable) Parameter */
254
- ext?: boolean;
267
+ "ext"?: boolean;
255
268
  /** JWK "use" (Public Key Use) Parameter */
256
- use?: string;
269
+ "use"?: string;
257
270
  /** JWK "x5c" (X.509 Certificate Chain) Parameter */
258
- x5c?: string[];
271
+ "x5c"?: string[];
259
272
  /** JWK "x5t" (X.509 Certificate SHA-1 Thumbprint) Parameter */
260
- x5t?: string;
273
+ "x5t"?: string;
261
274
  /** JWK "x5t#S256" (X.509 Certificate SHA-256 Thumbprint) Parameter */
262
275
  "x5t#S256"?: string;
263
276
  /** JWK "x5u" (X.509 URL) Parameter */
264
- x5u?: string;
277
+ "x5u"?: string;
265
278
  /** JWK "kid" (Key ID) Parameter */
266
- kid?: string;
267
- /**
268
- * Non-standard JWK content encryption algorithm hint.
269
- * When `alg` is `"dir"`, the library reads this field to infer the
270
- * content encryption algorithm (`enc`) when it is not provided in options.
271
- */
272
- enc?: ContentEncryptionAlgorithm;
273
- }
279
+ "kid"?: string;
280
+ /** Non-standard `enc` hint, read when `alg` is `"dir"` and no `enc` option is given. */
281
+ "enc"?: ContentEncryptionAlgorithm;
282
+ }
283
+ /** JWK members a caller may set on a produced key: all but `alg`, `kty`, `key_ops` and `ext`. */
284
+ export type JWKMetadata = Omit<JWKParameters, "alg" | "kty" | "key_ops" | "ext">;
285
+ /** ECDH-ES ephemeral key material: a private key, a `CryptoKeyPair`, or an object with both halves. */
286
+ export type ECDHEphemeralKeyInput = CryptoKey | JWK_EC_Private | JWK_OKP_Private | CryptoKeyPair | {
287
+ publicKey: CryptoKey | JWK_EC_Public | JWK_OKP_Public;
288
+ privateKey: CryptoKey | JWK_EC_Private | JWK_OKP_Private;
289
+ };
274
290
  /** Public EC JSON Web Keys */
275
- interface JWK_EC_Public<Alg extends JWK_ECDSA | JWK_ECDH_ES | (string & {}) = string> extends JWKParameters<Alg> {
276
- /** EC JWK "kty" (Key Type) Parameter */
291
+ export interface JWK_EC_Public<Alg extends JWK_ECDSA | JWK_ECDH_ES | (string & {}) = string> extends JWKParameters<Alg> {
277
292
  kty: "EC";
278
293
  /** EC JWK "crv" (Curve) Parameter */
279
294
  crv: string;
@@ -283,15 +298,14 @@ interface JWK_EC_Public<Alg extends JWK_ECDSA | JWK_ECDH_ES | (string & {}) = st
283
298
  y: string;
284
299
  }
285
300
  /** Private EC JSON Web Keys */
286
- interface JWK_EC_Private<Alg extends JWK_ECDSA | JWK_ECDH_ES | (string & {}) = string> extends JWK_EC_Public<Alg> {
301
+ export interface JWK_EC_Private<Alg extends JWK_ECDSA | JWK_ECDH_ES | (string & {}) = string> extends JWK_EC_Public<Alg> {
287
302
  /** EC JWK "d" (ECC Private Key) Parameter */
288
303
  d: string;
289
304
  }
290
305
  /** EC JSON Web Keys */
291
- type JWK_EC<Alg extends JWK_ECDSA | JWK_ECDH_ES | (string & {}) = string> = JWK_EC_Public<Alg> | JWK_EC_Private<Alg>;
306
+ export type JWK_EC<Alg extends JWK_ECDSA | JWK_ECDH_ES | (string & {}) = string> = JWK_EC_Public<Alg> | JWK_EC_Private<Alg>;
292
307
  /** Public RSA JSON Web Keys */
293
- interface JWK_RSA_Public<Alg extends JWK_RSA_SIGN | JWK_RSA_PSS | JWK_RSA_ENC | (string & {}) = string> extends JWKParameters<Alg> {
294
- /** RSA JWK "kty" (Key Type) Parameter */
308
+ export interface JWK_RSA_Public<Alg extends JWK_RSA_SIGN | JWK_RSA_PSS | JWK_RSA_ENC | (string & {}) = string> extends JWKParameters<Alg> {
295
309
  kty: "RSA";
296
310
  /** RSA JWK "e" (Exponent) Parameter */
297
311
  e: string;
@@ -300,7 +314,7 @@ interface JWK_RSA_Public<Alg extends JWK_RSA_SIGN | JWK_RSA_PSS | JWK_RSA_ENC |
300
314
  oth?: RsaOtherPrimesInfo[];
301
315
  }
302
316
  /** Private RSA JSON Web Keys */
303
- interface JWK_RSA_Private<Alg extends JWK_RSA_SIGN | JWK_RSA_PSS | JWK_RSA_ENC | (string & {}) = string> extends JWK_RSA_Public<Alg> {
317
+ export interface JWK_RSA_Private<Alg extends JWK_RSA_SIGN | JWK_RSA_PSS | JWK_RSA_ENC | (string & {}) = string> extends JWK_RSA_Public<Alg> {
304
318
  /** RSA JWK "d" (Private Exponent) Parameter */
305
319
  d: string;
306
320
  /** RSA JWK "dp" (First Factor CRT Exponent) Parameter */
@@ -315,10 +329,9 @@ interface JWK_RSA_Private<Alg extends JWK_RSA_SIGN | JWK_RSA_PSS | JWK_RSA_ENC |
315
329
  qi: string;
316
330
  }
317
331
  /** RSA JSON Web Keys */
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>;
332
+ export type JWK_RSA<Alg extends JWK_RSA_SIGN | JWK_RSA_PSS | JWK_RSA_ENC | (string & {}) = string> = JWK_RSA_Public<Alg> | JWK_RSA_Private<Alg>;
319
333
  /** Public ED JSON Web Keys */
320
- interface JWK_OKP_Public<Alg extends JWK_OKP_SIGN | JWK_ECDH_ES | (string & {}) = string> extends JWKParameters<Alg> {
321
- /** ED JWK "kty" (Key Type) Parameter */
334
+ export interface JWK_OKP_Public<Alg extends JWK_OKP_SIGN | JWK_ECDH_ES | (string & {}) = string> extends JWKParameters<Alg> {
322
335
  kty: "OKP";
323
336
  /** ED JWK "crv" (Curve) Parameter */
324
337
  crv: string;
@@ -326,43 +339,30 @@ interface JWK_OKP_Public<Alg extends JWK_OKP_SIGN | JWK_ECDH_ES | (string & {})
326
339
  x: string;
327
340
  }
328
341
  /** Private ED JSON Web Keys */
329
- interface JWK_OKP_Private<Alg extends JWK_OKP_SIGN | JWK_ECDH_ES | (string & {}) = string> extends JWK_OKP_Public<Alg> {
342
+ export interface JWK_OKP_Private<Alg extends JWK_OKP_SIGN | JWK_ECDH_ES | (string & {}) = string> extends JWK_OKP_Public<Alg> {
330
343
  /** ED JWK "d" (Private Key) Parameter */
331
344
  d: string;
332
345
  }
333
346
  /** OKP JSON Web Keys */
334
- type JWK_OKP<Alg extends JWK_OKP_SIGN | JWK_ECDH_ES | (string & {}) = string> = JWK_OKP_Public<Alg> | JWK_OKP_Private<Alg>;
347
+ export type JWK_OKP<Alg extends JWK_OKP_SIGN | JWK_ECDH_ES | (string & {}) = string> = JWK_OKP_Public<Alg> | JWK_OKP_Private<Alg>;
335
348
  /** oct JSON Web Keys */
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> {
349
+ export 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> {
350
+ kty: "oct";
337
351
  /** Oct JWK "k" (Key Value) Parameter */
338
352
  k: string;
339
353
  }
340
354
  /** Symmetric JSON Web Keys */
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>;
355
+ export 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>;
342
356
  /** Asymmetric JSON Web Keys */
343
- type JWK_Asymmetric<Alg extends string = string> = JWK_RSA<Alg> | JWK_EC<Alg> | JWK_OKP<Alg>;
357
+ export type JWK_Asymmetric<Alg extends string = string> = JWK_RSA<Alg> | JWK_EC<Alg> | JWK_OKP<Alg>;
344
358
  /** Public JSON Web Keys */
345
- type JWK_Public<Alg extends string = string> = JWK_RSA_Public<Alg> | JWK_EC_Public<Alg> | JWK_OKP_Public<Alg>;
359
+ export type JWK_Public<Alg extends string = string> = JWK_RSA_Public<Alg> | JWK_EC_Public<Alg> | JWK_OKP_Public<Alg>;
346
360
  /** Private JSON Web Keys */
347
- type JWK_Private<Alg extends string = string> = JWK_RSA_Private<Alg> | JWK_EC_Private<Alg> | JWK_OKP_Private<Alg>;
348
- /**
349
- * JSON Web Key ({@link https://www.rfc-editor.org/rfc/rfc7517 JWK}). "RSA", "EC", "OKP" and "oct" key types are supported.
350
- */
351
- type JWK<Alg extends string = string> = JWK_oct<Alg> | JWK_RSA<Alg> | JWK_EC<Alg> | JWK_OKP<Alg>;
352
- /**
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.
364
- */
365
- type JWK_Pair<Alg extends string = string> = Alg extends JWK_RSA_SIGN | JWK_RSA_PSS | JWK_RSA_ENC ? {
361
+ export type JWK_Private<Alg extends string = string> = JWK_RSA_Private<Alg> | JWK_EC_Private<Alg> | JWK_OKP_Private<Alg>;
362
+ /** JSON Web Key (RFC 7517) of type "RSA", "EC", "OKP" or "oct". */
363
+ export type JWK<Alg extends string = string> = JWK_oct<Alg> | JWK_RSA<Alg> | JWK_EC<Alg> | JWK_OKP<Alg>;
364
+ /** Public/private JWK pair, narrowed to the key family `Alg` identifies (ECDH-ES: EC or OKP). */
365
+ export type JWK_Pair<Alg extends string = string> = Alg extends JWK_RSA_SIGN | JWK_RSA_PSS | JWK_RSA_ENC ? {
366
366
  publicKey: JWK_RSA_Public<Alg>;
367
367
  privateKey: JWK_RSA_Private<Alg>;
368
368
  } : Alg extends JWK_ECDSA ? {
@@ -387,38 +387,49 @@ type JWK_Pair<Alg extends string = string> = Alg extends JWK_RSA_SIGN | JWK_RSA_
387
387
  publicKey: JWK_OKP_Public<Alg>;
388
388
  privateKey: JWK_OKP_Private<Alg>;
389
389
  };
390
- /**
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).
397
- */
398
- interface JWKSet<T extends readonly JWK[] = JWK[]> {
399
- /** JWK Set "keys" Parameter */
390
+ /** JSON Web Key Set (RFC 7517); `T` preserves a precise key tuple. */
391
+ export interface JWKSet<T extends readonly JWK[] = JWK[]> {
400
392
  keys: T;
401
393
  [parameter: string]: unknown;
402
394
  }
403
395
  /** JWK Key Algorithms */
404
- type JWK_HMAC = "HS256" | "HS384" | "HS512";
405
- type JWK_RSA_SIGN = "RS256" | "RS384" | "RS512";
406
- type JWK_RSA_PSS = "PS256" | "PS384" | "PS512";
407
- type JWK_ECDSA = "ES256" | "ES384" | "ES512";
408
- type JWK_RSA_ENC = "RSA-OAEP" | "RSA-OAEP-256" | "RSA-OAEP-384" | "RSA-OAEP-512";
409
- type JWK_AES_KW = "A128KW" | "A192KW" | "A256KW";
410
- type JWK_AES_CBC_HMAC = "A128CBC-HS256" | "A192CBC-HS384" | "A256CBC-HS512";
411
- type JWK_AES_GCM = "A128GCM" | "A192GCM" | "A256GCM";
412
- type JWK_AES_GCM_KW = "A128GCMKW" | "A192GCMKW" | "A256GCMKW";
413
- type JWK_PBES2 = "PBES2-HS256+A128KW" | "PBES2-HS384+A192KW" | "PBES2-HS512+A256KW";
414
- type JWK_ECDH_ES = "ECDH-ES" | "ECDH-ES+A128KW" | "ECDH-ES+A192KW" | "ECDH-ES+A256KW";
415
- type JWK_OKP_SIGN = "Ed25519" | "EdDSA";
416
- type JWK_Symmetric_Algorithm = JWK_HMAC | JWK_AES_KW | JWK_AES_GCM | JWK_AES_GCM_KW;
417
- type JWK_Asymmetric_Algorithm = JWK_RSA_SIGN | JWK_RSA_PSS | JWK_ECDSA | JWK_RSA_ENC | JWK_OKP_SIGN | JWK_ECDH_ES;
418
- type JWKAlgorithm = JWK_Symmetric_Algorithm | JWK_Asymmetric_Algorithm | JWK_AES_CBC_HMAC | JWK_PBES2 | JWK_ECDH_ES | "dir";
419
- type JWKPEMAlgorithm = JWK_RSA_PSS | JWK_RSA_SIGN | JWK_RSA_ENC | JWK_ECDSA | JWK_ECDH_ES | JWK_OKP_SIGN;
420
- /** Header Parameters common to JWE and JWS */
421
- interface JoseHeaderParameters {
396
+ export type JWK_HMAC = "HS256" | "HS384" | "HS512";
397
+ export type JWK_RSA_SIGN = "RS256" | "RS384" | "RS512";
398
+ export type JWK_RSA_PSS = "PS256" | "PS384" | "PS512";
399
+ export type JWK_ECDSA = "ES256" | "ES384" | "ES512";
400
+ export type JWK_RSA_ENC = "RSA-OAEP" | "RSA-OAEP-256" | "RSA-OAEP-384" | "RSA-OAEP-512";
401
+ export type JWK_AES_KW = "A128KW" | "A192KW" | "A256KW";
402
+ export type JWK_AES_CBC_HMAC = "A128CBC-HS256" | "A192CBC-HS384" | "A256CBC-HS512";
403
+ export type JWK_AES_GCM = "A128GCM" | "A192GCM" | "A256GCM";
404
+ export type JWK_AES_GCM_KW = "A128GCMKW" | "A192GCMKW" | "A256GCMKW";
405
+ export type JWK_PBES2 = "PBES2-HS256+A128KW" | "PBES2-HS384+A192KW" | "PBES2-HS512+A256KW";
406
+ export type JWK_ECDH_ES = "ECDH-ES" | "ECDH-ES+A128KW" | "ECDH-ES+A192KW" | "ECDH-ES+A256KW";
407
+ export type JWK_OKP_SIGN = "Ed25519" | "EdDSA";
408
+ export type JWK_Symmetric_Algorithm = JWK_HMAC | JWK_AES_KW | JWK_AES_GCM | JWK_AES_GCM_KW;
409
+ export type JWK_Asymmetric_Algorithm = JWK_RSA_SIGN | JWK_RSA_PSS | JWK_ECDSA | JWK_RSA_ENC | JWK_OKP_SIGN | JWK_ECDH_ES;
410
+ export type JWKAlgorithm = JWK_Symmetric_Algorithm | JWK_Asymmetric_Algorithm | JWK_AES_CBC_HMAC | JWK_PBES2 | JWK_ECDH_ES | "dir";
411
+ export type JWKPEMAlgorithm = JWK_RSA_PSS | JWK_RSA_SIGN | JWK_RSA_ENC | JWK_ECDSA | JWK_ECDH_ES | JWK_OKP_SIGN;
412
+ type GeneratedJWKMembers<A, Kid> = [Kid] extends [false] ? {
413
+ alg: A;
414
+ } : [Kid] extends [string] ? {
415
+ alg: A;
416
+ kid: string;
417
+ } : {
418
+ alg: A;
419
+ kid?: string;
420
+ };
421
+ type GeneratedJWKPair<P, A, Kid> = P extends {
422
+ privateKey: infer Private;
423
+ publicKey: infer Public;
424
+ } ? {
425
+ privateKey: Private & GeneratedJWKMembers<A, Kid>;
426
+ publicKey: Public & GeneratedJWKMembers<A, Kid>;
427
+ } : never;
428
+ type GeneratedKid<TOptions> = "kid" extends keyof TOptions ? ThumbprintIfUnset<Extract<TOptions["kid" & keyof TOptions], string | false>> : string;
429
+ type ThumbprintIfUnset<Kid extends string | false> = [Kid] extends [never] ? string : Kid;
430
+ type GeneratedKeyShape<TAlg extends GenerateKeyAlgorithm, ToJWK, Kid extends string | false> = [ToJWK] extends [never] ? GeneratedKeyMap[TAlg] : ToJWK extends true ? GeneratedJWKMap<Kid>[TAlg] : GeneratedKeyMap[TAlg];
431
+ /** Header Parameters common to JWE and JWS. */
432
+ export interface JoseHeaderParameters {
422
433
  /** "kid" (Key ID) Header Parameter */
423
434
  kid?: string;
424
435
  /** "x5t" (X.509 Certificate SHA-1 Thumbprint) Header Parameter */
@@ -437,19 +448,21 @@ interface JoseHeaderParameters {
437
448
  cty?: string;
438
449
  /** "crit" (Critical) Header Parameter */
439
450
  crit?: string[];
440
- /** Any other JWS/JWE Header member. */
441
451
  [propName: string]: unknown;
442
452
  }
443
- /**
444
- * Payload accepted by {@link sign} and {@link encrypt}.
445
- *
446
- * Covers raw strings and bytes for non-JWT use, plus any JSON-serializable
447
- * object for JWT and generic structured payloads. JWT-specific claim names
448
- * are not enforced at this level — use {@link JWTClaims} when you want typed
449
- * claim names and spec-compliant field types.
450
- */
451
- type JOSEPayload = string | Uint8Array<ArrayBuffer> | Record<string, unknown>;
452
- interface JWTClaims {
453
+ /** Payload accepted by `sign` and `encrypt`: a string, raw bytes, or a JSON object. */
454
+ export type JOSEPayload = string | Uint8Array<ArrayBuffer> | Record<string, unknown>;
455
+ /** How a verified or decrypted payload is decoded: `"json"` object, UTF-8 `"string"`, or raw `"bytes"`. */
456
+ export type JOSEPayloadMode = keyof JOSEPayloadTypeMap;
457
+ /** The payload type each `JOSEPayloadMode` resolves to. */
458
+ export interface JOSEPayloadTypeMap<T = JWTClaims> {
459
+ json: T;
460
+ string: string;
461
+ bytes: Uint8Array<ArrayBuffer>;
462
+ }
463
+ /** The payload type returned under `Mode`; a union of modes yields the union of payloads. */
464
+ export type PayloadOf<Mode extends JOSEPayloadMode, T = JWTClaims> = JOSEPayloadTypeMap<T>[Mode];
465
+ export interface JWTClaims {
453
466
  /** "iss" (Issuer) Claim */
454
467
  iss?: string;
455
468
  /** "sub" (Subject) Claim */
@@ -464,679 +477,360 @@ interface JWTClaims {
464
477
  iat?: number;
465
478
  /** "jti" (JWT ID) Claim */
466
479
  jti?: string;
467
- /** Any other JWT member. */
468
480
  [propName: string]: unknown;
469
481
  }
470
- interface JWT<T = JWTClaims> {
482
+ export interface JWT<T = JWTClaims> {
471
483
  header: JoseHeaderParameters & {
472
- /** "alg" (Algorithm) Header Parameter */alg: string;
484
+ /** "alg" (Algorithm) Header Parameter */
485
+ alg: string;
473
486
  };
474
487
  claims: T;
475
488
  }
476
- interface JWTClaimValidationOptions {
477
- /** Expected JWT "aud" (Audience) Claim value(s). Implies presence requirement. */
489
+ /** Per-call work bounds; each entry must be a positive integer, else `ERR_INVALID_OPTION`. */
490
+ export interface JOSELimits {
491
+ /** Max `signatures[]` entries in a JWS JSON serialization. @default 16 */
492
+ signatures?: number;
493
+ /** Max `recipients[]` entries in a JWE JSON serialization. @default 16 */
494
+ recipients?: number;
495
+ /** Max JWK Set candidates tried per token after `kid`/`alg`/`use` filtering. @default 8 */
496
+ keyCandidates?: number;
497
+ /** Total PBKDF2 iterations one call may spend across PBES2 attempts. @default 2_400_000 */
498
+ pbes2Iterations?: number;
499
+ }
500
+ /** Claim expectations, each checked when set; an empty or malformed value is `ERR_INVALID_OPTION`. */
501
+ export interface JWTClaimValidationOptions {
502
+ /** Expected "aud" value(s); `aud` is checked only when this is set (RFC 7519 §4.1.3). */
478
503
  audience?: string | string[];
479
- /** Expected JWT "iss" (Issuer) Claim value(s). Implies presence requirement. */
504
+ /** Expected "iss" value(s); implies presence. */
480
505
  issuer?: string | string[];
481
- /** Expected JWT "sub" (Subject) Claim value. Implies presence requirement. */
506
+ /** Expected "sub" value; implies presence. */
482
507
  subject?: string;
483
- /** Maximum token age, from the JWT "iat" (Issued At) Claim value. Implies presence requirement. */
508
+ /** Maximum token age from "iat"; implies presence. */
484
509
  maxTokenAge?: MaxTokenAge;
485
- /**
486
- * Clock skew tolerance (in seconds) for validating time-based claims (nbf/exp/iat).
487
- *
488
- * @default 0
489
- */
490
- clockTolerance?: number;
491
- /** Expected JWT "typ" (Type) Header Parameter value. Implies presence requirement. */
510
+ /** Clock skew tolerance for nbf/exp/iat, in seconds or a `Duration`. @default 0 */
511
+ clockTolerance?: number | Duration;
512
+ /** Expected "typ" header, compared as a media type (RFC 7515 §4.1.9); implies presence. */
492
513
  typ?: string;
493
- /** Date to use when comparing NumericDate claims, defaults to `new Date()`. */
514
+ /** Date used for NumericDate comparisons. @default new Date() */
494
515
  currentDate?: Date;
495
516
  /** Additional required claim names. */
496
517
  requiredClaims?: string[];
497
- /**
498
- * Critical header parameters that this caller understands and has processed.
499
- * If the token's `crit` header lists a parameter not present in this list
500
- * (and not natively understood by the library), verification will fail per
501
- * RFC 7515 §4.1.11 / RFC 7516 §4.1.13.
502
- */
518
+ /** `crit` header parameters the caller understands (RFC 7515 §4.1.11, RFC 7516 §4.1.13). */
503
519
  recognizedHeaders?: string[];
504
520
  }
505
- /**
506
- * All known error codes thrown by unjwt.
507
- *
508
- * Code naming follows the JOSE spec hierarchy:
509
- * ERR_JWT_* — RFC 7519 JSON Web Token claim validation
510
- * ERR_JWS_* — RFC 7515 JSON Web Signature
511
- * ERR_JWE_* — RFC 7516 JSON Web Encryption
512
- * ERR_JWK_* — RFC 7517 JSON Web Key
513
- */
514
- type JWTErrorCode = "ERR_JWT_EXPIRED" | "ERR_JWT_NBF" | "ERR_JWT_CLAIM_INVALID" | "ERR_JWT_CLAIM_MISSING" | "ERR_JWS_INVALID" | "ERR_JWS_INVALID_SERIALIZATION" | "ERR_JWS_SIGNATURE_INVALID" | "ERR_JWS_ALG_NOT_ALLOWED" | "ERR_JWS_ALG_MISSING" | "ERR_JWS_SIGNER_ALG_INFERENCE" | "ERR_JWS_NO_MATCHING_SIGNER" | "ERR_JWS_HEADER_PARAMS_NOT_DISJOINT" | "ERR_JWS_B64_INCONSISTENT" | "ERR_JWE_INVALID" | "ERR_JWE_INVALID_SERIALIZATION" | "ERR_JWE_DECRYPTION_FAILED" | "ERR_JWE_ALG_NOT_ALLOWED" | "ERR_JWE_ALG_MISSING" | "ERR_JWE_ALG_FORBIDDEN_IN_MULTI" | "ERR_JWE_ENC_MISSING" | "ERR_JWE_RECIPIENT_ALG_INFERENCE" | "ERR_JWE_NO_MATCHING_RECIPIENT" | "ERR_JWE_HEADER_PARAMS_NOT_DISJOINT" | "ERR_JWK_INVALID" | "ERR_JWK_KEY_NOT_FOUND" | "ERR_JWK_UNSUPPORTED" | (string & {});
515
- /**
516
- * Maps known error codes to their structured `cause` shapes.
517
- * Only codes that carry decoded context beyond the message appear here.
518
- * Extend this interface when new structured causes are introduced.
519
- */
520
- interface JWTErrorCauseMap {
521
- /** Decoded claims available at the point the lifetime check failed. */
522
- ERR_JWT_EXPIRED: {
523
- jti?: string;
524
- iat?: number;
525
- exp?: number;
526
- };
521
+ /** Time claims a producer computes; a claim already in the payload is kept as given. */
522
+ export interface JWTTimeClaimOptions {
523
+ /** Reference moment for `iat` and relative durations. @default new Date() */
524
+ currentDate?: Date;
525
+ /** Duration until `exp`; exclusive with `expiresAt`. */
526
+ expiresIn?: ExpiresIn;
527
+ /** Absolute `exp`; exclusive with `expiresIn`. */
528
+ expiresAt?: Date;
529
+ /** Duration from `iat` until `nbf` (`0` sets `nbf = iat`); exclusive with `notBeforeAt`. */
530
+ notBeforeIn?: ExpiresIn;
531
+ /** Absolute `nbf` (RFC 7519 §4.1.5); exclusive with `notBeforeIn`. */
532
+ notBeforeAt?: Date;
527
533
  }
528
- /**
529
- * Base error class for all unjwt errors. Every error thrown by the library is
530
- * an instance of `JWTError`, so a single `instanceof` check is sufficient to
531
- * distinguish library errors from other thrown values. Use the `code` property
532
- * (or the `isJWTError` type guard) to narrow to a specific error condition.
533
- *
534
- * @example
535
- * import { JWTError, isJWTError } from "unjwt/jws";
536
- *
537
- * try {
538
- * await verify(token, key);
539
- * } catch (err) {
540
- * if (isJWTError(err, "ERR_JWT_EXPIRED")) {
541
- * console.log(err.cause.jti); // string | undefined
542
- * }
543
- * }
544
- */
545
- declare class JWTError<TCode extends JWTErrorCode = JWTErrorCode> extends Error {
546
- readonly code: TCode;
547
- override readonly cause?: unknown;
548
- constructor(message: string, code: TCode, cause?: unknown);
534
+ /** Options shared by `verify` and `decrypt` (compact and multi). */
535
+ export interface JOSEConsumerOptions<Mode extends JOSEPayloadMode = JOSEPayloadMode> extends JWTClaimValidationOptions {
536
+ /** Admit `oct` entries of a JWK Set as key material; only for application-controlled sets. @default false */
537
+ allowSymmetricJWKSet?: boolean;
538
+ /** Payload decoding mode; a mismatch is `ERR_JWS_INVALID` / `ERR_JWE_INVALID`. @default "json" */
539
+ payload?: Mode;
540
+ /**
541
+ * If true, forces the payload to be returned as a `Uint8Array`.
542
+ *
543
+ * @deprecated Use `payload: "bytes"`. Deprecated in v0.8.0, removed in v0.9.0
544
+ */
545
+ forceUint8Array?: boolean;
546
+ /** `false` skips claim validation; `true` with a non-`"json"` payload is `ERR_INVALID_OPTION`. */
547
+ validateClaims?: boolean;
549
548
  }
550
- /**
551
- * Type guard that narrows `error` to `JWTError`.
552
- *
553
- * When called with a code that is a key of `JWTErrorCauseMap`, the return
554
- * type is additionally narrowed to include the structured `cause` shape for
555
- * that code. When called with any other `JWTErrorCode`, `code` is narrowed
556
- * but `cause` remains `unknown`. When called without a code, narrows only to
557
- * `JWTError`.
558
- *
559
- * @example
560
- * if (isJWTError(err, "ERR_JWT_EXPIRED")) {
561
- * err.cause.jti // string | undefined ✓
562
- * }
563
- */
564
- declare function isJWTError<T extends keyof JWTErrorCauseMap>(error: unknown, code: T): error is JWTError<T> & {
565
- cause: JWTErrorCauseMap[T];
566
- };
567
- declare function isJWTError<T extends JWTErrorCode>(error: unknown, code: T): error is JWTError<T>;
568
- declare function isJWTError(error: unknown): error is JWTError;
569
- type StrictOmit<T, K extends keyof T | (string & {}) | (number & {}) | (symbol & {})> = { [P in keyof T as P extends K ? never : P]: T[P] };
549
+ export type StrictOmit<T, K extends keyof T | (string & {}) | (number & {}) | (symbol & {})> = { [P in keyof T as P extends K ? never : P]: T[P]; };
570
550
  /** JWS Signing Algorithm Identifier. */
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;
598
- /** Recognized JWS Header Parameters, any other Header Members may also be present. */
599
- interface JWSHeaderParameters extends JoseHeaderParameters {
551
+ export type JWSAlgorithm = JWK_HMAC | JWK_RSA_SIGN | JWK_RSA_PSS | JWK_ECDSA | JWK_OKP_SIGN;
552
+ /** Asymmetric private JWKs admissible as a signing key. */
553
+ export type JWSAsymmetricPrivateJWK = JWK_RSA_Private<JWK_RSA_SIGN | JWK_RSA_PSS> | JWK_EC_Private<JWK_ECDSA> | JWK_OKP_Private<JWK_OKP_SIGN>;
554
+ /** Asymmetric public JWKs admissible as a verification key. */
555
+ export type JWSAsymmetricPublicJWK = JWK_RSA_Public<JWK_RSA_SIGN | JWK_RSA_PSS> | JWK_EC_Public<JWK_ECDSA> | JWK_OKP_Public<JWK_OKP_SIGN>;
556
+ /** JWKs admissible as a `sign` key; a non-signing `alg` is a type error. */
557
+ export type JWSSignJWK = JWK_oct<JWK_HMAC> | JWSAsymmetricPrivateJWK;
558
+ /** JWKs admissible as a `verify` key; a non-signing `alg` is a type error. */
559
+ export type JWSVerifyJWK = JWK_oct<JWK_HMAC> | JWSAsymmetricPublicJWK;
560
+ /** Recognized JWS Header Parameters; other members may be present. */
561
+ export interface JWSHeaderParameters extends JoseHeaderParameters {
600
562
  /** JWS "alg" (Algorithm) Header Parameter */
601
563
  alg?: JWSAlgorithm;
602
- /**
603
- * This JWS Extension Header Parameter modifies the JWS Payload representation and the JWS Signing
604
- * Input computation as per {@link https://www.rfc-editor.org/rfc/rfc7797 RFC7797}.
605
- * If `false`, the payload is used directly without Base64URL encoding.
606
- * Defaults to `true`.
607
- */
564
+ /** `false` signs the payload unencoded (RFC 7797). @default true */
608
565
  b64?: boolean;
609
566
  }
610
567
  /** JWS Protected Header */
611
- interface JWSProtectedHeader extends JWSHeaderParameters {
568
+ export interface JWSProtectedHeader extends JWSHeaderParameters {
612
569
  alg: JWSAlgorithm;
613
570
  }
614
- /**
615
- * JWS (JSON Web Signature) options for signing
616
- */
617
- interface JWSSignOptions {
618
- /** The JWS Algorithm to use. Must be provided. */
571
+ /** Options for `sign`. */
572
+ export interface JWSSignOptions extends JWTTimeClaimOptions {
573
+ /** JWS algorithm; inferred from the key when omitted. */
619
574
  alg?: JWSAlgorithm;
620
- /**
621
- * Additional protected header parameters. `alg` is always derived from the top-level `alg`
622
- * option (or inferred from the key) and cannot be overridden. `typ` defaults to `"JWT"`
623
- * when the payload is a JSON object.
624
- */
575
+ /** Extra protected header parameters; `alg` cannot be set, `typ` defaults to `"JWT"` for an object payload. */
625
576
  protectedHeader?: StrictOmit<JWSHeaderParameters, "alg"> & {
626
577
  alg?: never;
627
578
  };
628
- /** Date to use when comparing NumericDate claims, defaults to `new Date()`. */
629
- currentDate?: Date;
630
- /**
631
- * Duration until the JWS should expire, relative to `currentDate` (or `new Date()`).
632
- * Skipped when the payload already carries an `exp` claim.
633
- *
634
- * Mutually exclusive with {@link expiresAt}.
635
- */
636
- expiresIn?: ExpiresIn;
637
- /**
638
- * Absolute moment at which the JWS should expire (sets the `exp` claim directly).
639
- * Skipped when the payload already carries an `exp` claim.
640
- *
641
- * Mutually exclusive with {@link expiresIn}.
642
- */
643
- expiresAt?: Date;
644
- /**
645
- * Duration from `iat` before which the JWS must not be accepted.
646
- * `0` is allowed and sets `nbf = iat` (explicit temporal floor at sign time).
647
- * Skipped when the payload already carries an `nbf` claim.
648
- *
649
- * Mutually exclusive with {@link notBeforeAt}.
650
- */
651
- notBeforeIn?: ExpiresIn;
652
- /**
653
- * Absolute moment before which the JWS must not be accepted (sets the `nbf`
654
- * claim directly per RFC 7519 §4.1.5). Skipped when the payload already
655
- * carries an `nbf` claim.
656
- *
657
- * Mutually exclusive with {@link notBeforeIn}.
658
- */
659
- notBeforeAt?: Date;
660
579
  }
661
- /** Result of JWS verification */
662
- interface JWSVerifyResult<T extends JOSEPayload = JOSEPayload> {
663
- /** The decoded and verified payload. */
580
+ /** Result of JWS verification. */
581
+ export interface JWSVerifyResult<T extends JOSEPayload = JOSEPayload> {
664
582
  payload: T;
665
- /** The JWS Protected Header. */
666
583
  protectedHeader: JWSProtectedHeader;
667
584
  }
668
- /** Options for JWS verification */
669
- interface JWSVerifyOptions extends JWTClaimValidationOptions {
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
- */
585
+ /** Options for `verify`; `Mode` is the `payload` option's literal. */
586
+ export interface JWSVerifyOptions<Mode extends JOSEPayloadMode = JOSEPayloadMode> extends JOSEConsumerOptions<Mode> {
587
+ /** Allowed `alg` values; inferred from the key when omitted, required for raw secrets, alg-less JWKs and resolvers. */
676
588
  algorithms?: JWSAlgorithm[];
677
- /** If true, forces the payload to be returned as a Uint8Array, otherwise type is inferred. */
678
- forceUint8Array?: boolean;
679
- /**
680
- * Controls JWT claim validation after a successful verification.
681
- *
682
- * - `true` — always validate claims regardless of the `typ` header
683
- * - `false` — skip claim validation entirely
684
- * - `undefined` (default) — validate when `typ` is `"JWT"` or contains `"jwt"`
685
- */
686
- validateClaims?: boolean;
589
+ /** Max JWK Set candidates per token; more is `ERR_JWK_KEY_NOT_FOUND`. @default { keyCandidates: 8 } */
590
+ limits?: Pick<JOSELimits, "keyCandidates">;
687
591
  }
688
- /**
689
- * JWS Flattened JSON Serialization, RFC 7515 §7.2.2. Accepted as input by
690
- * {@link verifyMulti} and normalized to {@link JWSGeneralSerialization}
691
- * internally. Emitted by {@link generalToFlattenedJWS} on a single-signature
692
- * General serialization.
693
- */
694
- interface JWSFlattenedSerialization {
695
- /** The JWS Payload. base64url-encoded when `b64 !== false`. */
592
+ /** JWS Flattened JSON Serialization (RFC 7515 §7.2.2). */
593
+ export interface JWSFlattenedSerialization {
594
+ /** The JWS Payload; base64url-encoded unless `b64: false`. */
696
595
  payload: string;
697
- /** Base64URL-encoded JWS Protected Header (part of the signing input). */
596
+ /** Base64url-encoded JWS Protected Header. */
698
597
  protected?: string;
699
- /** JWS Unprotected Header (not part of the signing input). */
598
+ /** JWS Unprotected Header (not signed). */
700
599
  header?: JWSHeaderParameters;
701
- /** Base64URL-encoded signature bytes. */
600
+ /** Base64url-encoded signature. */
702
601
  signature: string;
703
602
  }
704
- /**
705
- * JWS General JSON Serialization, RFC 7515 §7.2.1. Canonical multi-signature
706
- * output shape of {@link signMulti}.
707
- *
708
- * `payload` is shared across all signatures and carries base64url-encoded
709
- * bytes by default. When the consistent `b64: false` signing mode is used
710
- * (RFC 7797), `payload` holds the raw UTF-8 payload string instead.
711
- */
712
- interface JWSGeneralSerialization extends Omit<JWSFlattenedSerialization, "protected" | "header" | "signature"> {
603
+ /** JWS General JSON Serialization (RFC 7515 §7.2.1). */
604
+ export interface JWSGeneralSerialization extends Omit<JWSFlattenedSerialization, "protected" | "header" | "signature"> {
713
605
  /** One entry per signer. */
714
606
  signatures: JWSGeneralSignature[];
715
607
  }
716
- /** A single signature entry within {@link JWSGeneralSerialization.signatures}. */
717
- type JWSGeneralSignature = Pick<JWSFlattenedSerialization, "protected" | "header" | "signature">;
718
- /**
719
- * Input shape for a single signer passed to {@link signMulti}.
720
- *
721
- * `alg` is inferred from `key.alg`; throws `ERR_JWS_SIGNER_ALG_INFERENCE`
722
- * when absent. `kid` is pulled from `key.kid` when present.
723
- */
724
- interface JWSMultiSigner {
725
- /** Signing key (JWK-first; `alg` inferred from `key.alg`). */
726
- key: JWSSignJWK;
727
- /**
728
- * Extra per-signer JWS Protected Header parameters (RFC 7515 §7.2.1).
729
- * `alg` is always derived from the JWK and cannot be set here. `b64`
730
- * MUST be consistent across every signer (RFC 7797 §3) — if set on one
731
- * signer it must match on all.
732
- */
608
+ /** A single entry of `JWSGeneralSerialization.signatures`. */
609
+ export type JWSGeneralSignature = Pick<JWSFlattenedSerialization, "protected" | "header" | "signature">;
610
+ /** One signer passed to `signMulti`. */
611
+ export interface JWSMultiSigner {
612
+ /** Signing key; `kid` is taken from a JWK, a `CryptoKey` must set it in `protectedHeader`. */
613
+ key: JWSSignJWK | CryptoKey;
614
+ /** JWS algorithm; inferred from the key when possible, else `ERR_JWS_SIGNER_ALG_INFERENCE`. */
615
+ alg?: JWSAlgorithm;
616
+ /** Per-signer protected header; `b64` must match across signers (RFC 7797 §3), `typ` defaults to `"JWT"`. */
733
617
  protectedHeader?: StrictOmit<JWSHeaderParameters, "alg"> & {
734
618
  alg?: never;
735
619
  };
736
- /** Per-signer JWS Unprotected Header (not part of signing input). */
620
+ /** Per-signer JWS Unprotected Header (not signed). */
737
621
  unprotectedHeader?: JWSHeaderParameters;
738
622
  }
739
- /**
740
- * Options for {@link signMulti}. Mirrors {@link JWSSignOptions} minus the
741
- * per-signer fields (`alg`, `protectedHeader` — set those on each
742
- * {@link JWSMultiSigner} instead).
743
- */
744
- interface JWSMultiSignOptions extends StrictOmit<JWSSignOptions, "alg" | "protectedHeader"> {}
745
- /** Options for {@link verifyMulti}. Extends {@link JWSVerifyOptions}. */
746
- interface JWSMultiVerifyOptions extends JWSVerifyOptions {
747
- /**
748
- * When `false` (default), verification trials signatures in order — mirrors
749
- * the multi-key retry behaviour of {@link verify} against a JWK Set. When
750
- * `true`, only signatures whose header unambiguously matches the provided
751
- * key (by `kid`, then by `kty`/`crv`/length) are attempted, and any
752
- * mismatch throws `ERR_JWS_NO_MATCHING_SIGNER` before any crypto work.
753
- */
623
+ /** Options for `signMulti`; `alg` and `protectedHeader` are set per signer. */
624
+ export interface JWSMultiSignOptions extends StrictOmit<JWSSignOptions, "alg" | "protectedHeader"> {}
625
+ /** Options for `verifyMulti`. */
626
+ export interface JWSMultiVerifyOptions<Mode extends JOSEPayloadMode = JOSEPayloadMode> extends JWSVerifyOptions<Mode> {
627
+ /** Max `signatures[]` (more is `ERR_JWS_INVALID`) and JWK Set candidates per signature. @default { signatures: 16, keyCandidates: 8 } */
628
+ limits?: Pick<JOSELimits, "signatures" | "keyCandidates">;
629
+ /** Try only signatures the key could have produced (by `kid`, `kty`, curve, length), else `ERR_JWS_NO_MATCHING_SIGNER`. @default false */
754
630
  strictSignerMatch?: boolean;
755
631
  }
756
- /**
757
- * Result of a {@link verifyMulti} operation. Extends {@link JWSVerifyResult}
758
- * with the per-signer header and matched signature index.
759
- */
760
- interface JWSMultiVerifyResult<T extends JOSEPayload = JOSEPayload> extends JWSVerifyResult<T> {
761
- /** Parsed per-signer unprotected header of the signature that verified. */
632
+ /** Result of `verifyMulti`. */
633
+ export interface JWSMultiVerifyResult<T extends JOSEPayload = JOSEPayload> extends Omit<JWSVerifyResult<T>, "protectedHeader"> {
634
+ /** Protected header of the verified signature as signed; `alg` may sit in `signerHeader` (RFC 7515 §7.2.1). */
635
+ protectedHeader: JWSHeaderParameters;
636
+ /** Unprotected header of the verified signature. */
762
637
  signerHeader?: JWSHeaderParameters;
763
- /** Index into `jws.signatures` of the signature that successfully verified. */
638
+ /** Index into `signatures` of the verified signature. */
764
639
  signerIndex: number;
765
640
  }
766
- /**
767
- * Options for {@link verifyMultiAll}. Inherits the same validation knobs as
768
- * {@link JWSMultiVerifyOptions} minus `strictSignerMatch` (not meaningful when
769
- * every signature is independently reported).
770
- */
771
- interface JWSMultiVerifyAllOptions extends StrictOmit<JWSMultiVerifyOptions, "strictSignerMatch"> {}
772
- /**
773
- * Per-signature outcome collected by {@link verifyMultiAll}. Discriminated by
774
- * `verified`:
775
- *
776
- * - `verified: true` — the signature cryptographically verified and any
777
- * claim/`crit` validation the caller asked for also passed. `payload` is
778
- * provided.
779
- * - `verified: false` — verification could not be completed for this
780
- * signature. `error` carries the {@link JWTError} reason (signature
781
- * invalid, disallowed alg, `typ` mismatch, key-resolver failure, malformed
782
- * protected header, expired claim, etc.). `protectedHeader` / `signerHeader`
783
- * are populated when they were successfully parsed before failure.
784
- *
785
- * Callers apply their own policy over the returned array — e.g. "all must
786
- * verify", "quorum of N", "signed by these specific kids".
787
- */
788
- type JWSMultiVerifyOutcome<T extends JOSEPayload = JOSEPayload> = {
641
+ /** Options for `verifyMultiAll`. */
642
+ export interface JWSMultiVerifyAllOptions<Mode extends JOSEPayloadMode = JOSEPayloadMode> extends StrictOmit<JWSMultiVerifyOptions<Mode>, "strictSignerMatch"> {}
643
+ /** Per-signature outcome of `verifyMultiAll`, discriminated by `verified`; failures carry `error`. */
644
+ export type JWSMultiVerifyOutcome<T extends JOSEPayload = JOSEPayload> = {
789
645
  signerIndex: number;
790
646
  verified: true;
791
647
  payload: T;
792
- protectedHeader: JWSProtectedHeader;
648
+ protectedHeader: JWSHeaderParameters;
793
649
  signerHeader?: JWSHeaderParameters;
794
650
  } | {
795
651
  signerIndex: number;
796
652
  verified: false;
797
653
  error: JWTError;
798
- protectedHeader?: JWSProtectedHeader;
654
+ protectedHeader?: JWSHeaderParameters;
799
655
  signerHeader?: JWSHeaderParameters;
800
656
  };
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
- */
657
+ /** `oct` JWK algorithms admissible for JWE key management (HMAC excluded). */
806
658
  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;
828
- /** Recognized JWE Header Parameters, any other Header Members may also be present. */
829
- interface JWEHeaderParameters extends JoseHeaderParameters {
830
- /**
831
- * `alg` (Algorithm): Header Parameter - Key Management Algorithm
832
- */
659
+ /** Asymmetric public JWKs admissible for JWE encryption (RSA-OAEP or ECDH-ES). */
660
+ export type JWEAsymmetricPublicJWK = JWK_RSA_Public<JWK_RSA_ENC> | JWK_EC_Public<JWK_ECDH_ES> | JWK_OKP_Public<JWK_ECDH_ES>;
661
+ /** Asymmetric private JWKs admissible for JWE decryption (RSA-OAEP or ECDH-ES). */
662
+ export type JWEAsymmetricPrivateJWK = JWK_RSA_Private<JWK_RSA_ENC> | JWK_EC_Private<JWK_ECDH_ES> | JWK_OKP_Private<JWK_ECDH_ES>;
663
+ /** JWKs admissible as the `key` of `encrypt`; a non-JWE `alg` is a type error. */
664
+ export type JWEEncryptJWK = JWK_oct<_JWEOctAlg> | JWEAsymmetricPublicJWK;
665
+ /** JWKs admissible as a `key` of `decrypt`; a non-JWE `alg` is a type error. */
666
+ export type JWEDecryptJWK = JWK_oct<_JWEOctAlg> | JWEAsymmetricPrivateJWK;
667
+ /** Recognized JWE Header Parameters; other members may also be present. */
668
+ export interface JWEHeaderParameters extends JoseHeaderParameters {
669
+ /** Key Management Algorithm. */
833
670
  alg?: KeyManagementAlgorithm | (string & {});
834
- /**
835
- * `enc` (Encryption Algorithm): Header Parameter - Content Encryption Algorithm
836
- */
671
+ /** Content Encryption Algorithm. */
837
672
  enc?: ContentEncryptionAlgorithm | (string & {});
838
- /**
839
- * `p2c` (PBES2 Count): Header Parameter
840
- */
673
+ /** PBES2 Count. */
841
674
  p2c?: number;
842
- /**
843
- * `p2s` (PBES2 Salt): Header Parameter. Base64URL encoded.
844
- */
675
+ /** PBES2 Salt, base64url. */
845
676
  p2s?: string;
846
- /**
847
- * "iv" (Initialization Vector) Header Parameter for AES GCM Key Wrapping. Base64URL encoded.
848
- */
677
+ /** AES-GCMKW Initialization Vector, base64url. */
849
678
  iv?: string;
850
- /**
851
- * "tag" (Authentication Tag) Header Parameter for AES GCM Key Wrapping. Base64URL encoded.
852
- */
679
+ /** AES-GCMKW Authentication Tag, base64url. */
853
680
  tag?: string;
854
- /**
855
- * "epk" (Ephemeral Public Key) Header Parameter for ECDH-ES.
856
- */
857
- epk?: JWK_EC_Public;
858
- /**
859
- * "apu" (Agreement PartyUInfo) Header Parameter for ECDH-ES. Base64URL encoded.
860
- */
681
+ /** ECDH-ES Ephemeral Public Key. */
682
+ epk?: JWK_EC_Public | JWK_OKP_Public;
683
+ /** ECDH-ES Agreement PartyUInfo, base64url. */
861
684
  apu?: string;
862
- /**
863
- * "apv" (Agreement PartyVInfo) Header Parameter for ECDH-ES. Base64URL encoded.
864
- */
685
+ /** ECDH-ES Agreement PartyVInfo, base64url. */
865
686
  apv?: string;
866
- /** Any other JWE Header member. */
687
+ /** Compression (RFC 7516 §4.1.3) is not supported: a token carrying `zip` is rejected. */
688
+ zip?: never;
867
689
  [propName: string]: unknown;
868
690
  }
869
- /** Recognized JWE Key Management-related Header Parameters. */
870
- interface JWEKeyManagementHeaderParameters {
691
+ /** Recognized JWE Key Management-related Header Parameters; all but `apu`/`apv` are internal. */
692
+ export interface JWEKeyManagementHeaderParameters {
871
693
  apu?: Uint8Array<ArrayBuffer>;
872
694
  apv?: Uint8Array<ArrayBuffer>;
873
- /**
874
- * For Internal use only
875
- */
876
695
  p2c?: number;
877
- /**
878
- * For Internal use only
879
- */
880
696
  p2s?: Uint8Array<ArrayBuffer>;
881
- /**
882
- * For Internal use only
883
- */
884
697
  iv?: Uint8Array<ArrayBuffer>;
885
- /**
886
- * For Internal use only
887
- */
888
- epk?: CryptoKey | JWK_EC_Public;
889
- /**
890
- * For Internal use only
891
- */
892
- epkPrivateKey?: CryptoKey | JWK_EC_Private;
698
+ epk?: CryptoKey | JWK_EC_Public | JWK_OKP_Public;
699
+ epkPrivateKey?: CryptoKey | JWK_EC_Private | JWK_OKP_Private;
893
700
  }
894
- /**
895
- * JWE (JSON Web Encryption) encryption options
896
- */
897
- interface JWEEncryptOptions {
898
- /** JWE "alg" (Algorithm) Header Parameter. Key Management Algorithm. */
701
+ /** Header parameters the library writes itself and no caller header may set (RFC 7516 §4.1, RFC 7518 §4.6–§4.8). */
702
+ export type JWELibraryHeaderName = "alg" | "enc" | "iv" | "tag" | "p2s" | "p2c" | "epk" | "apu" | "apv";
703
+ /** JWE encryption options. */
704
+ export interface JWEEncryptOptions extends JWTTimeClaimOptions {
899
705
  alg?: KeyManagementAlgorithm;
900
- /** JWE "enc" (Encryption Algorithm) Header Parameter. Content Encryption Algorithm. */
901
706
  enc?: ContentEncryptionAlgorithm;
902
- /** Date to use when computing NumericDate claims, defaults to `new Date()`. */
903
- currentDate?: Date;
904
- /**
905
- * Duration until the JWT should expire, relative to `currentDate` (or `new Date()`).
906
- * Skipped when the payload already carries an `exp` claim.
907
- *
908
- * Mutually exclusive with {@link expiresAt}.
909
- */
910
- expiresIn?: ExpiresIn;
911
- /**
912
- * Absolute moment at which the JWT should expire (sets the `exp` claim directly).
913
- * Skipped when the payload already carries an `exp` claim.
914
- *
915
- * Mutually exclusive with {@link expiresIn}.
916
- */
917
- expiresAt?: Date;
918
- /**
919
- * Duration from `iat` before which the JWT must not be accepted.
920
- * `0` is allowed and sets `nbf = iat` (explicit temporal floor at sign time).
921
- * Skipped when the payload already carries an `nbf` claim.
922
- *
923
- * Mutually exclusive with {@link notBeforeAt}.
924
- */
925
- notBeforeIn?: ExpiresIn;
926
- /**
927
- * Absolute moment before which the JWT must not be accepted (sets the `nbf`
928
- * claim directly per RFC 7519 §4.1.5). Skipped when the payload already
929
- * carries an `nbf` claim.
930
- *
931
- * Mutually exclusive with {@link notBeforeIn}.
932
- */
933
- notBeforeAt?: Date;
934
- /** Additional JWE Protected Header parameters. */
935
- protectedHeader?: StrictOmit<JWEHeaderParameters, "alg" | "enc" | "iv" | "tag" | "p2s" | "p2c" | "epk" | "apu" | "apv">;
936
- /** Initialization Vector for AES-GCMKW key wrapping. Generated if not provided. */
707
+ /** Extra protected header; `typ` defaults to `"JWT"` for a JSON object payload, `cty` is never added (`"JWT"` for a nested JWT, RFC 7519 §5.2). */
708
+ protectedHeader?: StrictOmit<JWEHeaderParameters, JWELibraryHeaderName>;
709
+ /** AES-GCMKW key-wrapping IV. Generated when omitted. */
937
710
  keyManagementIV?: Uint8Array<ArrayBuffer>;
938
- /** PBES2 Salt value (p2s). Required for PBES2 algorithms. */
711
+ /** PBES2 Salt (p2s). Required for PBES2 algorithms. */
939
712
  p2s?: Uint8Array<ArrayBuffer>;
940
- /** PBES2 Iteration count (p2c). Required for PBES2 algorithms. */
713
+ /** PBES2 iteration count (p2c), between `1000` and `600_000`. Default: `600_000`. */
941
714
  p2c?: number;
942
- /** ECDH-ES specific options. */
943
715
  ecdh?: {
944
- /**
945
- * ECDH-ES Ephemeral key material. Provide a private key (CryptoKey or JWK),
946
- * a CryptoKeyPair, or an object exposing both public and private parts.
947
- */
948
- ephemeralKey?: CryptoKey | JWK_EC_Private | CryptoKeyPair | {
949
- publicKey: CryptoKey | JWK_EC_Public;
950
- privateKey: CryptoKey | JWK_EC_Private;
951
- }; /** ECDH-ES Agreement PartyUInfo. */
952
- partyUInfo?: Uint8Array<ArrayBuffer>; /** ECDH-ES Agreement PartyVInfo. */
716
+ ephemeralKey?: ECDHEphemeralKeyInput;
717
+ partyUInfo?: Uint8Array<ArrayBuffer>;
953
718
  partyVInfo?: Uint8Array<ArrayBuffer>;
954
719
  };
955
- /**
956
- * Content Encryption Key (CEK) to use.
957
- * If provided, it will be used directly. Otherwise, a CEK will be generated.
958
- */
720
+ /** Content Encryption Key. Generated when omitted. */
959
721
  cek?: Uint8Array<ArrayBuffer>;
960
- /**
961
- * Initialization Vector for content encryption.
962
- * If provided, it will be used. Otherwise, one will be generated.
963
- */
722
+ /** Content encryption IV. Generated when omitted. */
964
723
  contentEncryptionIV?: Uint8Array<ArrayBuffer>;
965
724
  }
966
- /**
967
- * JWE (JSON Web Encryption) decryption options
968
- */
969
- interface JWEDecryptOptions extends JWTClaimValidationOptions {
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
- */
725
+ /** JWE decryption options; `Mode` is the `payload` option's literal, which sets the returned payload type. */
726
+ export interface JWEDecryptOptions<Mode extends JOSEPayloadMode = JOSEPayloadMode> extends JOSEConsumerOptions<Mode> {
727
+ /** Allowed `alg` values. Inferred from the key when omitted (a password infers PBES2); required for raw bytes and lookup functions. */
976
728
  algorithms?: KeyManagementAlgorithm[];
977
- /** A list of allowed JWE "enc" (Encryption Algorithm) Header Parameter values for content encryption. */
729
+ /** Max JWK Set candidates per token (else `ERR_JWK_KEY_NOT_FOUND`) and PBKDF2 iterations per call (else `ERR_JWE_INVALID`). Default: `{ keyCandidates: 8, pbes2Iterations: 2_400_000 }`. */
730
+ limits?: Pick<JOSELimits, "keyCandidates" | "pbes2Iterations">;
731
+ /** Allowed `enc` values. */
978
732
  encryptionAlgorithms?: ContentEncryptionAlgorithm[];
979
- /** Algorithm to import the unwrapped CEK as (e.g., { name: 'AES-GCM' }). Defaults based on 'enc'. */
733
+ /** Algorithm to import the unwrapped CEK as. Defaults based on `enc`. */
980
734
  unwrappedKeyAlgorithm?: Parameters<typeof crypto.subtle.importKey>[2];
981
- /** Key usages for the unwrapped CEK. Defaults based on 'enc' (typically ['encrypt', 'decrypt']). */
735
+ /** Unwrapped CEK usages. Defaults based on `enc`. */
982
736
  keyUsage?: KeyUsage[];
983
- /** Mark the unwrapped CEK as extractable. Defaults to true. */
737
+ /** Mark the unwrapped CEK extractable. Default: `true`. */
984
738
  extractable?: boolean;
985
- /** If true, forces the payload to be returned as a Uint8Array, otherwise type is inferred based on JWE headers. */
986
- forceUint8Array?: boolean;
987
- /**
988
- * Controls JWT claim validation after a successful decryption.
989
- *
990
- * - `true` — always validate claims regardless of the `typ` header
991
- * - `false` — skip claim validation entirely
992
- * - `undefined` (default) — validate when `typ` is `"JWT"` or contains `"jwt"`
993
- */
994
- validateClaims?: boolean;
995
- /** If true, include the Content Encryption Key (CEK) and Additional Authenticated Data (AAD) in the result. */
739
+ /** Include the CEK and AAD in the result. */
996
740
  returnCek?: boolean;
997
741
  /** Minimum accepted PBES2 `p2c` on unwrap. Defaults to 1000 (RFC 7518 §4.8.1.2). */
998
742
  minIterations?: number;
999
- /** Maximum accepted PBES2 `p2c` on unwrap. Defaults to 1_000_000 to cap PBKDF2 DoS potential. */
743
+ /** Maximum accepted PBES2 `p2c` on unwrap. Default: `600_000`. */
1000
744
  maxIterations?: number;
1001
745
  }
1002
- /**
1003
- * JWE Protected Header — the parsed and validated protected header returned
1004
- * after a successful {@link decrypt} call. Both `alg` and `enc` are present
1005
- * and strongly typed because decryption could not have succeeded without them.
1006
- */
1007
- interface JWEProtectedHeader extends JWEHeaderParameters {
1008
- /** Key management algorithm. */
746
+ /** Validated protected header returned by `decrypt`; `alg` and `enc` are always present. */
747
+ export interface JWEProtectedHeader extends JWEHeaderParameters {
1009
748
  alg: KeyManagementAlgorithm;
1010
- /** Content encryption algorithm. */
1011
749
  enc: ContentEncryptionAlgorithm;
1012
750
  }
1013
- /**
1014
- * Result of a JWE decryption operation.
1015
- */
1016
- interface JWEDecryptResult<T extends JOSEPayload = JOSEPayload> {
1017
- /** The decrypted payload. */
751
+ /** Result of a JWE decryption. */
752
+ export interface JWEDecryptResult<T extends JOSEPayload = JOSEPayload> {
1018
753
  payload: T;
1019
- /** The JWE Protected Header. */
1020
754
  protectedHeader: JWEProtectedHeader;
1021
- /** The Content Encryption Key (CEK) used for decryption, as Uint8Array. Only present when `returnCek` is true. */
755
+ /** Present only when `returnCek` is true. */
1022
756
  cek?: Uint8Array<ArrayBuffer>;
1023
- /** The Additional Authenticated Data (AAD) used, as Uint8Array. Only present when `returnCek` is true. */
757
+ /** Present only when `returnCek` is true. */
1024
758
  aad?: Uint8Array<ArrayBuffer>;
1025
759
  }
1026
- /**
1027
- * JWE Flattened JSON Serialization, RFC 7516 §7.2.2.
1028
- */
1029
- interface JWEFlattenedSerialization {
760
+ /** JWE Flattened JSON Serialization (RFC 7516 §7.2.2); string members are base64url. */
761
+ export interface JWEFlattenedSerialization {
1030
762
  header?: JWEHeaderParameters;
1031
763
  encrypted_key?: string;
1032
- /** Base64URL-encoded JWE Protected Header (part of AAD). */
764
+ /** JWE Protected Header (part of AAD). */
1033
765
  protected?: string;
1034
- /** Shared JWE Unprotected Header (JSON, not part of AAD). */
766
+ /** Shared Unprotected Header (not part of AAD). */
1035
767
  unprotected?: JWEHeaderParameters;
1036
- /** Base64URL-encoded external Additional Authenticated Data. */
768
+ /** External Additional Authenticated Data. */
1037
769
  aad?: string;
1038
- /** Base64URL-encoded IV (Initialization Vector). */
1039
- iv?: string;
1040
- /** Base64URL-encoded ciphertext. */
770
+ iv: string;
1041
771
  ciphertext: string;
1042
- /** Base64URL-encoded authentication tag. */
1043
- tag?: string;
772
+ tag: string;
1044
773
  }
1045
- /**
1046
- * JWE General JSON Serialization, RFC 7516 §7.2.1. The canonical
1047
- * multi-recipient output shape of {@link encryptMulti}.
1048
- */
1049
- interface JWEGeneralSerialization extends Omit<JWEFlattenedSerialization, "encrypted_key" | "header"> {
1050
- /** One entry per recipient. */
774
+ /** JWE General JSON Serialization (RFC 7516 §7.2.1), the output of `encryptMulti`. */
775
+ export interface JWEGeneralSerialization extends Omit<JWEFlattenedSerialization, "encrypted_key" | "header"> {
1051
776
  recipients: JWEGeneralRecipient[];
1052
777
  }
1053
- /** A single recipient entry within {@link JWEGeneralSerialization.recipients}. */
1054
- interface JWEGeneralRecipient {
1055
- /** Per-recipient JWE Unprotected Header (JSON, not part of AAD). */
778
+ /** One recipient entry of a JWE General JSON Serialization. */
779
+ export interface JWEGeneralRecipient {
780
+ /** Per-recipient Unprotected Header (not part of AAD). */
1056
781
  header?: JWEHeaderParameters;
1057
- /** Base64URL-encoded encrypted CEK for this recipient. */
1058
782
  encrypted_key?: string;
1059
783
  }
1060
- /**
1061
- * Input shape for a single recipient passed to {@link encryptMulti}.
1062
- *
1063
- * `alg` is inferred from `key.alg` or from the JWK's kty/curve/length using
1064
- * the same rules as {@link encrypt}. `kid` is pulled from `key.kid` when
1065
- * present. To override either, spread or set via {@link JWEMultiRecipient.header}.
1066
- */
1067
- interface JWEMultiRecipient {
1068
- /** Recipient key (JWK-first; `alg` inferred if absent from JWK). */
784
+ /** One recipient of `encryptMulti`; `alg` and `kid` come from the key unless set in `header`. */
785
+ export interface JWEMultiRecipient {
1069
786
  key: JWEEncryptJWK;
1070
- /**
1071
- * Extra per-recipient JWE Unprotected Header parameters (RFC 7516 §7.2.1).
1072
- * Excludes fields the library writes automatically: `alg`, `enc`, `iv`,
1073
- * `tag`, `p2s`, `p2c`, `epk`, `apu`, `apv`.
1074
- *
1075
- * Typical use: `x5c`, `x5t`, custom routing metadata.
1076
- */
1077
- header?: StrictOmit<JWEHeaderParameters, "alg" | "enc" | "iv" | "tag" | "p2s" | "p2c" | "epk" | "apu" | "apv">;
1078
- /** ECDH-ES ephemeral key / party info for this recipient. */
787
+ /** Extra per-recipient Unprotected Header parameters (RFC 7516 §7.2.1). */
788
+ header?: StrictOmit<JWEHeaderParameters, JWELibraryHeaderName>;
1079
789
  ecdh?: JWEEncryptOptions["ecdh"];
1080
- /** PBES2 salt for this recipient. Randomized (16 bytes) when omitted. */
790
+ /** PBES2 salt. Random 16 bytes when omitted. */
1081
791
  p2s?: Uint8Array<ArrayBuffer>;
1082
- /** PBES2 iteration count for this recipient. Defaults to 600_000. */
792
+ /** PBES2 iteration count, between `1000` and `600_000`. Default: `600_000`. */
1083
793
  p2c?: number;
1084
- /** Initialization vector for AES-GCMKW key wrapping for this recipient. */
1085
794
  keyManagementIV?: Uint8Array<ArrayBuffer>;
1086
795
  }
1087
- /**
1088
- * Options for {@link encryptMulti}. Extends {@link JWEEncryptOptions} and drops
1089
- * the fields that are per-recipient in multi-recipient mode (`alg`, `ecdh`,
1090
- * `p2s`, `p2c`, `keyManagementIV` — set those on each {@link JWEMultiRecipient}
1091
- * instead).
1092
- */
1093
- interface JWEMultiEncryptOptions extends StrictOmit<JWEEncryptOptions, "alg" | "ecdh" | "p2s" | "p2c" | "keyManagementIV"> {
1094
- /** Shared JWE Unprotected Header (surfaces as `unprotected` in the output). */
796
+ /** Options for `encryptMulti`; per-recipient fields are set on each `JWEMultiRecipient`. */
797
+ export interface JWEMultiEncryptOptions extends StrictOmit<JWEEncryptOptions, "alg" | "ecdh" | "p2s" | "p2c" | "keyManagementIV"> {
798
+ /** Shared Unprotected Header, written as `unprotected`. */
1095
799
  sharedUnprotectedHeader?: Record<string, unknown>;
1096
- /**
1097
- * External Additional Authenticated Data (RFC 7516 §5.1). Encoded as
1098
- * base64url and written to the `aad` field; the content cipher AAD becomes
1099
- * `BASE64URL(protected) || '.' || BASE64URL(aad)`.
1100
- */
800
+ /** External AAD (RFC 7516 §5.1); empty means none (RFC 7516 §7.2.1); not a string or bytes is `ERR_INVALID_OPTION`. */
1101
801
  aad?: Uint8Array<ArrayBuffer> | string;
1102
802
  }
1103
- /**
1104
- * Options for {@link decryptMulti}. Extends {@link JWEDecryptOptions}.
1105
- */
1106
- interface JWEMultiDecryptOptions extends JWEDecryptOptions {
1107
- /**
1108
- * When `false` (default) decryption trials recipients in order — mirrors the
1109
- * multi-key retry behaviour of {@link decrypt} against a JWK Set. When
1110
- * `true`, only recipients whose header unambiguously matches the provided
1111
- * key (by `kid`, then by `kty`/`crv`/length) are attempted, and any mismatch
1112
- * throws `ERR_JWE_NO_MATCHING_RECIPIENT` before any crypto work.
1113
- */
803
+ /** Key material `decryptMulti` accepts, or a function resolving it from the recipient's header. */
804
+ export type JWEMultiDecryptKey = CryptoKey | JWKSet | JWEDecryptJWK | string | Uint8Array<ArrayBuffer> | JWKLookupFunction;
805
+ /** Options for `decryptMulti`. */
806
+ export interface JWEMultiDecryptOptions<Mode extends JOSEPayloadMode = JOSEPayloadMode> extends JWEDecryptOptions<Mode> {
807
+ /** Max recipients (else `ERR_JWE_INVALID`), JWK Set candidates per recipient, and PBKDF2 iterations summed over the call. Default: `{ recipients: 16, keyCandidates: 8, pbes2Iterations: 2_400_000 }`. */
808
+ limits?: Pick<JOSELimits, "recipients" | "keyCandidates" | "pbes2Iterations">;
809
+ /** Try only recipients the key could open, else `ERR_JWE_NO_MATCHING_RECIPIENT`; a JWK Set with no candidate is `ERR_JWK_KEY_NOT_FOUND`. Default: `false` (trial in order). */
1114
810
  strictRecipientMatch?: boolean;
1115
811
  }
1116
- /**
1117
- * Result of a {@link decryptMulti} operation. Extends {@link JWEDecryptResult}
1118
- * with the per-recipient header tier surfaced on the matching recipient.
1119
- */
1120
- interface JWEMultiDecryptResult<T extends JOSEPayload = JOSEPayload> extends JWEDecryptResult<T> {
1121
- /** Parsed shared unprotected header, when present on the serialization. */
812
+ /** Result of `decryptMulti`, with the header tiers of the recipient that decrypted. */
813
+ export interface JWEMultiDecryptResult<T extends JOSEPayload = JOSEPayload> extends Omit<JWEDecryptResult<T>, "protectedHeader"> {
814
+ /** Protected header as integrity protected (`{}` when absent); `alg`/`enc` may sit in the unprotected tiers (RFC 7516 §7.2.1). */
815
+ protectedHeader: JWEHeaderParameters;
1122
816
  sharedUnprotectedHeader?: JWEHeaderParameters;
1123
- /** Parsed per-recipient unprotected header of the recipient that decrypted. */
817
+ /** Unprotected header of the recipient that decrypted. */
1124
818
  recipientHeader?: JWEHeaderParameters;
1125
- /** Index into `jwe.recipients` of the recipient that successfully decrypted. */
819
+ /** Index into `recipients` of the recipient that decrypted. */
1126
820
  recipientIndex: number;
1127
821
  }
1128
822
  /**
1129
- * A time duration, expressed as an integer number of seconds or a human-readable
1130
- * shorthand like `"10m"`, `"2h"`, `"7D"`.
1131
- *
1132
- * Shared base type for every duration-valued option in the library:
1133
- * {@link ExpiresIn}, {@link NotBeforeIn}, {@link MaxTokenAge}.
1134
- */
1135
- type Duration = number | `${number}` | `${number}${"s" | "second" | "seconds" | "m" | "minute" | "minutes" | "h" | "hour" | "hours" | "D" | "day" | "days" | "W" | "week" | "weeks" | "M" | "month" | "months" | "Y" | "year" | "years"}`;
823
+ * A time duration, expressed as an integer number of seconds or a human-readable
824
+ * shorthand like `"10m"`, `"2h"`, `"7D"`.
825
+ *
826
+ * Shared base type for every duration-valued option in the library:
827
+ * {@link ExpiresIn}, {@link NotBeforeIn}, {@link MaxTokenAge}.
828
+ */
829
+ export type Duration = number | `${number}` | `${number}${"s" | "second" | "seconds" | "m" | "minute" | "minutes" | "h" | "hour" | "hours" | "D" | "day" | "days" | "W" | "week" | "weeks" | "M" | "month" | "months" | "Y" | "year" | "years"}`;
1136
830
  /** Duration until `exp` — the `expiresIn` option on {@link sign} / {@link encrypt}. */
1137
- type ExpiresIn = Duration;
831
+ export type ExpiresIn = Duration;
1138
832
  /** Duration from `iat` for `nbf` — the `notBeforeIn` option on {@link sign} / {@link encrypt}. */
1139
- type NotBeforeIn = Duration;
833
+ export type NotBeforeIn = Duration;
1140
834
  /** Duration for `maxTokenAge` validation on {@link verify} / {@link decrypt}. */
1141
- type MaxTokenAge = Duration;
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 };
835
+ export type MaxTokenAge = Duration;
836
+ export {};