unjwt 0.5.39 → 0.6.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 (41) hide show
  1. package/README.md +156 -13
  2. package/dist/_chunks/_crypto.mjs +1014 -0
  3. package/dist/_chunks/error.d.mts +67 -0
  4. package/dist/_chunks/index.d.mts +631 -219
  5. package/dist/_chunks/jwk.d.mts +220 -87
  6. package/dist/_chunks/jws.mjs +729 -682
  7. package/dist/_chunks/utils.mjs +74 -69
  8. package/dist/adapters/h3v1/index.d.mts +282 -0
  9. package/dist/{_chunks/h3v1.mjs → adapters/h3v1/index.mjs} +204 -91
  10. package/dist/adapters/h3v2/index.d.mts +213 -0
  11. package/dist/adapters/{h3v2.mjs → h3v2/index.mjs} +215 -113
  12. package/dist/core/_crypto/index.d.mts +71 -0
  13. package/dist/core/_crypto/index.mjs +2 -0
  14. package/dist/core/jwe.d.mts +40 -0
  15. package/dist/{_chunks → core}/jwe.mjs +61 -32
  16. package/dist/core/jwk.d.mts +231 -0
  17. package/dist/core/jwk.mjs +686 -0
  18. package/dist/core/jws.d.mts +31 -0
  19. package/dist/core/jws.mjs +104 -0
  20. package/dist/{_chunks/index2.d.mts → core/utils/index.d.mts} +13 -12
  21. package/dist/core/utils/index.mjs +2 -0
  22. package/dist/index.d.mts +7 -6
  23. package/dist/index.mjs +5 -5
  24. package/package.json +50 -41
  25. package/dist/_chunks/chunk.mjs +0 -13
  26. package/dist/_chunks/jwe.d.mts +0 -43
  27. package/dist/_chunks/jwk.mjs +0 -1592
  28. package/dist/_chunks/jws.d.mts +0 -46
  29. package/dist/adapters/h3.d.mts +0 -3
  30. package/dist/adapters/h3.mjs +0 -3
  31. package/dist/adapters/h3v1.d.mts +0 -3
  32. package/dist/adapters/h3v1.mjs +0 -3
  33. package/dist/adapters/h3v2.d.mts +0 -184
  34. package/dist/jwe.d.mts +0 -3
  35. package/dist/jwe.mjs +0 -4
  36. package/dist/jwk.d.mts +0 -3
  37. package/dist/jwk.mjs +0 -3
  38. package/dist/jws.d.mts +0 -3
  39. package/dist/jws.mjs +0 -4
  40. package/dist/utils.d.mts +0 -3
  41. package/dist/utils.mjs +0 -2
@@ -1,4 +1,36 @@
1
- import { t as __exportAll } from "./chunk.mjs";
1
+ //#region src/core/error.ts
2
+ /**
3
+ * Base error class for all unjwt errors. Every error thrown by the library is
4
+ * an instance of `JWTError`, so a single `instanceof` check is sufficient to
5
+ * distinguish library errors from other thrown values. Use the `code` property
6
+ * (or the `isJWTError` type guard) to narrow to a specific error condition.
7
+ *
8
+ * @example
9
+ * import { JWTError, isJWTError } from "unjwt/jws";
10
+ *
11
+ * try {
12
+ * await verify(token, key);
13
+ * } catch (err) {
14
+ * if (isJWTError(err, "ERR_JWT_EXPIRED")) {
15
+ * console.log(err.cause.jti); // string | undefined
16
+ * }
17
+ * }
18
+ */
19
+ var JWTError = class extends Error {
20
+ code;
21
+ cause;
22
+ constructor(message, code, cause) {
23
+ super(message);
24
+ this.name = "JWTError";
25
+ this.code = code;
26
+ this.cause = cause;
27
+ }
28
+ };
29
+ function isJWTError(error, code) {
30
+ if (!(error instanceof JWTError)) return false;
31
+ return code === void 0 || error.code === code;
32
+ }
33
+ //#endregion
2
34
  //#region src/core/utils/jwt.ts
3
35
  /**
4
36
  * Apply default typ/cty semantics shared by JWS & JWE.
@@ -107,23 +139,31 @@ function validateJwtClaims(jwtClaims, options = {}) {
107
139
  if (options.subject) allRequiredClaims.add("sub");
108
140
  if (options.maxTokenAge) allRequiredClaims.add("iat");
109
141
  for (const claimName of allRequiredClaims) if (!(claimName in jwtClaims)) missingClaims.add(claimName);
110
- if (missingClaims.size > 0) throw new Error(`Missing required JWT Claims: ${[...missingClaims].join(", ")}`);
142
+ if (missingClaims.size > 0) throw new JWTError(`Missing required JWT Claims: ${[...missingClaims].join(", ")}`, "ERR_JWT_CLAIM_MISSING");
111
143
  if (options.issuer) {
112
144
  const expectedIssuers = maybeArray(options.issuer);
113
- if (!jwtClaims.iss || !expectedIssuers.includes(jwtClaims.iss)) throw new Error(`Invalid JWT "iss" (Issuer) Claim: Expected ${expectedIssuers.join(" or ")}, got ${jwtClaims.iss}`);
145
+ if (!jwtClaims.iss || !expectedIssuers.includes(jwtClaims.iss)) throw new JWTError(`Invalid JWT "iss" (Issuer) Claim: Expected ${expectedIssuers.join(" or ")}, got ${jwtClaims.iss}`, "ERR_JWT_CLAIM_INVALID");
114
146
  }
115
- if (options.subject && jwtClaims.sub !== options.subject) throw new Error(`Invalid JWT "sub" (Subject) Claim: Expected ${options.subject}, got ${jwtClaims.sub}`);
147
+ if (options.subject && jwtClaims.sub !== options.subject) throw new JWTError(`Invalid JWT "sub" (Subject) Claim: Expected ${options.subject}, got ${jwtClaims.sub}`, "ERR_JWT_CLAIM_INVALID");
116
148
  if (options.audience) {
117
149
  const expectedAudiences = maybeArray(options.audience);
118
150
  const claimAudience = maybeArray(jwtClaims.aud || []);
119
- if (!claimAudience.some((aud) => expectedAudiences.includes(aud))) throw new Error(`Invalid JWT "aud" (Audience) Claim: Expected ${expectedAudiences.join(" or ")}, got ${claimAudience.join(", ")}`);
151
+ if (!claimAudience.some((aud) => expectedAudiences.includes(aud))) throw new JWTError(`Invalid JWT "aud" (Audience) Claim: Expected ${expectedAudiences.join(" or ")}, got ${claimAudience.join(", ")}`, "ERR_JWT_CLAIM_INVALID");
120
152
  }
121
- if (typeof jwtClaims.nbf === "number" && jwtClaims.nbf > currentTime + clockTolerance) throw new Error(`JWT "nbf" (Not Before) Claim validation failed: Token is not yet valid (nbf: ${(/* @__PURE__ */ new Date(jwtClaims.nbf * 1e3)).toISOString()})`);
122
- if (typeof jwtClaims.exp === "number" && jwtClaims.exp <= currentTime - clockTolerance) throw new Error(`JWT "exp" (Expiration Time) Claim validation failed: Token has expired (exp: ${(/* @__PURE__ */ new Date(jwtClaims.exp * 1e3)).toISOString()})`);
153
+ if (typeof jwtClaims.nbf === "number" && jwtClaims.nbf > currentTime + clockTolerance) throw new JWTError(`JWT "nbf" (Not Before) Claim validation failed: Token is not yet valid (nbf: ${(/* @__PURE__ */ new Date(jwtClaims.nbf * 1e3)).toISOString()})`, "ERR_JWT_NBF");
154
+ if (typeof jwtClaims.exp === "number" && jwtClaims.exp <= currentTime - clockTolerance) throw new JWTError(`JWT "exp" (Expiration Time) Claim validation failed: Token has expired (exp: ${(/* @__PURE__ */ new Date(jwtClaims.exp * 1e3)).toISOString()})`, "ERR_JWT_EXPIRED", {
155
+ jti: jwtClaims.jti,
156
+ iat: jwtClaims.iat,
157
+ exp: jwtClaims.exp
158
+ });
123
159
  if (options.maxTokenAge) {
124
- if (typeof jwtClaims.iat !== "number") throw new TypeError("JWT \"iat\" (Issued At) Claim must be a number when maxTokenAge is set.");
125
- if (jwtClaims.iat > currentTime + clockTolerance) throw new Error(`JWT "iat" (Issued At) Claim validation failed: Token was issued in the future (iat: ${(/* @__PURE__ */ new Date(jwtClaims.iat * 1e3)).toISOString()})`);
126
- if (jwtClaims.iat < currentTime - computeMaxTokenAgeSeconds(options.maxTokenAge) - clockTolerance) throw new Error(`JWT "iat" (Issued At) Claim validation failed: Token is too old (maxTokenAge: ${options.maxTokenAge}s, iat: ${(/* @__PURE__ */ new Date(jwtClaims.iat * 1e3)).toISOString()})`);
160
+ if (typeof jwtClaims.iat !== "number") throw new JWTError("JWT \"iat\" (Issued At) Claim must be a number when maxTokenAge is set.", "ERR_JWT_CLAIM_INVALID");
161
+ if (jwtClaims.iat > currentTime + clockTolerance) throw new JWTError(`JWT "iat" (Issued At) Claim validation failed: Token was issued in the future (iat: ${(/* @__PURE__ */ new Date(jwtClaims.iat * 1e3)).toISOString()})`, "ERR_JWT_CLAIM_INVALID");
162
+ if (jwtClaims.iat < currentTime - computeMaxTokenAgeSeconds(options.maxTokenAge) - clockTolerance) throw new JWTError(`JWT "iat" (Issued At) Claim validation failed: Token is too old (maxTokenAge: ${options.maxTokenAge}s, iat: ${(/* @__PURE__ */ new Date(jwtClaims.iat * 1e3)).toISOString()})`, "ERR_JWT_EXPIRED", {
163
+ jti: jwtClaims.jti,
164
+ iat: jwtClaims.iat,
165
+ exp: jwtClaims.exp
166
+ });
127
167
  }
128
168
  }
129
169
  const BASE_HEADER_PARAMS = [
@@ -138,11 +178,11 @@ const BASE_HEADER_PARAMS = [
138
178
  "x5u"
139
179
  ];
140
180
  /** Validate critical headers in JWS semantics. */
141
- function validateCriticalHeadersJWS(protectedHeader, requiredHeaders = []) {
181
+ function validateCriticalHeadersJWS(protectedHeader, recognizedHeaders = []) {
142
182
  if (!protectedHeader.crit) return;
143
183
  const missingHeaderParams = /* @__PURE__ */ new Set();
144
184
  const recognizedParams = new Set([
145
- ...requiredHeaders,
185
+ ...recognizedHeaders,
146
186
  ...BASE_HEADER_PARAMS,
147
187
  "b64"
148
188
  ]);
@@ -150,14 +190,14 @@ function validateCriticalHeadersJWS(protectedHeader, requiredHeaders = []) {
150
190
  if (recognizedParams.has(param) && (param in protectedHeader || param === "b64")) continue;
151
191
  missingHeaderParams.add(param);
152
192
  }
153
- if (missingHeaderParams.size > 0) throw new Error(`Missing critical header parameters: ${[...missingHeaderParams].join(", ")}`);
193
+ if (missingHeaderParams.size > 0) throw new JWTError(`Missing critical header parameters: ${[...missingHeaderParams].join(", ")}`, "ERR_JWS_INVALID");
154
194
  }
155
195
  /** Validate critical headers in JWE semantics. */
156
- function validateCriticalHeadersJWE(protectedHeader, understoodFromOptions) {
157
- if (protectedHeader.crit && !understoodFromOptions) throw new Error(`Unprocessed critical header parameters: ${protectedHeader.crit.join(", ")}`);
196
+ function validateCriticalHeadersJWE(protectedHeader, recognizedHeaders) {
197
+ if (protectedHeader.crit && !recognizedHeaders) throw new JWTError(`Unprocessed critical header parameters: ${protectedHeader.crit.join(", ")}`, "ERR_JWE_INVALID");
158
198
  if (!protectedHeader.crit) return;
159
199
  const understoodParams = new Set([
160
- ...understoodFromOptions || [],
200
+ ...recognizedHeaders || [],
161
201
  ...BASE_HEADER_PARAMS,
162
202
  "enc",
163
203
  "iv",
@@ -169,76 +209,41 @@ function validateCriticalHeadersJWE(protectedHeader, understoodFromOptions) {
169
209
  "apv"
170
210
  ]);
171
211
  for (const critParam of protectedHeader.crit) {
172
- if (!Object.prototype.hasOwnProperty.call(protectedHeader, critParam)) throw new Error(`Critical header parameter "${critParam}" listed in "crit" but not present in the protected header.`);
173
- if (!understoodParams.has(critParam)) throw new Error(`Unprocessed critical header parameters: ${critParam}`);
212
+ if (!Object.prototype.hasOwnProperty.call(protectedHeader, critParam)) throw new JWTError(`Critical header parameter "${critParam}" listed in "crit" but not present in the protected header.`, "ERR_JWE_INVALID");
213
+ if (!understoodParams.has(critParam)) throw new JWTError(`Unprocessed critical header parameters: ${critParam}`, "ERR_JWE_INVALID");
174
214
  }
175
215
  }
176
216
  //#endregion
177
217
  //#region src/core/utils/sanitize.ts
178
218
  /**
179
- * Forked from unsecure@0.0.4
219
+ * Originally derived from unsecure@0.0.4
180
220
  * Licensed under the MIT License.
181
221
  *
182
222
  * Source: https://github.com/sandros94/unsecure/blob/913ed5580c551153a19154b4916c67a8efb2be85/src/sanitize.ts
183
223
  */
184
224
  /**
185
- * Remove prototype-pollution vectors from a plain record in-place.
186
- * This strips __proto__, prototype, and constructor own properties.
187
- * Returns the same reference for convenience.
225
+ * Returns a deep structural copy of `obj` with prototype-pollution vectors
226
+ * stripped at every level (`__proto__`, `prototype`, `constructor`).
227
+ *
228
+ * The input is never modified. Arrays are copied element-by-element;
229
+ * nested objects are recursed with a WeakSet cycle guard.
188
230
  */
189
231
  function sanitizeObject(obj) {
190
232
  if (!obj || typeof obj !== "object") return obj;
191
- sanitizeKeys(obj);
192
- return obj;
233
+ return _sanitizeCopy(obj, /* @__PURE__ */ new WeakSet());
193
234
  }
194
- function sanitizeKeys(current, seen) {
195
- if (Object.prototype.hasOwnProperty.call(current, "__proto__")) delete current["__proto__"];
196
- if (Object.prototype.hasOwnProperty.call(current, "prototype")) delete current["prototype"];
197
- if (Object.prototype.hasOwnProperty.call(current, "constructor")) delete current["constructor"];
198
- const items = Array.isArray(current) ? current : Object.values(current);
199
- for (const v of items) if (v && typeof v === "object") {
200
- seen ??= /* @__PURE__ */ new WeakSet();
201
- if (!seen.has(v)) {
202
- seen.add(v);
203
- sanitizeKeys(v, seen);
204
- }
235
+ function _sanitizeCopy(current, seen) {
236
+ seen.add(current);
237
+ if (Array.isArray(current)) return current.map((item) => item && typeof item === "object" && !seen.has(item) ? _sanitizeCopy(item, seen) : item);
238
+ const result = {};
239
+ for (const [key, value] of Object.entries(current)) {
240
+ if (key === "__proto__" || key === "prototype" || key === "constructor") continue;
241
+ result[key] = value && typeof value === "object" && !seen.has(value) ? _sanitizeCopy(value, seen) : value;
205
242
  }
243
+ return result;
206
244
  }
207
245
  //#endregion
208
246
  //#region src/core/utils/index.ts
209
- var utils_exports = /* @__PURE__ */ __exportAll({
210
- applyTypCtyDefaults: () => applyTypCtyDefaults,
211
- assertCryptoKey: () => assertCryptoKey,
212
- base64Decode: () => base64Decode,
213
- base64Encode: () => base64Encode,
214
- base64UrlDecode: () => base64UrlDecode,
215
- base64UrlEncode: () => base64UrlEncode,
216
- computeExpiresInSeconds: () => computeExpiresInSeconds,
217
- computeJwtTimeClaims: () => computeJwtTimeClaims,
218
- computeMaxTokenAgeSeconds: () => computeMaxTokenAgeSeconds,
219
- concatUint8Arrays: () => concatUint8Arrays,
220
- decodeMaybeJWTString: () => decodeMaybeJWTString,
221
- decodePayloadFromB64UrlSegment: () => decodePayloadFromB64UrlSegment,
222
- decodePayloadFromBytes: () => decodePayloadFromBytes,
223
- getPlaintextBytes: () => getPlaintextBytes,
224
- isAsymmetricJWK: () => isAsymmetricJWK,
225
- isCryptoKey: () => isCryptoKey,
226
- isCryptoKeyPair: () => isCryptoKeyPair,
227
- isJWK: () => isJWK,
228
- isJWKSet: () => isJWKSet,
229
- isJWTContent: () => isJWTContent,
230
- isPrivateJWK: () => isPrivateJWK,
231
- isPublicJWK: () => isPublicJWK,
232
- isSymmetricJWK: () => isSymmetricJWK,
233
- maybeArray: () => maybeArray,
234
- randomBytes: () => randomBytes,
235
- sanitizeObject: () => sanitizeObject,
236
- textDecoder: () => textDecoder,
237
- textEncoder: () => textEncoder,
238
- validateCriticalHeadersJWE: () => validateCriticalHeadersJWE,
239
- validateCriticalHeadersJWS: () => validateCriticalHeadersJWS,
240
- validateJwtClaims: () => validateJwtClaims
241
- });
242
247
  const textEncoder = /* @__PURE__ */ new TextEncoder();
243
248
  const textDecoder = /* @__PURE__ */ new TextDecoder();
244
249
  const _Buffer = /* @__PURE__ */ (() => {
@@ -371,4 +376,4 @@ function isPublicJWK(key) {
371
376
  return false;
372
377
  }
373
378
  //#endregion
374
- export { validateCriticalHeadersJWE as A, computeJwtTimeClaims as C, decodePayloadFromBytes as D, decodePayloadFromB64UrlSegment as E, validateJwtClaims as M, getPlaintextBytes as O, computeExpiresInSeconds as S, decodeMaybeJWTString as T, textDecoder as _, base64UrlEncode as a, sanitizeObject as b, isCryptoKey as c, isJWKSet as d, isPrivateJWK as f, randomBytes as g, maybeArray as h, base64UrlDecode as i, validateCriticalHeadersJWS as j, isJWTContent as k, isCryptoKeyPair as l, isSymmetricJWK as m, base64Decode as n, concatUint8Arrays as o, isPublicJWK as p, base64Encode as r, isAsymmetricJWK as s, assertCryptoKey as t, isJWK as u, textEncoder as v, computeMaxTokenAgeSeconds as w, applyTypCtyDefaults as x, utils_exports as y };
379
+ export { validateCriticalHeadersJWS as A, computeMaxTokenAgeSeconds as C, getPlaintextBytes as D, decodePayloadFromBytes as E, JWTError as M, isJWTError as N, isJWTContent as O, computeJwtTimeClaims as S, decodePayloadFromB64UrlSegment as T, textDecoder as _, base64UrlEncode as a, applyTypCtyDefaults as b, isCryptoKey as c, isJWKSet as d, isPrivateJWK as f, randomBytes as g, maybeArray as h, base64UrlDecode as i, validateJwtClaims as j, validateCriticalHeadersJWE as k, isCryptoKeyPair as l, isSymmetricJWK as m, base64Decode as n, concatUint8Arrays as o, isPublicJWK as p, base64Encode as r, isAsymmetricJWK as s, assertCryptoKey as t, isJWK as u, textEncoder as v, decodeMaybeJWTString as w, computeExpiresInSeconds as x, sanitizeObject as y };
@@ -0,0 +1,282 @@
1
+ import { $ as JWK_HMAC, A as GenerateJWKReturn, B as JWKParameters, C as JWTClaims, D as DeriveKeyOptions, E as ContentEncryptionAlgorithm, F as JWKAlgorithm, G as JWK_AES_KW, H as JWK_AES_CBC_HMAC, I as JWKCacheAdapter, J as JWK_EC, K as JWK_Asymmetric, L as JWKLookupFunction, M as GenerateKeyOptions, N as GenerateKeyReturn, O as DeriveKeyReturn, P as JWK, Q as JWK_EC_Public, R as JWKLookupFunctionHeader, S as JWTClaimValidationOptions, T as CompositeKey, U as JWK_AES_GCM, V as JWKSet, W as JWK_AES_GCM_KW, X as JWK_ECDSA, Y as JWK_ECDH_ES, Z as JWK_EC_Private, _ as JWSSignOptions, _t as KeyManagementAlgorithm, a as ExpiresIn, at as JWK_Pair, b as JOSEPayload, bt as WrapKeyResult, c as JWEDecryptResult, ct as JWK_RSA, d as JWEKeyManagementHeaderParameters, dt as JWK_RSA_Private, et as JWK_OKP, f as JWEProtectedHeader, ft as JWK_RSA_Public, g as JWSProtectedHeader, gt as JWK_oct, h as JWSHeaderParameters, ht as JWK_Symmetric_Algorithm, i as importFromPEM, it as JWK_PBES2, j as GenerateKeyAlgorithm, k as GenerateJWKOptions, l as JWEEncryptOptions, lt as JWK_RSA_ENC, m as JWSAlgorithm, mt as JWK_Symmetric, n as exportToPEM, nt as JWK_OKP_Public, o as MaxTokenAge, ot as JWK_Private, p as StrictOmit, pt as JWK_RSA_SIGN, q as JWK_Asymmetric_Algorithm, r as generateJWK, rt as JWK_OKP_SIGN, s as JWEDecryptOptions, st as JWK_Public, t as deriveJWKFromPassword, tt as JWK_OKP_Private, u as JWEHeaderParameters, ut as JWK_RSA_PSS, v as JWSVerifyOptions, vt as UnwrapKeyOptions, w as JoseHeaderParameters, x as JWT, y as JWSVerifyResult, yt as WrapKeyOptions, z as JWKPEMAlgorithm } from "../../_chunks/jwk.mjs";
2
+ import { H3Event } from "h3";
3
+ import { CookieSerializeOptions } from "cookie-es";
4
+
5
+ //#region src/adapters/h3v1/session/types.d.ts
6
+ interface SessionClaims extends Required<Pick<JWTClaims, "jti" | "iat">>, StrictOmit<JWTClaims, "jti" | "iat"> {}
7
+ type SessionData<T extends Record<string, any> = SessionClaims> = StrictOmit<T, "jti" | "iat" | "exp">;
8
+ type SessionUpdate<T extends Record<string, any> = SessionClaims> = Partial<SessionData<T>> | ((oldData: SessionData<T>) => Partial<SessionData<T>> | undefined);
9
+ interface SessionManager<T extends Record<string, any> = SessionClaims, ConfigMaxAge extends ExpiresIn | undefined = ExpiresIn | undefined> {
10
+ readonly id: string | undefined;
11
+ readonly createdAt: number;
12
+ readonly expiresAt: ConfigMaxAge extends ExpiresIn ? number : "exp" extends keyof T ? T["exp"] : number | undefined;
13
+ readonly data: SessionData<T>;
14
+ readonly token: string | undefined;
15
+ update: (update?: SessionUpdate<T>) => Promise<SessionManager<T, ConfigMaxAge> & {
16
+ readonly id: string;
17
+ readonly token: string;
18
+ }>;
19
+ clear: () => Promise<SessionManager<T, ConfigMaxAge> & {
20
+ readonly id: undefined;
21
+ readonly createdAt: number;
22
+ readonly expiresAt: undefined;
23
+ }>;
24
+ }
25
+ //#endregion
26
+ //#region src/adapters/h3v1/session/jwe.d.ts
27
+ declare const kGetSessionPromise$1: unique symbol;
28
+ interface SessionJWE<T extends Record<string, any> = SessionClaims, MaxAge extends ExpiresIn | undefined = ExpiresIn | undefined> {
29
+ id: string | undefined;
30
+ createdAt: number;
31
+ expiresAt: MaxAge extends ExpiresIn ? number : T["exp"];
32
+ data: SessionData<T>;
33
+ token: string | undefined;
34
+ [kGetSessionPromise$1]?: Promise<SessionJWE<T, MaxAge>>;
35
+ }
36
+ interface SessionHooksJWE<T extends Record<string, any> = SessionClaims, MaxAge extends ExpiresIn | undefined = ExpiresIn | undefined, TEvent extends CompatEvent$1 | H3Event = CompatEvent$1 | H3Event> {
37
+ onRead?: (args: {
38
+ session: SessionJWE<T, MaxAge> & {
39
+ id: string;
40
+ token: string;
41
+ };
42
+ event: TEvent;
43
+ config: SessionConfigJWE<T, MaxAge, TEvent>;
44
+ }) => void | Promise<void>;
45
+ onUpdate?: (args: {
46
+ /** Session after it has been updated.. */session: SessionJWE<T, MaxAge> & {
47
+ id: string;
48
+ token: string;
49
+ }; /** Snapshot of the session before was updated. */
50
+ oldSession: SessionJWE<T, MaxAge>;
51
+ event: TEvent;
52
+ config: SessionConfigJWE<T, MaxAge, TEvent>;
53
+ }) => void | Promise<void>;
54
+ onClear?: (args: {
55
+ oldSession: SessionJWE<T, MaxAge> | undefined;
56
+ event: TEvent;
57
+ config: SessionConfigJWE<T, MaxAge, TEvent>;
58
+ }) => void | Promise<void>;
59
+ onExpire?: (args: {
60
+ session: {
61
+ id: string | undefined;
62
+ createdAt: number | undefined;
63
+ expiresAt: number | undefined;
64
+ token: string;
65
+ };
66
+ event: TEvent;
67
+ error: Error;
68
+ config: SessionConfigJWE<T, MaxAge, TEvent>;
69
+ }) => void | Promise<void>;
70
+ onError?: (args: {
71
+ /**
72
+ * The session involved in the error.
73
+ */
74
+ session: SessionJWE<T, MaxAge>;
75
+ event: TEvent;
76
+ error: any;
77
+ config: SessionConfigJWE<T, MaxAge, TEvent>;
78
+ }) => void | Promise<void>;
79
+ onUnsealKeyLookup?: (args: {
80
+ header: JWEHeaderParameters;
81
+ event: TEvent;
82
+ config: SessionConfigJWE<T, MaxAge, TEvent>;
83
+ }) => JWK_Symmetric | JWK_Private | Promise<JWK_Symmetric | JWK_Private>;
84
+ }
85
+ interface SessionConfigJWE<T extends Record<string, any> = SessionClaims, MaxAge extends ExpiresIn | undefined = ExpiresIn | undefined, TEvent extends CompatEvent$1 | H3Event = CompatEvent$1 | H3Event> {
86
+ /** Shared key used, string for PBES2 or Json Web Key (JWK) */
87
+ key: string | JWK_Symmetric | JWK_Private | {
88
+ privateKey: JWK_Private | JWK_Symmetric;
89
+ publicKey?: JWK_Public;
90
+ };
91
+ /** Session lifetime in seconds (used to derive exp from iat) */
92
+ maxAge?: MaxAge;
93
+ /** Default is "h3" */
94
+ name?: string;
95
+ /** Default is secure, httpOnly, path="/" */
96
+ cookie?: false | CookieSerializeOptions;
97
+ /** Default is x-h3-session / x-{name}-session */
98
+ sessionHeader?: false | string;
99
+ /** Default is crypto.randomUUID */
100
+ generateId?: () => string;
101
+ /** JWE configuration overrides */
102
+ jwe?: {
103
+ encryptOptions?: Omit<JWEEncryptOptions, "expiresIn">;
104
+ decryptOptions?: JWTClaimValidationOptions;
105
+ };
106
+ hooks?: SessionHooksJWE<T, MaxAge, TEvent>;
107
+ }
108
+ type CompatEvent$1 = {
109
+ request: {
110
+ headers: Headers;
111
+ };
112
+ context: any;
113
+ } | {
114
+ headers: Headers;
115
+ context: any;
116
+ };
117
+ /**
118
+ * Create a session manager for the current request.
119
+ */
120
+ declare function useJWESession<T extends Record<string, any> = SessionClaims, MaxAge extends ExpiresIn | undefined = ExpiresIn | undefined, TEvent extends CompatEvent$1 | H3Event = CompatEvent$1 | H3Event>(event: TEvent, config: SessionConfigJWE<T, MaxAge, TEvent>): Promise<SessionManager<T, MaxAge>>;
121
+ /**
122
+ * Get (and lazily initialize) the session for the current request.
123
+ */
124
+ declare function getJWESession<T extends Record<string, any> = SessionClaims, MaxAge extends ExpiresIn | undefined = ExpiresIn | undefined, TEvent extends CompatEvent$1 | H3Event = CompatEvent$1 | H3Event>(event: TEvent, config: SessionConfigJWE<T, MaxAge, TEvent>): Promise<SessionJWE<T, MaxAge>>;
125
+ declare function getJWESessionToken<T extends Record<string, any> = SessionClaims, MaxAge extends ExpiresIn | undefined = ExpiresIn | undefined, TEvent extends CompatEvent$1 | H3Event = CompatEvent$1 | H3Event>(event: TEvent, config: SessionConfigJWE<T, MaxAge, TEvent>): string | undefined;
126
+ /**
127
+ * Update the session (optionally mutating the session data) and re-issue the JWE token.
128
+ */
129
+ declare function updateJWESession<T extends Record<string, any> = SessionClaims, MaxAge extends ExpiresIn | undefined = ExpiresIn | undefined, TEvent extends CompatEvent$1 | H3Event = CompatEvent$1 | H3Event>(event: TEvent, config: SessionConfigJWE<T, MaxAge, TEvent>, update?: SessionUpdate<T>): Promise<SessionJWE<T, MaxAge> & {
130
+ id: string;
131
+ token: string;
132
+ }>;
133
+ /**
134
+ * Produce a JWE for the current session.
135
+ * Payload structure:
136
+ * {
137
+ * jti: string;
138
+ * iat: number; (seconds)
139
+ * exp?: number; (seconds)
140
+ * data: Record<string, any>;
141
+ * }
142
+ */
143
+ declare function sealJWESession<T extends Record<string, any> = SessionClaims, MaxAge extends ExpiresIn | undefined = ExpiresIn | undefined, TEvent extends CompatEvent$1 | H3Event = CompatEvent$1 | H3Event>(event: TEvent, config: SessionConfigJWE<T, MaxAge, TEvent>): Promise<string>;
144
+ /**
145
+ * Decrypt the JWE and return a Session-compatible object.
146
+ */
147
+ declare function unsealJWESession<T extends Record<string, any> = SessionClaims, MaxAge extends ExpiresIn | undefined = ExpiresIn | undefined, TEvent extends CompatEvent$1 | H3Event = CompatEvent$1 | H3Event>(event: TEvent, config: SessionConfigJWE<T, MaxAge, TEvent>, sealed: string): Promise<Partial<SessionJWE<T, MaxAge>>>;
148
+ /**
149
+ * Clear the session (delete from context and drop cookie).
150
+ */
151
+ declare function clearJWESession<T extends Record<string, any> = SessionClaims, MaxAge extends ExpiresIn | undefined = ExpiresIn | undefined, TEvent extends CompatEvent$1 | H3Event = CompatEvent$1 | H3Event>(event: TEvent, config: SessionConfigJWE<T, MaxAge, TEvent>): Promise<void>;
152
+ //#endregion
153
+ //#region src/adapters/h3v1/session/jws.d.ts
154
+ declare const kGetSessionPromise: unique symbol;
155
+ interface SessionJWS<T extends Record<string, any> = SessionClaims, MaxAge extends ExpiresIn | undefined = ExpiresIn | undefined> {
156
+ id: string | undefined;
157
+ createdAt: number;
158
+ expiresAt: MaxAge extends ExpiresIn ? number : T["exp"];
159
+ data: SessionData<T>;
160
+ token: string | undefined;
161
+ [kGetSessionPromise]?: Promise<SessionJWS<T, MaxAge>>;
162
+ }
163
+ interface SessionHooksJWS<T extends Record<string, any> = SessionClaims, MaxAge extends ExpiresIn | undefined = ExpiresIn | undefined, TEvent extends CompatEvent | H3Event = CompatEvent | H3Event> {
164
+ onRead?: (args: {
165
+ session: SessionJWS<T, MaxAge> & {
166
+ id: string;
167
+ token: string;
168
+ };
169
+ event: TEvent;
170
+ config: SessionConfigJWS<T, MaxAge, TEvent>;
171
+ }) => void | Promise<void>;
172
+ onUpdate?: (args: {
173
+ /** Session after it has been updated.. */session: SessionJWS<T, MaxAge> & {
174
+ id: string;
175
+ token: string;
176
+ }; /** Snapshot of the session before was updated. */
177
+ oldSession: SessionJWS<T, MaxAge>;
178
+ event: TEvent;
179
+ config: SessionConfigJWS<T, MaxAge, TEvent>;
180
+ }) => void | Promise<void>;
181
+ onClear?: (args: {
182
+ oldSession: SessionJWS<T, MaxAge> | undefined;
183
+ event: TEvent;
184
+ config: SessionConfigJWS<T, MaxAge, TEvent>;
185
+ }) => void | Promise<void>;
186
+ onExpire?: (args: {
187
+ session: {
188
+ id: string | undefined;
189
+ createdAt: number | undefined;
190
+ expiresAt: number | undefined;
191
+ token: string;
192
+ };
193
+ event: TEvent;
194
+ error: Error;
195
+ config: SessionConfigJWS<T, MaxAge, TEvent>;
196
+ }) => void | Promise<void>;
197
+ onError?: (args: {
198
+ /**
199
+ * The session involved in the error.
200
+ */
201
+ session: SessionJWS<T, MaxAge>;
202
+ event: TEvent;
203
+ error: any;
204
+ config: SessionConfigJWS<T, MaxAge, TEvent>;
205
+ }) => void | Promise<void>;
206
+ onVerifyKeyLookup?: (args: {
207
+ header: JWKLookupFunctionHeader;
208
+ event: TEvent;
209
+ config: SessionConfigJWS<T, MaxAge, TEvent>;
210
+ }) => JWKSet | JWK_Symmetric | JWK_Public | Promise<JWKSet | JWK_Symmetric | JWK_Public>;
211
+ }
212
+ interface SessionConfigJWS<T extends Record<string, any> = SessionClaims, MaxAge extends ExpiresIn | undefined = ExpiresIn | undefined, TEvent extends CompatEvent | H3Event = CompatEvent | H3Event> {
213
+ /**
214
+ * JWK (private for signing with RS/ES/PS, or symmetric oct) used for signing.
215
+ */
216
+ key: JWK_Symmetric | {
217
+ privateKey: JWK_Private;
218
+ publicKey: JWK_Public | JWK_Public[] | JWKSet;
219
+ };
220
+ /** Session lifetime in seconds (sets exp = iat + maxAge) */
221
+ maxAge?: MaxAge;
222
+ /** Default cookie / header name base */
223
+ name?: string;
224
+ /** Cookie options (false to disable cookies) */
225
+ cookie?: false | CookieSerializeOptions;
226
+ /** Custom header (false to disable header lookup) */
227
+ sessionHeader?: false | string;
228
+ /** Custom ID generator (defaults to crypto.randomUUID) */
229
+ generateId?: () => string;
230
+ /** JWS customization */
231
+ jws?: {
232
+ signOptions?: Omit<JWSSignOptions, "expiresIn">;
233
+ verifyOptions?: JWTClaimValidationOptions;
234
+ };
235
+ hooks?: SessionHooksJWS<T, MaxAge, TEvent>;
236
+ }
237
+ type CompatEvent = {
238
+ request: {
239
+ headers: Headers;
240
+ };
241
+ context: any;
242
+ } | {
243
+ headers: Headers;
244
+ context: any;
245
+ };
246
+ /**
247
+ * Create a session manager for the current request using JWS (signed only, not encrypted).
248
+ * NOTE: Contents are visible to clients (Base64URL-decoded JSON). Do not store secrets in session data.
249
+ */
250
+ declare function useJWSSession<T extends Record<string, any> = SessionClaims, MaxAge extends ExpiresIn | undefined = ExpiresIn | undefined, TEvent extends CompatEvent | H3Event = CompatEvent | H3Event>(event: TEvent, config: SessionConfigJWS<T, MaxAge, TEvent>): Promise<SessionManager<T, MaxAge>>;
251
+ /**
252
+ * Retrieve (and lazily initialize) the session.
253
+ */
254
+ declare function getJWSSession<T extends Record<string, any> = SessionClaims, MaxAge extends ExpiresIn | undefined = ExpiresIn | undefined, TEvent extends CompatEvent | H3Event = CompatEvent | H3Event>(event: TEvent, config: SessionConfigJWS<T, MaxAge, TEvent>): Promise<SessionJWS<T, MaxAge>>;
255
+ /**
256
+ * Update session data (if provided) and reissue JWS.
257
+ */
258
+ declare function updateJWSSession<T extends Record<string, any> = SessionClaims, MaxAge extends ExpiresIn | undefined = ExpiresIn | undefined, TEvent extends CompatEvent | H3Event = CompatEvent | H3Event>(event: TEvent, config: SessionConfigJWS<T, MaxAge, TEvent>, update?: SessionUpdate<T>): Promise<SessionJWS<T, MaxAge> & {
259
+ id: string;
260
+ token: string;
261
+ }>;
262
+ /**
263
+ * Sign current session as a compact JWS.
264
+ * Payload claims:
265
+ * jti, iat, exp?, data, plus optional extraClaims (cannot override reserved)
266
+ */
267
+ declare function signJWSSession<T extends Record<string, any> = SessionClaims, MaxAge extends ExpiresIn | undefined = ExpiresIn | undefined, TEvent extends CompatEvent | H3Event = CompatEvent | H3Event>(event: TEvent, config: SessionConfigJWS<T, MaxAge, TEvent>): Promise<string>;
268
+ /**
269
+ * Verify and parse a compact JWS into a Session structure.
270
+ * Performs:
271
+ * - cryptographic signature verification
272
+ * - (optional) standard claim checks if validateJWT true
273
+ * - ensures jti & iat presence
274
+ * - enforces maxAge if provided
275
+ */
276
+ declare function verifyJWSSession<T extends Record<string, any> = SessionClaims, MaxAge extends ExpiresIn | undefined = ExpiresIn | undefined, TEvent extends CompatEvent | H3Event = CompatEvent | H3Event>(event: TEvent, config: SessionConfigJWS<T, MaxAge, TEvent>, token: string): Promise<Partial<SessionJWS<T, MaxAge>>>;
277
+ /**
278
+ * Destroy the session (context + cookie).
279
+ */
280
+ declare function clearJWSSession<T extends Record<string, any> = SessionClaims, MaxAge extends ExpiresIn | undefined = ExpiresIn | undefined, TEvent extends CompatEvent | H3Event = CompatEvent | H3Event>(event: TEvent, config: SessionConfigJWS<T, MaxAge, TEvent>): Promise<void>;
281
+ //#endregion
282
+ export { CompositeKey, ContentEncryptionAlgorithm, DeriveKeyOptions, DeriveKeyReturn, ExpiresIn, GenerateJWKOptions, GenerateJWKReturn, GenerateKeyAlgorithm, GenerateKeyOptions, GenerateKeyReturn, JOSEPayload, JWEDecryptOptions, JWEDecryptResult, JWEEncryptOptions, JWEHeaderParameters, JWEKeyManagementHeaderParameters, 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, JWSHeaderParameters, JWSProtectedHeader, JWSSignOptions, JWSVerifyOptions, JWSVerifyResult, JWT, JWTClaimValidationOptions, JWTClaims, JoseHeaderParameters, KeyManagementAlgorithm, MaxTokenAge, type SessionClaims, type SessionConfigJWE, type SessionConfigJWS, type SessionData, type SessionHooksJWE, type SessionHooksJWS, type SessionJWE, type SessionJWS, type SessionManager, type SessionUpdate, UnwrapKeyOptions, WrapKeyOptions, WrapKeyResult, clearJWESession, clearJWSSession, deriveJWKFromPassword, exportToPEM, generateJWK, getJWESession, getJWESessionToken, getJWSSession, importFromPEM, sealJWESession, signJWSSession, unsealJWESession, updateJWESession, updateJWSSession, useJWESession, useJWSSession, verifyJWSSession };