unjwt 0.6.1 → 0.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +27 -363
- package/dist/_chunks/_internal.mjs +88 -0
- package/dist/_chunks/index.d.mts +537 -80
- package/dist/_chunks/jwe.d.mts +84 -0
- package/dist/_chunks/jwe.mjs +407 -0
- package/dist/_chunks/{_crypto.mjs → jwk.mjs} +637 -26
- package/dist/_chunks/jws.d.mts +111 -0
- package/dist/_chunks/jws.mjs +264 -2031
- package/dist/_chunks/libs/unsecure.d.mts +94 -0
- package/dist/_chunks/libs/unsecure.mjs +149 -0
- package/dist/_chunks/utils.mjs +222 -211
- package/dist/adapters/h3v1/index.d.mts +17 -17
- package/dist/adapters/h3v1/index.mjs +15 -77
- package/dist/adapters/h3v2/index.d.mts +17 -17
- package/dist/adapters/h3v2/index.mjs +15 -39
- package/dist/core/jwe.d.mts +3 -40
- package/dist/core/jwe.mjs +3 -161
- package/dist/core/jwk.d.mts +205 -49
- package/dist/core/jwk.mjs +3 -686
- package/dist/core/jws.d.mts +3 -31
- package/dist/core/jws.mjs +3 -104
- package/dist/core/utils/index.d.mts +96 -63
- package/dist/core/utils/index.mjs +3 -2
- package/dist/index.d.mts +6 -7
- package/dist/index.mjs +5 -5
- package/package.json +24 -19
- package/dist/_chunks/error.d.mts +0 -67
- package/dist/_chunks/jwk.d.mts +0 -708
- package/dist/core/_crypto/index.d.mts +0 -71
- package/dist/core/_crypto/index.mjs +0 -2
package/dist/_chunks/index.d.mts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
//#region src/core/types/jwk.d.ts
|
|
2
1
|
/**
|
|
3
2
|
* The decoded JOSE protected header received by a {@link JWKLookupFunction}.
|
|
4
3
|
*
|
|
@@ -28,8 +27,12 @@ type JWKLookupFunctionHeader = {
|
|
|
28
27
|
*
|
|
29
28
|
* Returning a `string` is meaningful for JWE only (PBES2 password); for JWS
|
|
30
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.
|
|
31
34
|
*/
|
|
32
|
-
type JWKLookupFunction =
|
|
35
|
+
type JWKLookupFunction<TReturn = CryptoKey | JWK | JWKSet | string | Uint8Array<ArrayBuffer>> = (header: JWKLookupFunctionHeader, token: string) => TReturn | Promise<TReturn>;
|
|
33
36
|
/**
|
|
34
37
|
* Interface for custom JWK import cache implementations.
|
|
35
38
|
*
|
|
@@ -78,16 +81,7 @@ interface GenerateKeyOptions {
|
|
|
78
81
|
*/
|
|
79
82
|
toJWK?: boolean;
|
|
80
83
|
}
|
|
81
|
-
type GenerateKeyReturnJWK<TAlg extends GenerateKeyAlgorithm> = TAlg extends JWK_Asymmetric_Algorithm ? TAlg
|
|
82
|
-
privateKey: JWK_RSA_Private;
|
|
83
|
-
publicKey: JWK_RSA_Public;
|
|
84
|
-
} : TAlg extends JWK_ECDSA | JWK_ECDH_ES ? {
|
|
85
|
-
privateKey: JWK_EC_Private;
|
|
86
|
-
publicKey: JWK_EC_Public;
|
|
87
|
-
} : TAlg extends JWK_OKP_SIGN ? {
|
|
88
|
-
privateKey: JWK_OKP_Private;
|
|
89
|
-
publicKey: JWK_OKP_Public;
|
|
90
|
-
} : never : TAlg extends JWK_AES_CBC_HMAC | JWK_Symmetric_Algorithm ? JWK_oct : never;
|
|
84
|
+
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;
|
|
91
85
|
type GenerateKeyReturnCrypto<TAlg extends GenerateKeyAlgorithm> = TAlg extends JWK_AES_CBC_HMAC ? Uint8Array<ArrayBuffer> : TAlg extends JWK_Asymmetric_Algorithm ? CryptoKeyPair : CryptoKey;
|
|
92
86
|
type GenerateKeyReturn<TAlg extends GenerateKeyAlgorithm, TOptions extends GenerateKeyOptions> = TOptions["toJWK"] extends true ? GenerateKeyReturnJWK<TAlg> : GenerateKeyReturnCrypto<TAlg>;
|
|
93
87
|
type GenerateJWKOptions = Omit<GenerateKeyOptions, "toJWK">;
|
|
@@ -109,9 +103,27 @@ interface DeriveKeyOptions {
|
|
|
109
103
|
*/
|
|
110
104
|
toJWK?: boolean;
|
|
111
105
|
}
|
|
112
|
-
|
|
106
|
+
/** PBES2 → AES-KW alg that ends up stamped on the derived JWK's `alg`. */
|
|
107
|
+
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;
|
|
108
|
+
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;
|
|
113
109
|
type KeyManagementAlgorithm = JWK_RSA_ENC | JWK_AES_KW | JWK_AES_GCM | JWK_AES_GCM_KW | JWK_PBES2 | JWK_ECDH_ES | "dir";
|
|
114
110
|
type ContentEncryptionAlgorithm = JWK_AES_GCM | JWK_AES_CBC_HMAC;
|
|
111
|
+
/**
|
|
112
|
+
* Keys admissible as the `wrappingKey` argument of {@link wrapKey}, narrowed
|
|
113
|
+
* by the key management algorithm. Mirrors the runtime branches in
|
|
114
|
+
* `jwk.wrapKey` and the inference in `inferJWEAllowedAlgorithms`.
|
|
115
|
+
*
|
|
116
|
+
* - `dir` accepts any symmetric JWK (the key _is_ the CEK).
|
|
117
|
+
* - AES-GCMKW tolerates a JWK whose `alg` is the bare `A*GCM` counterpart —
|
|
118
|
+
* matches the `jweAlgsFromOctJWK` aliasing rule.
|
|
119
|
+
*/
|
|
120
|
+
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;
|
|
121
|
+
/**
|
|
122
|
+
* Keys admissible as the `unwrappingKey` argument of {@link unwrapKey}.
|
|
123
|
+
* The private-side counterpart of {@link WrappingKeyFor} — symmetric branches
|
|
124
|
+
* are identical; asymmetric branches use the `_Private` variants.
|
|
125
|
+
*/
|
|
126
|
+
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;
|
|
115
127
|
/** Options for the wrapKey function. */
|
|
116
128
|
interface WrapKeyOptions {
|
|
117
129
|
/** Initialization Vector for AES-GCMKW. Generated if not provided. */
|
|
@@ -140,25 +152,31 @@ interface WrapKeyOptions {
|
|
|
140
152
|
enc?: ContentEncryptionAlgorithm;
|
|
141
153
|
};
|
|
142
154
|
}
|
|
143
|
-
/**
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
/** PBES2
|
|
154
|
-
p2c
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
/**
|
|
158
|
-
|
|
159
|
-
|
|
155
|
+
/**
|
|
156
|
+
* Result of {@link wrapKey}, discriminated by key management algorithm family.
|
|
157
|
+
*
|
|
158
|
+
* Narrow the shape by passing a literal `alg` to `wrapKey`:
|
|
159
|
+
* - PBES2 → `{ encryptedKey, p2s, p2c }`
|
|
160
|
+
* - AES-GCMKW → `{ encryptedKey, iv, tag }`
|
|
161
|
+
* - ECDH-ES / ECDH-ES+A*KW → `{ encryptedKey, epk, apu?, apv? }`
|
|
162
|
+
* - dir / AES-KW / RSA-OAEP → `{ encryptedKey }`
|
|
163
|
+
*/
|
|
164
|
+
type WrapKeyResult<TAlg extends KeyManagementAlgorithm = KeyManagementAlgorithm> = TAlg extends JWK_PBES2 ? {
|
|
165
|
+
encryptedKey: Uint8Array<ArrayBuffer>; /** PBES2 Salt value (p2s). Base64URL encoded. */
|
|
166
|
+
p2s: string; /** PBES2 Iteration count (p2c). */
|
|
167
|
+
p2c: number;
|
|
168
|
+
} : TAlg extends JWK_AES_GCM_KW ? {
|
|
169
|
+
encryptedKey: Uint8Array<ArrayBuffer>; /** AES-GCMKW Initialization Vector. Base64URL encoded. */
|
|
170
|
+
iv: string; /** AES-GCMKW Authentication Tag. Base64URL encoded. */
|
|
171
|
+
tag: string;
|
|
172
|
+
} : TAlg extends JWK_ECDH_ES ? {
|
|
173
|
+
encryptedKey: Uint8Array<ArrayBuffer>; /** Ephemeral Public Key. */
|
|
174
|
+
epk: JWK_EC_Public; /** Agreement PartyUInfo. Base64URL encoded. Present only when supplied. */
|
|
175
|
+
apu?: string; /** Agreement PartyVInfo. Base64URL encoded. Present only when supplied. */
|
|
160
176
|
apv?: string;
|
|
161
|
-
}
|
|
177
|
+
} : {
|
|
178
|
+
encryptedKey: Uint8Array<ArrayBuffer>;
|
|
179
|
+
};
|
|
162
180
|
/** Options for the unwrapKey function. */
|
|
163
181
|
interface UnwrapKeyOptions {
|
|
164
182
|
/**
|
|
@@ -176,6 +194,10 @@ interface UnwrapKeyOptions {
|
|
|
176
194
|
p2s?: Uint8Array<ArrayBuffer> | string;
|
|
177
195
|
/** PBES2 Iteration count (required for PBES2). */
|
|
178
196
|
p2c?: number;
|
|
197
|
+
/** Minimum accepted PBES2 `p2c` on unwrap. Defaults to 1000 (RFC 7518 §4.8.1.2). */
|
|
198
|
+
minIterations?: number;
|
|
199
|
+
/** Maximum accepted PBES2 `p2c` on unwrap. Defaults to 1_000_000 to cap PBKDF2 DoS potential. */
|
|
200
|
+
maxIterations?: number;
|
|
179
201
|
/** ECDH-ES Ephemeral Public Key (required for ECDH-ES). */
|
|
180
202
|
epk?: JWK_EC_Public | CryptoKey;
|
|
181
203
|
/** ECDH-ES Agreement PartyUInfo. Base64URL encoded or Uint8Array. */
|
|
@@ -196,8 +218,15 @@ interface UnwrapKeyOptions {
|
|
|
196
218
|
* Copyright (c) 2018 Filip Skokan.
|
|
197
219
|
* LICENSE: https://github.com/panva/jose/blob/v6.0.10/LICENSE.md
|
|
198
220
|
*/
|
|
199
|
-
/**
|
|
200
|
-
|
|
221
|
+
/**
|
|
222
|
+
* Generic JSON Web Key Parameters.
|
|
223
|
+
*
|
|
224
|
+
* The `Alg` type parameter constrains the JWK's `alg` field. Each concrete JWK
|
|
225
|
+
* interface below tightens `Alg` to the algorithm family admissible for that key
|
|
226
|
+
* type — e.g. a `JWK_oct<JWK_HMAC>` can only hold `"HS256" | "HS384" | "HS512"`
|
|
227
|
+
* in `alg`.
|
|
228
|
+
*/
|
|
229
|
+
interface JWKParameters<Alg extends string = string> {
|
|
201
230
|
/** JWK "kty" (Key Type) Parameter */
|
|
202
231
|
kty: string;
|
|
203
232
|
/**
|
|
@@ -205,7 +234,7 @@ interface JWKParameters {
|
|
|
205
234
|
*
|
|
206
235
|
* @see {@link https://github.com/panva/jose/issues/210 Algorithm Key Requirements}
|
|
207
236
|
*/
|
|
208
|
-
alg?:
|
|
237
|
+
alg?: Alg;
|
|
209
238
|
/** JWK "key_ops" (Key Operations) Parameter */
|
|
210
239
|
key_ops?: KeyUsage[];
|
|
211
240
|
/** JWK "ext" (Extractable) Parameter */
|
|
@@ -230,7 +259,7 @@ interface JWKParameters {
|
|
|
230
259
|
enc?: ContentEncryptionAlgorithm;
|
|
231
260
|
}
|
|
232
261
|
/** Public EC JSON Web Keys */
|
|
233
|
-
interface JWK_EC_Public extends JWKParameters {
|
|
262
|
+
interface JWK_EC_Public<Alg extends JWK_ECDSA | JWK_ECDH_ES | (string & {}) = string> extends JWKParameters<Alg> {
|
|
234
263
|
/** EC JWK "kty" (Key Type) Parameter */
|
|
235
264
|
kty: "EC";
|
|
236
265
|
/** EC JWK "crv" (Curve) Parameter */
|
|
@@ -241,14 +270,14 @@ interface JWK_EC_Public extends JWKParameters {
|
|
|
241
270
|
y: string;
|
|
242
271
|
}
|
|
243
272
|
/** Private EC JSON Web Keys */
|
|
244
|
-
interface JWK_EC_Private extends JWK_EC_Public {
|
|
273
|
+
interface JWK_EC_Private<Alg extends JWK_ECDSA | JWK_ECDH_ES | (string & {}) = string> extends JWK_EC_Public<Alg> {
|
|
245
274
|
/** EC JWK "d" (ECC Private Key) Parameter */
|
|
246
275
|
d: string;
|
|
247
276
|
}
|
|
248
277
|
/** EC JSON Web Keys */
|
|
249
|
-
type JWK_EC = JWK_EC_Public | JWK_EC_Private
|
|
278
|
+
type JWK_EC<Alg extends JWK_ECDSA | JWK_ECDH_ES | (string & {}) = string> = JWK_EC_Public<Alg> | JWK_EC_Private<Alg>;
|
|
250
279
|
/** Public RSA JSON Web Keys */
|
|
251
|
-
interface JWK_RSA_Public extends JWKParameters {
|
|
280
|
+
interface JWK_RSA_Public<Alg extends JWK_RSA_SIGN | JWK_RSA_PSS | JWK_RSA_ENC | (string & {}) = string> extends JWKParameters<Alg> {
|
|
252
281
|
/** RSA JWK "kty" (Key Type) Parameter */
|
|
253
282
|
kty: "RSA";
|
|
254
283
|
/** RSA JWK "e" (Exponent) Parameter */
|
|
@@ -258,7 +287,7 @@ interface JWK_RSA_Public extends JWKParameters {
|
|
|
258
287
|
oth?: RsaOtherPrimesInfo[];
|
|
259
288
|
}
|
|
260
289
|
/** Private RSA JSON Web Keys */
|
|
261
|
-
interface JWK_RSA_Private extends JWK_RSA_Public {
|
|
290
|
+
interface JWK_RSA_Private<Alg extends JWK_RSA_SIGN | JWK_RSA_PSS | JWK_RSA_ENC | (string & {}) = string> extends JWK_RSA_Public<Alg> {
|
|
262
291
|
/** RSA JWK "d" (Private Exponent) Parameter */
|
|
263
292
|
d: string;
|
|
264
293
|
/** RSA JWK "dp" (First Factor CRT Exponent) Parameter */
|
|
@@ -273,9 +302,9 @@ interface JWK_RSA_Private extends JWK_RSA_Public {
|
|
|
273
302
|
qi: string;
|
|
274
303
|
}
|
|
275
304
|
/** RSA JSON Web Keys */
|
|
276
|
-
type JWK_RSA = JWK_RSA_Public | JWK_RSA_Private
|
|
305
|
+
type JWK_RSA<Alg extends JWK_RSA_SIGN | JWK_RSA_PSS | JWK_RSA_ENC | (string & {}) = string> = JWK_RSA_Public<Alg> | JWK_RSA_Private<Alg>;
|
|
277
306
|
/** Public ED JSON Web Keys */
|
|
278
|
-
interface JWK_OKP_Public extends JWKParameters {
|
|
307
|
+
interface JWK_OKP_Public<Alg extends JWK_OKP_SIGN | JWK_ECDH_ES | (string & {}) = string> extends JWKParameters<Alg> {
|
|
279
308
|
/** ED JWK "kty" (Key Type) Parameter */
|
|
280
309
|
kty: "OKP";
|
|
281
310
|
/** ED JWK "crv" (Curve) Parameter */
|
|
@@ -284,48 +313,78 @@ interface JWK_OKP_Public extends JWKParameters {
|
|
|
284
313
|
x: string;
|
|
285
314
|
}
|
|
286
315
|
/** Private ED JSON Web Keys */
|
|
287
|
-
interface JWK_OKP_Private extends JWK_OKP_Public {
|
|
316
|
+
interface JWK_OKP_Private<Alg extends JWK_OKP_SIGN | JWK_ECDH_ES | (string & {}) = string> extends JWK_OKP_Public<Alg> {
|
|
288
317
|
/** ED JWK "d" (Private Key) Parameter */
|
|
289
318
|
d: string;
|
|
290
319
|
}
|
|
291
320
|
/** OKP JSON Web Keys */
|
|
292
|
-
type JWK_OKP = JWK_OKP_Public | JWK_OKP_Private
|
|
321
|
+
type JWK_OKP<Alg extends JWK_OKP_SIGN | JWK_ECDH_ES | (string & {}) = string> = JWK_OKP_Public<Alg> | JWK_OKP_Private<Alg>;
|
|
293
322
|
/** oct JSON Web Keys */
|
|
294
|
-
interface JWK_oct extends JWKParameters {
|
|
323
|
+
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> {
|
|
295
324
|
/** Oct JWK "k" (Key Value) Parameter */
|
|
296
325
|
k: string;
|
|
297
326
|
}
|
|
298
327
|
/** Symmetric JSON Web Keys */
|
|
299
|
-
type JWK_Symmetric = JWK_oct
|
|
328
|
+
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>;
|
|
300
329
|
/** Asymmetric JSON Web Keys */
|
|
301
|
-
type JWK_Asymmetric = JWK_RSA | JWK_EC | JWK_OKP
|
|
330
|
+
type JWK_Asymmetric<Alg extends string = string> = JWK_RSA<Alg> | JWK_EC<Alg> | JWK_OKP<Alg>;
|
|
302
331
|
/** Public JSON Web Keys */
|
|
303
|
-
type JWK_Public = JWK_RSA_Public | JWK_EC_Public | JWK_OKP_Public
|
|
332
|
+
type JWK_Public<Alg extends string = string> = JWK_RSA_Public<Alg> | JWK_EC_Public<Alg> | JWK_OKP_Public<Alg>;
|
|
304
333
|
/** Private JSON Web Keys */
|
|
305
|
-
type JWK_Private = JWK_RSA_Private | JWK_EC_Private | JWK_OKP_Private
|
|
334
|
+
type JWK_Private<Alg extends string = string> = JWK_RSA_Private<Alg> | JWK_EC_Private<Alg> | JWK_OKP_Private<Alg>;
|
|
306
335
|
/**
|
|
307
336
|
* JSON Web Key ({@link https://www.rfc-editor.org/rfc/rfc7517 JWK}). "RSA", "EC", "OKP" and "oct" key types are supported.
|
|
308
337
|
*/
|
|
309
|
-
type JWK = JWK_oct | JWK_RSA | JWK_EC | JWK_OKP
|
|
338
|
+
type JWK<Alg extends string = string> = JWK_oct<Alg> | JWK_RSA<Alg> | JWK_EC<Alg> | JWK_OKP<Alg>;
|
|
310
339
|
/**
|
|
311
|
-
* A pair of public and private JSON Web Keys
|
|
340
|
+
* A pair of public and private JSON Web Keys, narrowed by `Alg` when that
|
|
341
|
+
* uniquely identifies the key family:
|
|
342
|
+
*
|
|
343
|
+
* - `JWK_Pair<"RS256">` → RSA pair only
|
|
344
|
+
* - `JWK_Pair<"ES256">` → EC pair only
|
|
345
|
+
* - `JWK_Pair<"ECDH-ES+A256KW">` → EC pair **or** OKP pair (curve decides at runtime)
|
|
346
|
+
* - `JWK_Pair<"Ed25519">` / `JWK_Pair<"EdDSA">` → OKP pair only
|
|
347
|
+
*
|
|
348
|
+
* The final branch is a generic fallback (`Alg = string`, or any custom /
|
|
349
|
+
* forward-compat algorithm that doesn't match a known family) — it yields
|
|
350
|
+
* the permissive three-branch union.
|
|
312
351
|
*/
|
|
313
|
-
type JWK_Pair = {
|
|
314
|
-
publicKey: JWK_RSA_Public
|
|
315
|
-
privateKey: JWK_RSA_Private
|
|
352
|
+
type JWK_Pair<Alg extends string = string> = Alg extends JWK_RSA_SIGN | JWK_RSA_PSS | JWK_RSA_ENC ? {
|
|
353
|
+
publicKey: JWK_RSA_Public<Alg>;
|
|
354
|
+
privateKey: JWK_RSA_Private<Alg>;
|
|
355
|
+
} : Alg extends JWK_ECDSA ? {
|
|
356
|
+
publicKey: JWK_EC_Public<Alg>;
|
|
357
|
+
privateKey: JWK_EC_Private<Alg>;
|
|
358
|
+
} : Alg extends JWK_ECDH_ES ? {
|
|
359
|
+
publicKey: JWK_EC_Public<Alg>;
|
|
360
|
+
privateKey: JWK_EC_Private<Alg>;
|
|
316
361
|
} | {
|
|
317
|
-
publicKey:
|
|
318
|
-
privateKey:
|
|
362
|
+
publicKey: JWK_OKP_Public<Alg>;
|
|
363
|
+
privateKey: JWK_OKP_Private<Alg>;
|
|
364
|
+
} : Alg extends JWK_OKP_SIGN ? {
|
|
365
|
+
publicKey: JWK_OKP_Public<Alg>;
|
|
366
|
+
privateKey: JWK_OKP_Private<Alg>;
|
|
367
|
+
} : {
|
|
368
|
+
publicKey: JWK_RSA_Public<Alg>;
|
|
369
|
+
privateKey: JWK_RSA_Private<Alg>;
|
|
319
370
|
} | {
|
|
320
|
-
publicKey:
|
|
321
|
-
privateKey:
|
|
371
|
+
publicKey: JWK_EC_Public<Alg>;
|
|
372
|
+
privateKey: JWK_EC_Private<Alg>;
|
|
373
|
+
} | {
|
|
374
|
+
publicKey: JWK_OKP_Public<Alg>;
|
|
375
|
+
privateKey: JWK_OKP_Private<Alg>;
|
|
322
376
|
};
|
|
323
377
|
/**
|
|
324
378
|
* JSON Web Key Set ({@link https://www.rfc-editor.org/rfc/rfc7517 JWK Set}). "RSA", "EC" and "oct" key types are supported.
|
|
379
|
+
*
|
|
380
|
+
* The optional `T` generic preserves the precise key tuple when constructed
|
|
381
|
+
* in TS — e.g. `JWKSet<[JWK_oct<"HS256">, JWK_EC_Public<"ES256">]>` — while the
|
|
382
|
+
* default `JWK[]` keeps the permissive behavior expected for JWKS fetched from
|
|
383
|
+
* external sources (runtime trials each candidate).
|
|
325
384
|
*/
|
|
326
|
-
interface JWKSet {
|
|
385
|
+
interface JWKSet<T extends readonly JWK[] = JWK[]> {
|
|
327
386
|
/** JWK Set "keys" Parameter */
|
|
328
|
-
keys:
|
|
387
|
+
keys: T;
|
|
329
388
|
[parameter: string]: unknown;
|
|
330
389
|
}
|
|
331
390
|
/** JWK Key Algorithms */
|
|
@@ -345,8 +404,6 @@ type JWK_Symmetric_Algorithm = JWK_HMAC | JWK_AES_KW | JWK_AES_GCM | JWK_AES_GCM
|
|
|
345
404
|
type JWK_Asymmetric_Algorithm = JWK_RSA_SIGN | JWK_RSA_PSS | JWK_ECDSA | JWK_RSA_ENC | JWK_OKP_SIGN | JWK_ECDH_ES;
|
|
346
405
|
type JWKAlgorithm = JWK_Symmetric_Algorithm | JWK_Asymmetric_Algorithm | JWK_AES_CBC_HMAC | JWK_PBES2 | JWK_ECDH_ES | "dir";
|
|
347
406
|
type JWKPEMAlgorithm = JWK_RSA_PSS | JWK_RSA_SIGN | JWK_RSA_ENC | JWK_ECDSA | JWK_ECDH_ES | JWK_OKP_SIGN;
|
|
348
|
-
//#endregion
|
|
349
|
-
//#region src/core/types/jwt.d.ts
|
|
350
407
|
/** Header Parameters common to JWE and JWS */
|
|
351
408
|
interface JoseHeaderParameters {
|
|
352
409
|
/** "kid" (Key ID) Header Parameter */
|
|
@@ -412,7 +469,11 @@ interface JWTClaimValidationOptions {
|
|
|
412
469
|
subject?: string;
|
|
413
470
|
/** Maximum token age, from the JWT "iat" (Issued At) Claim value. Implies presence requirement. */
|
|
414
471
|
maxTokenAge?: MaxTokenAge;
|
|
415
|
-
/**
|
|
472
|
+
/**
|
|
473
|
+
* Clock skew tolerance (in seconds) for validating time-based claims (nbf/exp/iat).
|
|
474
|
+
*
|
|
475
|
+
* @default 0
|
|
476
|
+
*/
|
|
416
477
|
clockTolerance?: number;
|
|
417
478
|
/** Expected JWT "typ" (Type) Header Parameter value. Implies presence requirement. */
|
|
418
479
|
typ?: string;
|
|
@@ -428,10 +489,99 @@ interface JWTClaimValidationOptions {
|
|
|
428
489
|
*/
|
|
429
490
|
recognizedHeaders?: string[];
|
|
430
491
|
}
|
|
431
|
-
|
|
432
|
-
|
|
492
|
+
/**
|
|
493
|
+
* All known error codes thrown by unjwt.
|
|
494
|
+
*
|
|
495
|
+
* Code naming follows the JOSE spec hierarchy:
|
|
496
|
+
* ERR_JWT_* — RFC 7519 JSON Web Token claim validation
|
|
497
|
+
* ERR_JWS_* — RFC 7515 JSON Web Signature
|
|
498
|
+
* ERR_JWE_* — RFC 7516 JSON Web Encryption
|
|
499
|
+
* ERR_JWK_* — RFC 7517 JSON Web Key
|
|
500
|
+
*/
|
|
501
|
+
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 & {});
|
|
502
|
+
/**
|
|
503
|
+
* Maps known error codes to their structured `cause` shapes.
|
|
504
|
+
* Only codes that carry decoded context beyond the message appear here.
|
|
505
|
+
* Extend this interface when new structured causes are introduced.
|
|
506
|
+
*/
|
|
507
|
+
interface JWTErrorCauseMap {
|
|
508
|
+
/** Decoded claims available at the point the lifetime check failed. */
|
|
509
|
+
ERR_JWT_EXPIRED: {
|
|
510
|
+
jti?: string;
|
|
511
|
+
iat?: number;
|
|
512
|
+
exp?: number;
|
|
513
|
+
};
|
|
514
|
+
}
|
|
515
|
+
/**
|
|
516
|
+
* Base error class for all unjwt errors. Every error thrown by the library is
|
|
517
|
+
* an instance of `JWTError`, so a single `instanceof` check is sufficient to
|
|
518
|
+
* distinguish library errors from other thrown values. Use the `code` property
|
|
519
|
+
* (or the `isJWTError` type guard) to narrow to a specific error condition.
|
|
520
|
+
*
|
|
521
|
+
* @example
|
|
522
|
+
* import { JWTError, isJWTError } from "unjwt/jws";
|
|
523
|
+
*
|
|
524
|
+
* try {
|
|
525
|
+
* await verify(token, key);
|
|
526
|
+
* } catch (err) {
|
|
527
|
+
* if (isJWTError(err, "ERR_JWT_EXPIRED")) {
|
|
528
|
+
* console.log(err.cause.jti); // string | undefined
|
|
529
|
+
* }
|
|
530
|
+
* }
|
|
531
|
+
*/
|
|
532
|
+
declare class JWTError<TCode extends JWTErrorCode = JWTErrorCode> extends Error {
|
|
533
|
+
readonly code: TCode;
|
|
534
|
+
override readonly cause?: unknown;
|
|
535
|
+
constructor(message: string, code: TCode, cause?: unknown);
|
|
536
|
+
}
|
|
537
|
+
/**
|
|
538
|
+
* Type guard that narrows `error` to `JWTError`.
|
|
539
|
+
*
|
|
540
|
+
* When called with a code that is a key of `JWTErrorCauseMap`, the return
|
|
541
|
+
* type is additionally narrowed to include the structured `cause` shape for
|
|
542
|
+
* that code. When called with any other `JWTErrorCode`, `code` is narrowed
|
|
543
|
+
* but `cause` remains `unknown`. When called without a code, narrows only to
|
|
544
|
+
* `JWTError`.
|
|
545
|
+
*
|
|
546
|
+
* @example
|
|
547
|
+
* if (isJWTError(err, "ERR_JWT_EXPIRED")) {
|
|
548
|
+
* err.cause.jti // string | undefined ✓
|
|
549
|
+
* }
|
|
550
|
+
*/
|
|
551
|
+
declare function isJWTError<T extends keyof JWTErrorCauseMap>(error: unknown, code: T): error is JWTError<T> & {
|
|
552
|
+
cause: JWTErrorCauseMap[T];
|
|
553
|
+
};
|
|
554
|
+
declare function isJWTError<T extends JWTErrorCode>(error: unknown, code: T): error is JWTError<T>;
|
|
555
|
+
declare function isJWTError(error: unknown): error is JWTError;
|
|
556
|
+
type StrictOmit<T, K extends keyof T | (string & {}) | (number & {}) | (symbol & {})> = { [P in keyof T as P extends K ? never : P]: T[P] };
|
|
433
557
|
/** JWS Signing Algorithm Identifier. */
|
|
434
558
|
type JWSAlgorithm = JWK_HMAC | JWK_RSA_SIGN | JWK_RSA_PSS | JWK_ECDSA | JWK_OKP_SIGN;
|
|
559
|
+
/**
|
|
560
|
+
* Asymmetric private JWKs admissible as a signing key. RSA keys carry a
|
|
561
|
+
* signing `alg` (RS* or PS*); EC keys carry an ECDSA alg; OKP keys carry an Ed
|
|
562
|
+
* signing alg.
|
|
563
|
+
*/
|
|
564
|
+
type JWSAsymmetricPrivateJWK = JWK_RSA_Private<JWK_RSA_SIGN | JWK_RSA_PSS> | JWK_EC_Private<JWK_ECDSA> | JWK_OKP_Private<JWK_OKP_SIGN>;
|
|
565
|
+
/**
|
|
566
|
+
* Asymmetric public JWKs admissible as a verification key. RSA keys carry a
|
|
567
|
+
* signing `alg` (RS* or PS*); EC keys carry an ECDSA alg; OKP keys carry an Ed
|
|
568
|
+
* signing alg.
|
|
569
|
+
*/
|
|
570
|
+
type JWSAsymmetricPublicJWK = JWK_RSA_Public<JWK_RSA_SIGN | JWK_RSA_PSS> | JWK_EC_Public<JWK_ECDSA> | JWK_OKP_Public<JWK_OKP_SIGN>;
|
|
571
|
+
/**
|
|
572
|
+
* JWKs admissible as the `key` argument of {@link sign}. HMAC oct keys carry a
|
|
573
|
+
* {@link JWK_HMAC} alg; asymmetric private keys carry their family's signing alg.
|
|
574
|
+
* A JWK whose `alg` points at a non-signing family (e.g. `"RSA-OAEP"`) is
|
|
575
|
+
* rejected at the type level.
|
|
576
|
+
*/
|
|
577
|
+
type JWSSignJWK = JWK_oct<JWK_HMAC> | JWSAsymmetricPrivateJWK;
|
|
578
|
+
/**
|
|
579
|
+
* JWKs admissible as a `key` for {@link verify}. HMAC oct keys carry a
|
|
580
|
+
* {@link JWK_HMAC} alg; asymmetric public keys carry their family's signing alg.
|
|
581
|
+
* A JWK whose `alg` points at a non-signing family (e.g. `"RSA-OAEP"`) is
|
|
582
|
+
* rejected at the type level.
|
|
583
|
+
*/
|
|
584
|
+
type JWSVerifyJWK = JWK_oct<JWK_HMAC> | JWSAsymmetricPublicJWK;
|
|
435
585
|
/** Recognized JWS Header Parameters, any other Header Members may also be present. */
|
|
436
586
|
interface JWSHeaderParameters extends JoseHeaderParameters {
|
|
437
587
|
/** JWS "alg" (Algorithm) Header Parameter */
|
|
@@ -455,16 +605,45 @@ interface JWSSignOptions {
|
|
|
455
605
|
/** The JWS Algorithm to use. Must be provided. */
|
|
456
606
|
alg?: JWSAlgorithm;
|
|
457
607
|
/**
|
|
458
|
-
* Additional protected header parameters. `alg` is
|
|
459
|
-
* `typ` defaults to "JWT"
|
|
608
|
+
* Additional protected header parameters. `alg` is always derived from the top-level `alg`
|
|
609
|
+
* option (or inferred from the key) and cannot be overridden. `typ` defaults to `"JWT"`
|
|
610
|
+
* when the payload is a JSON object.
|
|
460
611
|
*/
|
|
461
|
-
protectedHeader?: JWSHeaderParameters
|
|
612
|
+
protectedHeader?: StrictOmit<JWSHeaderParameters, "alg"> & {
|
|
613
|
+
alg?: never;
|
|
614
|
+
};
|
|
462
615
|
/** Date to use when comparing NumericDate claims, defaults to `new Date()`. */
|
|
463
616
|
currentDate?: Date;
|
|
464
617
|
/**
|
|
465
|
-
*
|
|
618
|
+
* Duration until the JWS should expire, relative to `currentDate` (or `new Date()`).
|
|
619
|
+
* Skipped when the payload already carries an `exp` claim.
|
|
620
|
+
*
|
|
621
|
+
* Mutually exclusive with {@link expiresAt}.
|
|
466
622
|
*/
|
|
467
623
|
expiresIn?: ExpiresIn;
|
|
624
|
+
/**
|
|
625
|
+
* Absolute moment at which the JWS should expire (sets the `exp` claim directly).
|
|
626
|
+
* Skipped when the payload already carries an `exp` claim.
|
|
627
|
+
*
|
|
628
|
+
* Mutually exclusive with {@link expiresIn}.
|
|
629
|
+
*/
|
|
630
|
+
expiresAt?: Date;
|
|
631
|
+
/**
|
|
632
|
+
* Duration from `iat` before which the JWS must not be accepted.
|
|
633
|
+
* `0` is allowed and sets `nbf = iat` (explicit temporal floor at sign time).
|
|
634
|
+
* Skipped when the payload already carries an `nbf` claim.
|
|
635
|
+
*
|
|
636
|
+
* Mutually exclusive with {@link notBeforeAt}.
|
|
637
|
+
*/
|
|
638
|
+
notBeforeIn?: ExpiresIn;
|
|
639
|
+
/**
|
|
640
|
+
* Absolute moment before which the JWS must not be accepted (sets the `nbf`
|
|
641
|
+
* claim directly per RFC 7519 §4.1.5). Skipped when the payload already
|
|
642
|
+
* carries an `nbf` claim.
|
|
643
|
+
*
|
|
644
|
+
* Mutually exclusive with {@link notBeforeIn}.
|
|
645
|
+
*/
|
|
646
|
+
notBeforeAt?: Date;
|
|
468
647
|
}
|
|
469
648
|
/** Result of JWS verification */
|
|
470
649
|
interface JWSVerifyResult<T extends JOSEPayload = JOSEPayload> {
|
|
@@ -488,11 +667,146 @@ interface JWSVerifyOptions extends JWTClaimValidationOptions {
|
|
|
488
667
|
*/
|
|
489
668
|
validateClaims?: boolean;
|
|
490
669
|
}
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
670
|
+
/**
|
|
671
|
+
* JWS Flattened JSON Serialization, RFC 7515 §7.2.2. Accepted as input by
|
|
672
|
+
* {@link verifyMulti} and normalized to {@link JWSGeneralSerialization}
|
|
673
|
+
* internally. Emitted by {@link generalToFlattenedJWS} on a single-signature
|
|
674
|
+
* General serialization.
|
|
675
|
+
*/
|
|
676
|
+
interface JWSFlattenedSerialization {
|
|
677
|
+
/** The JWS Payload. base64url-encoded when `b64 !== false`. */
|
|
678
|
+
payload: string;
|
|
679
|
+
/** Base64URL-encoded JWS Protected Header (part of the signing input). */
|
|
680
|
+
protected?: string;
|
|
681
|
+
/** JWS Unprotected Header (not part of the signing input). */
|
|
682
|
+
header?: JWSHeaderParameters;
|
|
683
|
+
/** Base64URL-encoded signature bytes. */
|
|
684
|
+
signature: string;
|
|
685
|
+
}
|
|
686
|
+
/**
|
|
687
|
+
* JWS General JSON Serialization, RFC 7515 §7.2.1. Canonical multi-signature
|
|
688
|
+
* output shape of {@link signMulti}.
|
|
689
|
+
*
|
|
690
|
+
* `payload` is shared across all signatures and carries base64url-encoded
|
|
691
|
+
* bytes by default. When the consistent `b64: false` signing mode is used
|
|
692
|
+
* (RFC 7797), `payload` holds the raw UTF-8 payload string instead.
|
|
693
|
+
*/
|
|
694
|
+
interface JWSGeneralSerialization extends Omit<JWSFlattenedSerialization, "protected" | "header" | "signature"> {
|
|
695
|
+
/** One entry per signer. */
|
|
696
|
+
signatures: JWSGeneralSignature[];
|
|
697
|
+
}
|
|
698
|
+
/** A single signature entry within {@link JWSGeneralSerialization.signatures}. */
|
|
699
|
+
type JWSGeneralSignature = Pick<JWSFlattenedSerialization, "protected" | "header" | "signature">;
|
|
700
|
+
/**
|
|
701
|
+
* Input shape for a single signer passed to {@link signMulti}.
|
|
702
|
+
*
|
|
703
|
+
* `alg` is inferred from `key.alg`; throws `ERR_JWS_SIGNER_ALG_INFERENCE`
|
|
704
|
+
* when absent. `kid` is pulled from `key.kid` when present.
|
|
705
|
+
*/
|
|
706
|
+
interface JWSMultiSigner {
|
|
707
|
+
/** Signing key (JWK-first; `alg` inferred from `key.alg`). */
|
|
708
|
+
key: JWSSignJWK;
|
|
709
|
+
/**
|
|
710
|
+
* Extra per-signer JWS Protected Header parameters (RFC 7515 §7.2.1).
|
|
711
|
+
* `alg` is always derived from the JWK and cannot be set here. `b64`
|
|
712
|
+
* MUST be consistent across every signer (RFC 7797 §3) — if set on one
|
|
713
|
+
* signer it must match on all.
|
|
714
|
+
*/
|
|
715
|
+
protectedHeader?: StrictOmit<JWSHeaderParameters, "alg"> & {
|
|
716
|
+
alg?: never;
|
|
717
|
+
};
|
|
718
|
+
/** Per-signer JWS Unprotected Header (not part of signing input). */
|
|
719
|
+
unprotectedHeader?: JWSHeaderParameters;
|
|
720
|
+
}
|
|
721
|
+
/**
|
|
722
|
+
* Options for {@link signMulti}. Mirrors {@link JWSSignOptions} minus the
|
|
723
|
+
* per-signer fields (`alg`, `protectedHeader` — set those on each
|
|
724
|
+
* {@link JWSMultiSigner} instead).
|
|
725
|
+
*/
|
|
726
|
+
interface JWSMultiSignOptions extends StrictOmit<JWSSignOptions, "alg" | "protectedHeader"> {}
|
|
727
|
+
/** Options for {@link verifyMulti}. Extends {@link JWSVerifyOptions}. */
|
|
728
|
+
interface JWSMultiVerifyOptions extends JWSVerifyOptions {
|
|
729
|
+
/**
|
|
730
|
+
* When `false` (default), verification trials signatures in order — mirrors
|
|
731
|
+
* the multi-key retry behaviour of {@link verify} against a JWK Set. When
|
|
732
|
+
* `true`, only signatures whose header unambiguously matches the provided
|
|
733
|
+
* key (by `kid`, then by `kty`/`crv`/length) are attempted, and any
|
|
734
|
+
* mismatch throws `ERR_JWS_NO_MATCHING_SIGNER` before any crypto work.
|
|
735
|
+
*/
|
|
736
|
+
strictSignerMatch?: boolean;
|
|
737
|
+
}
|
|
738
|
+
/**
|
|
739
|
+
* Result of a {@link verifyMulti} operation. Extends {@link JWSVerifyResult}
|
|
740
|
+
* with the per-signer header and matched signature index.
|
|
741
|
+
*/
|
|
742
|
+
interface JWSMultiVerifyResult<T extends JOSEPayload = JOSEPayload> extends JWSVerifyResult<T> {
|
|
743
|
+
/** Parsed per-signer unprotected header of the signature that verified. */
|
|
744
|
+
signerHeader?: JWSHeaderParameters;
|
|
745
|
+
/** Index into `jws.signatures` of the signature that successfully verified. */
|
|
746
|
+
signerIndex: number;
|
|
747
|
+
}
|
|
748
|
+
/**
|
|
749
|
+
* Options for {@link verifyMultiAll}. Inherits the same validation knobs as
|
|
750
|
+
* {@link JWSMultiVerifyOptions} minus `strictSignerMatch` (not meaningful when
|
|
751
|
+
* every signature is independently reported).
|
|
752
|
+
*/
|
|
753
|
+
interface JWSMultiVerifyAllOptions extends StrictOmit<JWSMultiVerifyOptions, "strictSignerMatch"> {}
|
|
754
|
+
/**
|
|
755
|
+
* Per-signature outcome collected by {@link verifyMultiAll}. Discriminated by
|
|
756
|
+
* `verified`:
|
|
757
|
+
*
|
|
758
|
+
* - `verified: true` — the signature cryptographically verified and any
|
|
759
|
+
* claim/`crit` validation the caller asked for also passed. `payload` is
|
|
760
|
+
* provided.
|
|
761
|
+
* - `verified: false` — verification could not be completed for this
|
|
762
|
+
* signature. `error` carries the {@link JWTError} reason (signature
|
|
763
|
+
* invalid, disallowed alg, `typ` mismatch, key-resolver failure, malformed
|
|
764
|
+
* protected header, expired claim, etc.). `protectedHeader` / `signerHeader`
|
|
765
|
+
* are populated when they were successfully parsed before failure.
|
|
766
|
+
*
|
|
767
|
+
* Callers apply their own policy over the returned array — e.g. "all must
|
|
768
|
+
* verify", "quorum of N", "signed by these specific kids".
|
|
769
|
+
*/
|
|
770
|
+
type JWSMultiVerifyOutcome<T extends JOSEPayload = JOSEPayload> = {
|
|
771
|
+
signerIndex: number;
|
|
772
|
+
verified: true;
|
|
773
|
+
payload: T;
|
|
774
|
+
protectedHeader: JWSProtectedHeader;
|
|
775
|
+
signerHeader?: JWSHeaderParameters;
|
|
776
|
+
} | {
|
|
777
|
+
signerIndex: number;
|
|
778
|
+
verified: false;
|
|
779
|
+
error: JWTError;
|
|
780
|
+
protectedHeader?: JWSProtectedHeader;
|
|
781
|
+
signerHeader?: JWSHeaderParameters;
|
|
782
|
+
};
|
|
783
|
+
/**
|
|
784
|
+
* Algorithms admissible on an `oct` JWK used for JWE key management. Mirrors
|
|
785
|
+
* the runtime aliasing table in `jweAlgsFromOctJWK` — HMAC algs intentionally
|
|
786
|
+
* excluded (they don't resolve to any JWE `alg`).
|
|
787
|
+
*/
|
|
788
|
+
type _JWEOctAlg = JWK_AES_KW | JWK_AES_GCM | JWK_AES_GCM_KW | JWK_AES_CBC_HMAC | JWK_PBES2 | "dir";
|
|
789
|
+
/**
|
|
790
|
+
* Asymmetric public JWKs admissible for JWE encryption. RSA keys carry an
|
|
791
|
+
* RSA-OAEP alg; EC/OKP keys carry an ECDH-ES alg.
|
|
792
|
+
*/
|
|
793
|
+
type JWEAsymmetricPublicJWK = JWK_RSA_Public<JWK_RSA_ENC> | JWK_EC_Public<JWK_ECDH_ES> | JWK_OKP_Public<JWK_ECDH_ES>;
|
|
794
|
+
/**
|
|
795
|
+
* Asymmetric private JWKs admissible for JWE decryption. RSA keys carry an
|
|
796
|
+
* RSA-OAEP alg; EC/OKP keys carry an ECDH-ES alg.
|
|
797
|
+
*/
|
|
798
|
+
type JWEAsymmetricPrivateJWK = JWK_RSA_Private<JWK_RSA_ENC> | JWK_EC_Private<JWK_ECDH_ES> | JWK_OKP_Private<JWK_ECDH_ES>;
|
|
799
|
+
/**
|
|
800
|
+
* JWKs admissible as the `key` argument of {@link encrypt}. A JWK whose `alg`
|
|
801
|
+
* points at a non-JWE family (e.g. `"HS256"`, `"RS256"`) is rejected at the
|
|
802
|
+
* type level.
|
|
803
|
+
*/
|
|
804
|
+
type JWEEncryptJWK = JWK_oct<_JWEOctAlg> | JWEAsymmetricPublicJWK;
|
|
805
|
+
/**
|
|
806
|
+
* JWKs admissible as a `key` for {@link decrypt}. A JWK whose `alg` points at
|
|
807
|
+
* a non-JWE family (e.g. `"HS256"`, `"RS256"`) is rejected at the type level.
|
|
808
|
+
*/
|
|
809
|
+
type JWEDecryptJWK = JWK_oct<_JWEOctAlg> | JWEAsymmetricPrivateJWK;
|
|
496
810
|
/** Recognized JWE Header Parameters, any other Header Members may also be present. */
|
|
497
811
|
interface JWEHeaderParameters extends JoseHeaderParameters {
|
|
498
812
|
/**
|
|
@@ -569,8 +883,36 @@ interface JWEEncryptOptions {
|
|
|
569
883
|
enc?: ContentEncryptionAlgorithm;
|
|
570
884
|
/** Date to use when computing NumericDate claims, defaults to `new Date()`. */
|
|
571
885
|
currentDate?: Date;
|
|
572
|
-
/**
|
|
886
|
+
/**
|
|
887
|
+
* Duration until the JWT should expire, relative to `currentDate` (or `new Date()`).
|
|
888
|
+
* Skipped when the payload already carries an `exp` claim.
|
|
889
|
+
*
|
|
890
|
+
* Mutually exclusive with {@link expiresAt}.
|
|
891
|
+
*/
|
|
573
892
|
expiresIn?: ExpiresIn;
|
|
893
|
+
/**
|
|
894
|
+
* Absolute moment at which the JWT should expire (sets the `exp` claim directly).
|
|
895
|
+
* Skipped when the payload already carries an `exp` claim.
|
|
896
|
+
*
|
|
897
|
+
* Mutually exclusive with {@link expiresIn}.
|
|
898
|
+
*/
|
|
899
|
+
expiresAt?: Date;
|
|
900
|
+
/**
|
|
901
|
+
* Duration from `iat` before which the JWT must not be accepted.
|
|
902
|
+
* `0` is allowed and sets `nbf = iat` (explicit temporal floor at sign time).
|
|
903
|
+
* Skipped when the payload already carries an `nbf` claim.
|
|
904
|
+
*
|
|
905
|
+
* Mutually exclusive with {@link notBeforeAt}.
|
|
906
|
+
*/
|
|
907
|
+
notBeforeIn?: ExpiresIn;
|
|
908
|
+
/**
|
|
909
|
+
* Absolute moment before which the JWT must not be accepted (sets the `nbf`
|
|
910
|
+
* claim directly per RFC 7519 §4.1.5). Skipped when the payload already
|
|
911
|
+
* carries an `nbf` claim.
|
|
912
|
+
*
|
|
913
|
+
* Mutually exclusive with {@link notBeforeIn}.
|
|
914
|
+
*/
|
|
915
|
+
notBeforeAt?: Date;
|
|
574
916
|
/** Additional JWE Protected Header parameters. */
|
|
575
917
|
protectedHeader?: StrictOmit<JWEHeaderParameters, "alg" | "enc" | "iv" | "tag" | "p2s" | "p2c" | "epk" | "apu" | "apv">;
|
|
576
918
|
/** Initialization Vector for AES-GCMKW key wrapping. Generated if not provided. */
|
|
@@ -629,6 +971,10 @@ interface JWEDecryptOptions extends JWTClaimValidationOptions {
|
|
|
629
971
|
validateClaims?: boolean;
|
|
630
972
|
/** If true, include the Content Encryption Key (CEK) and Additional Authenticated Data (AAD) in the result. */
|
|
631
973
|
returnCek?: boolean;
|
|
974
|
+
/** Minimum accepted PBES2 `p2c` on unwrap. Defaults to 1000 (RFC 7518 §4.8.1.2). */
|
|
975
|
+
minIterations?: number;
|
|
976
|
+
/** Maximum accepted PBES2 `p2c` on unwrap. Defaults to 1_000_000 to cap PBKDF2 DoS potential. */
|
|
977
|
+
maxIterations?: number;
|
|
632
978
|
}
|
|
633
979
|
/**
|
|
634
980
|
* JWE Protected Header — the parsed and validated protected header returned
|
|
@@ -654,9 +1000,120 @@ interface JWEDecryptResult<T extends JOSEPayload = JOSEPayload> {
|
|
|
654
1000
|
/** The Additional Authenticated Data (AAD) used, as Uint8Array. Only present when `returnCek` is true. */
|
|
655
1001
|
aad?: Uint8Array<ArrayBuffer>;
|
|
656
1002
|
}
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
1003
|
+
/**
|
|
1004
|
+
* JWE Flattened JSON Serialization, RFC 7516 §7.2.2.
|
|
1005
|
+
*/
|
|
1006
|
+
interface JWEFlattenedSerialization {
|
|
1007
|
+
header?: JWEHeaderParameters;
|
|
1008
|
+
encrypted_key?: string;
|
|
1009
|
+
/** Base64URL-encoded JWE Protected Header (part of AAD). */
|
|
1010
|
+
protected?: string;
|
|
1011
|
+
/** Shared JWE Unprotected Header (JSON, not part of AAD). */
|
|
1012
|
+
unprotected?: JWEHeaderParameters;
|
|
1013
|
+
/** Base64URL-encoded external Additional Authenticated Data. */
|
|
1014
|
+
aad?: string;
|
|
1015
|
+
/** Base64URL-encoded IV (Initialization Vector). */
|
|
1016
|
+
iv?: string;
|
|
1017
|
+
/** Base64URL-encoded ciphertext. */
|
|
1018
|
+
ciphertext: string;
|
|
1019
|
+
/** Base64URL-encoded authentication tag. */
|
|
1020
|
+
tag?: string;
|
|
1021
|
+
}
|
|
1022
|
+
/**
|
|
1023
|
+
* JWE General JSON Serialization, RFC 7516 §7.2.1. The canonical
|
|
1024
|
+
* multi-recipient output shape of {@link encryptMulti}.
|
|
1025
|
+
*/
|
|
1026
|
+
interface JWEGeneralSerialization extends Omit<JWEFlattenedSerialization, "encrypted_key" | "header"> {
|
|
1027
|
+
/** One entry per recipient. */
|
|
1028
|
+
recipients: JWEGeneralRecipient[];
|
|
1029
|
+
}
|
|
1030
|
+
/** A single recipient entry within {@link JWEGeneralSerialization.recipients}. */
|
|
1031
|
+
interface JWEGeneralRecipient {
|
|
1032
|
+
/** Per-recipient JWE Unprotected Header (JSON, not part of AAD). */
|
|
1033
|
+
header?: JWEHeaderParameters;
|
|
1034
|
+
/** Base64URL-encoded encrypted CEK for this recipient. */
|
|
1035
|
+
encrypted_key?: string;
|
|
1036
|
+
}
|
|
1037
|
+
/**
|
|
1038
|
+
* Input shape for a single recipient passed to {@link encryptMulti}.
|
|
1039
|
+
*
|
|
1040
|
+
* `alg` is inferred from `key.alg` or from the JWK's kty/curve/length using
|
|
1041
|
+
* the same rules as {@link encrypt}. `kid` is pulled from `key.kid` when
|
|
1042
|
+
* present. To override either, spread or set via {@link JWEMultiRecipient.header}.
|
|
1043
|
+
*/
|
|
1044
|
+
interface JWEMultiRecipient {
|
|
1045
|
+
/** Recipient key (JWK-first; `alg` inferred if absent from JWK). */
|
|
1046
|
+
key: JWEEncryptJWK;
|
|
1047
|
+
/**
|
|
1048
|
+
* Extra per-recipient JWE Unprotected Header parameters (RFC 7516 §7.2.1).
|
|
1049
|
+
* Excludes fields the library writes automatically: `alg`, `enc`, `iv`,
|
|
1050
|
+
* `tag`, `p2s`, `p2c`, `epk`, `apu`, `apv`.
|
|
1051
|
+
*
|
|
1052
|
+
* Typical use: `x5c`, `x5t`, custom routing metadata.
|
|
1053
|
+
*/
|
|
1054
|
+
header?: StrictOmit<JWEHeaderParameters, "alg" | "enc" | "iv" | "tag" | "p2s" | "p2c" | "epk" | "apu" | "apv">;
|
|
1055
|
+
/** ECDH-ES ephemeral key / party info for this recipient. */
|
|
1056
|
+
ecdh?: JWEEncryptOptions["ecdh"];
|
|
1057
|
+
/** PBES2 salt for this recipient. Randomized (16 bytes) when omitted. */
|
|
1058
|
+
p2s?: Uint8Array<ArrayBuffer>;
|
|
1059
|
+
/** PBES2 iteration count for this recipient. Defaults to 600_000. */
|
|
1060
|
+
p2c?: number;
|
|
1061
|
+
/** Initialization vector for AES-GCMKW key wrapping for this recipient. */
|
|
1062
|
+
keyManagementIV?: Uint8Array<ArrayBuffer>;
|
|
1063
|
+
}
|
|
1064
|
+
/**
|
|
1065
|
+
* Options for {@link encryptMulti}. Extends {@link JWEEncryptOptions} and drops
|
|
1066
|
+
* the fields that are per-recipient in multi-recipient mode (`alg`, `ecdh`,
|
|
1067
|
+
* `p2s`, `p2c`, `keyManagementIV` — set those on each {@link JWEMultiRecipient}
|
|
1068
|
+
* instead).
|
|
1069
|
+
*/
|
|
1070
|
+
interface JWEMultiEncryptOptions extends StrictOmit<JWEEncryptOptions, "alg" | "ecdh" | "p2s" | "p2c" | "keyManagementIV"> {
|
|
1071
|
+
/** Shared JWE Unprotected Header (surfaces as `unprotected` in the output). */
|
|
1072
|
+
sharedUnprotectedHeader?: Record<string, unknown>;
|
|
1073
|
+
/**
|
|
1074
|
+
* External Additional Authenticated Data (RFC 7516 §5.1). Encoded as
|
|
1075
|
+
* base64url and written to the `aad` field; the content cipher AAD becomes
|
|
1076
|
+
* `BASE64URL(protected) || '.' || BASE64URL(aad)`.
|
|
1077
|
+
*/
|
|
1078
|
+
aad?: Uint8Array<ArrayBuffer> | string;
|
|
1079
|
+
}
|
|
1080
|
+
/**
|
|
1081
|
+
* Options for {@link decryptMulti}. Extends {@link JWEDecryptOptions}.
|
|
1082
|
+
*/
|
|
1083
|
+
interface JWEMultiDecryptOptions extends JWEDecryptOptions {
|
|
1084
|
+
/**
|
|
1085
|
+
* When `false` (default) decryption trials recipients in order — mirrors the
|
|
1086
|
+
* multi-key retry behaviour of {@link decrypt} against a JWK Set. When
|
|
1087
|
+
* `true`, only recipients whose header unambiguously matches the provided
|
|
1088
|
+
* key (by `kid`, then by `kty`/`crv`/length) are attempted, and any mismatch
|
|
1089
|
+
* throws `ERR_JWE_NO_MATCHING_RECIPIENT` before any crypto work.
|
|
1090
|
+
*/
|
|
1091
|
+
strictRecipientMatch?: boolean;
|
|
1092
|
+
}
|
|
1093
|
+
/**
|
|
1094
|
+
* Result of a {@link decryptMulti} operation. Extends {@link JWEDecryptResult}
|
|
1095
|
+
* with the per-recipient header tier surfaced on the matching recipient.
|
|
1096
|
+
*/
|
|
1097
|
+
interface JWEMultiDecryptResult<T extends JOSEPayload = JOSEPayload> extends JWEDecryptResult<T> {
|
|
1098
|
+
/** Parsed shared unprotected header, when present on the serialization. */
|
|
1099
|
+
sharedUnprotectedHeader?: JWEHeaderParameters;
|
|
1100
|
+
/** Parsed per-recipient unprotected header of the recipient that decrypted. */
|
|
1101
|
+
recipientHeader?: JWEHeaderParameters;
|
|
1102
|
+
/** Index into `jwe.recipients` of the recipient that successfully decrypted. */
|
|
1103
|
+
recipientIndex: number;
|
|
1104
|
+
}
|
|
1105
|
+
/**
|
|
1106
|
+
* A time duration, expressed as an integer number of seconds or a human-readable
|
|
1107
|
+
* shorthand like `"10m"`, `"2h"`, `"7D"`.
|
|
1108
|
+
*
|
|
1109
|
+
* Shared base type for every duration-valued option in the library:
|
|
1110
|
+
* {@link ExpiresIn}, {@link NotBeforeIn}, {@link MaxTokenAge}.
|
|
1111
|
+
*/
|
|
1112
|
+
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"}`;
|
|
1113
|
+
/** Duration until `exp` — the `expiresIn` option on {@link sign} / {@link encrypt}. */
|
|
1114
|
+
type ExpiresIn = Duration;
|
|
1115
|
+
/** Duration from `iat` for `nbf` — the `notBeforeIn` option on {@link sign} / {@link encrypt}. */
|
|
1116
|
+
type NotBeforeIn = Duration;
|
|
1117
|
+
/** Duration for `maxTokenAge` validation on {@link verify} / {@link decrypt}. */
|
|
1118
|
+
type MaxTokenAge = Duration;
|
|
1119
|
+
export { DeriveKeyOptions as $, JWSMultiSigner as A, JWK_PBES2 as At, JWSVerifyResult as B, JWK_Symmetric as Bt, JWSAsymmetricPrivateJWK as C, JWK_EC_Private as Ct, JWSGeneralSignature as D, JWK_OKP_Private as Dt, JWSGeneralSerialization as E, JWK_OKP as Et, JWSProtectedHeader as F, JWK_RSA_ENC as Ft, isJWTError as G, UnwrappingKeyFor as Gt, JWTError as H, JWK_oct as Ht, JWSSignJWK as I, JWK_RSA_PSS as It, JWTClaimValidationOptions as J, WrappingKeyFor as Jt, JOSEPayload as K, WrapKeyOptions as Kt, JWSSignOptions as L, JWK_RSA_Private as Lt, JWSMultiVerifyOptions as M, JWK_Private as Mt, JWSMultiVerifyOutcome as N, JWK_Public as Nt, JWSHeaderParameters as O, JWK_OKP_Public as Ot, JWSMultiVerifyResult as P, JWK_RSA as Pt, ContentEncryptionAlgorithm as Q, JWSVerifyJWK as R, JWK_RSA_Public as Rt, JWSAlgorithm as S, JWK_ECDSA as St, JWSFlattenedSerialization as T, JWK_HMAC as Tt, JWTErrorCauseMap as U, KeyManagementAlgorithm as Ut, StrictOmit as V, JWK_Symmetric_Algorithm as Vt, JWTErrorCode as W, UnwrapKeyOptions as Wt, JoseHeaderParameters as X, JWTClaims as Y, CompositeKey as Z, JWEMultiDecryptOptions as _, JWK_AES_KW as _t, JWEAsymmetricPrivateJWK as a, GenerateKeyReturn as at, JWEMultiRecipient as b, JWK_EC as bt, JWEDecryptOptions as c, JWKCacheAdapter as ct, JWEEncryptOptions as d, JWKPEMAlgorithm as dt, DeriveKeyReturn as et, JWEFlattenedSerialization as f, JWKParameters as ft, JWEKeyManagementHeaderParameters as g, JWK_AES_GCM_KW as gt, JWEHeaderParameters as h, JWK_AES_GCM as ht, NotBeforeIn as i, GenerateKeyOptions as it, JWSMultiVerifyAllOptions as j, JWK_Pair as jt, JWSMultiSignOptions as k, JWK_OKP_SIGN as kt, JWEDecryptResult as l, JWKLookupFunction as lt, JWEGeneralSerialization as m, JWK_AES_CBC_HMAC as mt, ExpiresIn as n, GenerateJWKReturn as nt, JWEAsymmetricPublicJWK as o, JWK as ot, JWEGeneralRecipient as p, JWKSet as pt, JWT as q, WrapKeyResult as qt, MaxTokenAge as r, GenerateKeyAlgorithm as rt, JWEDecryptJWK as s, JWKAlgorithm as st, Duration as t, GenerateJWKOptions as tt, JWEEncryptJWK as u, JWKLookupFunctionHeader as ut, JWEMultiDecryptResult as v, JWK_Asymmetric as vt, JWSAsymmetricPublicJWK as w, JWK_EC_Public as wt, JWEProtectedHeader as x, JWK_ECDH_ES as xt, JWEMultiEncryptOptions as y, JWK_Asymmetric_Algorithm as yt, JWSVerifyOptions as z, JWK_RSA_SIGN as zt };
|