unjwt 0.8.5 → 0.9.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.
Files changed (44) hide show
  1. package/README.md +34 -21
  2. package/dist/_chunks/algorithms.mjs +44 -20
  3. package/dist/_chunks/digest.d.mts +4 -4
  4. package/dist/_chunks/digest.mjs +23 -15
  5. package/dist/_chunks/error.d.mts +29 -42
  6. package/dist/_chunks/export.mjs +1 -4
  7. package/dist/_chunks/index.d.mts +270 -234
  8. package/dist/_chunks/index2.d.mts +82 -189
  9. package/dist/_chunks/index4.d.mts +223 -60
  10. package/dist/_chunks/index5.d.mts +68 -31
  11. package/dist/_chunks/index6.d.mts +45 -64
  12. package/dist/_chunks/jwe.mjs +53 -48
  13. package/dist/_chunks/jwk.mjs +9 -3
  14. package/dist/_chunks/jws.mjs +55 -50
  15. package/dist/_chunks/jwt.d.mts +13 -49
  16. package/dist/_chunks/jwt.mjs +4 -158
  17. package/dist/_chunks/jwt2.mjs +162 -0
  18. package/dist/_chunks/libs/unsecure.d.mts +0 -6
  19. package/dist/_chunks/limits.d.mts +3 -2
  20. package/dist/_chunks/payload.mjs +13 -7
  21. package/dist/_chunks/wrap.mjs +3 -1
  22. package/dist/core/internal.d.mts +50 -2
  23. package/dist/core/internal.mjs +3 -1
  24. package/dist/core/jwe/index.d.mts +1 -1
  25. package/dist/core/jwk/index.d.mts +2 -2
  26. package/dist/core/jwk/index.mjs +2 -2
  27. package/dist/dpop/index.d.mts +77 -18
  28. package/dist/index.d.mts +6 -6
  29. package/dist/index.mjs +4 -4
  30. package/dist/session/index.d.mts +568 -22
  31. package/dist/session/index.mjs +1386 -34
  32. package/dist/utils/index.d.mts +4 -4
  33. package/dist/utils/index.mjs +2 -10
  34. package/package.json +4 -32
  35. package/dist/_chunks/codec-jwe.d.mts +0 -280
  36. package/dist/_chunks/codec-jws.mjs +0 -1005
  37. package/dist/_chunks/cookie-attributes.d.mts +0 -12
  38. package/dist/_chunks/cookie.mjs +0 -50
  39. package/dist/adapters/elysia/index.d.mts +0 -123
  40. package/dist/adapters/elysia/index.mjs +0 -120
  41. package/dist/adapters/h3/index.d.mts +0 -135
  42. package/dist/adapters/h3/index.mjs +0 -117
  43. package/dist/adapters/h3v1/index.d.mts +0 -148
  44. package/dist/adapters/h3v1/index.mjs +0 -128
@@ -1,7 +1,7 @@
1
- import { BytesSource, UnsecureError, UnsecureErrorCode, safeJsonParse, sanitizeObject, sanitizeObjectCopy, secureRandomBytes, textDecoder, textEncoder } from "../_chunks/libs/unsecure.mjs";
1
+ import { UnsecureError, UnsecureErrorCode, safeJsonParse, sanitizeObject, sanitizeObjectCopy, secureRandomBytes, textDecoder, textEncoder } from "../_chunks/libs/unsecure.mjs";
2
2
  import { isUnsecureError } from "../_chunks/error.mjs";
3
3
  import { StrictOmit } from "../_chunks/index.mjs";
4
- import { DigestHash, digestUrl } from "../_chunks/digest.mjs";
5
4
  import { computeDurationInSeconds, isJWTContent, validateJwtClaims } from "../_chunks/jwt.mjs";
6
- import { Base64ParseOptions, ComputeJwtTimeClaimsOptions, DecodeOptions, DecodePayloadOptions, DecodeReturnAs, InferAlgorithmsOptions, applyTypCtyDefaults, assertCritShape, assertCryptoKey, base64Decode, base64Encode, base64Parse, base64Stringify, base64UrlDecode, base64UrlEncode, base64UrlParse, base64UrlStringify, computeJwtTimeClaims, concatUint8Arrays, decodePayloadFromB64UrlSegment, decodePayloadFromBytes, getPlaintextBytes, inferJWEAllowedAlgorithms, inferJWSAllowedAlgorithms, isAsymmetricJWK, isCryptoKey, isCryptoKeyPair, isJWK, isJWKSet, isPrivateJWK, isPublicJWK, isSymmetricJWK, maybeArray, validateCriticalHeadersJWE, validateCriticalHeadersJWS } from "../_chunks/index6.mjs";
7
- export { type Base64ParseOptions, type BytesSource, ComputeJwtTimeClaimsOptions, DecodeOptions, DecodePayloadOptions, type DecodeReturnAs, type DigestHash, type InferAlgorithmsOptions, type StrictOmit, UnsecureError, type UnsecureErrorCode, applyTypCtyDefaults, assertCritShape, assertCryptoKey, base64Decode, base64Encode, base64Parse, base64Stringify, base64UrlDecode, base64UrlEncode, base64UrlParse, base64UrlStringify, computeDurationInSeconds, computeJwtTimeClaims, concatUint8Arrays, decodePayloadFromB64UrlSegment, decodePayloadFromBytes, digestUrl, getPlaintextBytes, inferJWEAllowedAlgorithms, inferJWSAllowedAlgorithms, isAsymmetricJWK, isCryptoKey, isCryptoKeyPair, isJWK, isJWKSet, isJWTContent, isPrivateJWK, isPublicJWK, isSymmetricJWK, isUnsecureError, maybeArray, safeJsonParse, sanitizeObject, sanitizeObjectCopy, secureRandomBytes, textDecoder, textEncoder, validateCriticalHeadersJWE, validateCriticalHeadersJWS, validateJwtClaims };
5
+ import { DigestHash, digestUrl } from "../_chunks/digest.mjs";
6
+ import { Base64ParseOptions, DecodeReturnAs, assertCryptoKey, base64Parse, base64Stringify, base64UrlParse, base64UrlStringify, concatUint8Arrays, inferJWEAllowedAlgorithms, inferJWSAllowedAlgorithms, isAsymmetricJWK, isCryptoKey, isCryptoKeyPair, isJWK, isJWKSet, isPrivateJWK, isPublicJWK, isSymmetricJWK, maybeArray } from "../_chunks/index6.mjs";
7
+ export { type Base64ParseOptions, type DecodeReturnAs, type DigestHash, type StrictOmit, UnsecureError, type UnsecureErrorCode, assertCryptoKey, base64Parse, base64Stringify, base64UrlParse, base64UrlStringify, computeDurationInSeconds, concatUint8Arrays, digestUrl, inferJWEAllowedAlgorithms, inferJWSAllowedAlgorithms, isAsymmetricJWK, isCryptoKey, isCryptoKeyPair, isJWK, isJWKSet, isJWTContent, isPrivateJWK, isPublicJWK, isSymmetricJWK, isUnsecureError, maybeArray, safeJsonParse, sanitizeObject, sanitizeObjectCopy, secureRandomBytes, textDecoder, textEncoder, validateJwtClaims };
@@ -1,13 +1,5 @@
1
1
  import { UnsecureError, safeJsonParse, sanitizeObject, sanitizeObjectCopy, secureRandomBytes, textDecoder, textEncoder } from "../_chunks/libs/unsecure.mjs";
2
2
  import { isUnsecureError } from "../error.mjs";
3
- import { applyTypDefault, assertCritShape as assertCritShape$1, assertCryptoKey, base64Decode, base64Encode, base64Parse, base64Stringify, base64UrlDecode, base64UrlEncode, base64UrlParse, base64UrlStringify, computeDurationInSeconds, computeJwtTimeClaims as computeJwtTimeClaims$1, concatUint8Arrays, getPlaintextBytes as getPlaintextBytes$1, isAsymmetricJWK, isCryptoKey, isCryptoKeyPair, isJWK, isJWKSet, isJWTContent, isPrivateJWK, isPublicJWK, isSymmetricJWK, maybeArray, parsePayloadBytes, parsePayloadSegment, validateCriticalHeadersJWE as validateCriticalHeadersJWE$1, validateCriticalHeadersJWS as validateCriticalHeadersJWS$1, validateJwtClaims } from "../_chunks/jwt.mjs";
3
+ import { assertCryptoKey, base64Parse, base64Stringify, base64UrlParse, base64UrlStringify, computeDurationInSeconds, concatUint8Arrays, isAsymmetricJWK, isCryptoKey, isCryptoKeyPair, isJWK, isJWKSet, isJWTContent, isPrivateJWK, isPublicJWK, isSymmetricJWK, maybeArray, validateJwtClaims } from "../_chunks/jwt.mjs";
4
4
  import { digestUrl, inferJWEAllowedAlgorithms, inferJWSAllowedAlgorithms } from "../_chunks/digest.mjs";
5
- const applyTypCtyDefaults = applyTypDefault;
6
- const decodePayloadFromBytes = parsePayloadBytes;
7
- const decodePayloadFromB64UrlSegment = parsePayloadSegment;
8
- const getPlaintextBytes = getPlaintextBytes$1;
9
- const computeJwtTimeClaims = computeJwtTimeClaims$1;
10
- const validateCriticalHeadersJWS = validateCriticalHeadersJWS$1;
11
- const validateCriticalHeadersJWE = validateCriticalHeadersJWE$1;
12
- const assertCritShape = assertCritShape$1;
13
- export { UnsecureError, applyTypCtyDefaults, assertCritShape, assertCryptoKey, base64Decode, base64Encode, base64Parse, base64Stringify, base64UrlDecode, base64UrlEncode, base64UrlParse, base64UrlStringify, computeDurationInSeconds, computeJwtTimeClaims, concatUint8Arrays, decodePayloadFromB64UrlSegment, decodePayloadFromBytes, digestUrl, getPlaintextBytes, inferJWEAllowedAlgorithms, inferJWSAllowedAlgorithms, isAsymmetricJWK, isCryptoKey, isCryptoKeyPair, isJWK, isJWKSet, isJWTContent, isPrivateJWK, isPublicJWK, isSymmetricJWK, isUnsecureError, maybeArray, safeJsonParse, sanitizeObject, sanitizeObjectCopy, secureRandomBytes, textDecoder, textEncoder, validateCriticalHeadersJWE, validateCriticalHeadersJWS, validateJwtClaims };
5
+ export { UnsecureError, assertCryptoKey, base64Parse, base64Stringify, base64UrlParse, base64UrlStringify, computeDurationInSeconds, concatUint8Arrays, digestUrl, inferJWEAllowedAlgorithms, inferJWSAllowedAlgorithms, isAsymmetricJWK, isCryptoKey, isCryptoKeyPair, isJWK, isJWKSet, isJWTContent, isPrivateJWK, isPublicJWK, isSymmetricJWK, isUnsecureError, maybeArray, safeJsonParse, sanitizeObject, sanitizeObjectCopy, secureRandomBytes, textDecoder, textEncoder, validateJwtClaims };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "unjwt",
3
- "version": "0.8.5",
3
+ "version": "0.9.1",
4
4
  "description": "A collection of JWT utilities based on the Web Crypto API.",
5
5
  "keywords": [
6
6
  "auth",
@@ -80,22 +80,6 @@
80
80
  "./internal": {
81
81
  "types": "./dist/core/internal.d.mts",
82
82
  "default": "./dist/core/internal.mjs"
83
- },
84
- "./adapters/h3": {
85
- "types": "./dist/adapters/h3/index.d.mts",
86
- "default": "./dist/adapters/h3/index.mjs"
87
- },
88
- "./adapters/h3v1": {
89
- "types": "./dist/adapters/h3v1/index.d.mts",
90
- "default": "./dist/adapters/h3v1/index.mjs"
91
- },
92
- "./adapters/h3v2": {
93
- "types": "./dist/adapters/h3/index.d.mts",
94
- "default": "./dist/adapters/h3/index.mjs"
95
- },
96
- "./adapters/elysia": {
97
- "types": "./dist/adapters/elysia/index.d.mts",
98
- "default": "./dist/adapters/elysia/index.mjs"
99
83
  }
100
84
  },
101
85
  "devDependencies": {
@@ -104,9 +88,8 @@
104
88
  "@vitest/coverage-v8": "^5.0.4",
105
89
  "automd": "^0.4.3",
106
90
  "cookie-es": "^3.1.1",
107
- "elysia": "^1.4.30",
108
91
  "h3": "^2.0.5",
109
- "h3v1": "npm:h3@^1.15.11",
92
+ "hono": "^4.13.13",
110
93
  "jose": "^6.2.12",
111
94
  "obuild": "^0.4.45",
112
95
  "oxfmt": "^0.73.0",
@@ -119,18 +102,6 @@
119
102
  "unsecure": "^0.3.4",
120
103
  "vitest": "^5.0.4"
121
104
  },
122
- "peerDependencies": {
123
- "elysia": "^1.4.29",
124
- "h3": "^1.15.4 || ^2.0.1"
125
- },
126
- "peerDependenciesMeta": {
127
- "elysia": {
128
- "optional": true
129
- },
130
- "h3": {
131
- "optional": true
132
- }
133
- },
134
105
  "simple-git-hooks": {
135
106
  "pre-commit": "pnpm build --stub && pnpm lint && pnpm typecheck"
136
107
  },
@@ -149,6 +120,7 @@
149
120
  "scripts": {
150
121
  "build": "obuild",
151
122
  "dev": "pnpm --dir playgrounds/h3 dev",
123
+ "docs": "pnpm --filter unjwt-docs dev",
152
124
  "dev:nuxt": "pnpm --dir playgrounds/nuxt-4 dev",
153
125
  "dev:nitro": "pnpm --dir playgrounds/nitro dev",
154
126
  "dev:prepare": "obuild --stub && pnpm --dir playgrounds/nuxt-4 prepare && pnpm simple-git-hooks",
@@ -157,7 +129,7 @@
157
129
  "fmt": "automd && oxlint --fix . && oxfmt .",
158
130
  "test": "vitest run --slowTestThreshold=1000",
159
131
  "test:coverage": "vitest run --coverage --slowTestThreshold=1000",
160
- "typecheck": "tsc --noEmit",
132
+ "typecheck": "tsc --noEmit && tsc --noEmit -p examples && tsc --noEmit -p test/examples",
161
133
  "bench": "vitest bench --run"
162
134
  }
163
135
  }
@@ -1,280 +0,0 @@
1
- import "./error.mjs";
2
- import { ExpiresIn, JWEAsymmetricPrivateJWK, JWEAsymmetricPublicJWK, JWEDecryptJWK, JWEDecryptOptions, JWEEncryptJWK, JWEEncryptOptions, JWEHeaderParameters, JWKSet, JWK_HMAC, JWK_oct, JWSAsymmetricPrivateJWK, JWSAsymmetricPublicJWK, JWSHeaderParameters, JWSSignOptions, JWSVerifyJWK, JWSVerifyOptions, JWTClaims, StrictOmit } from "./index.mjs";
3
- interface ExpirableCookieAttributes {
4
- expires?: Date;
5
- maxAge?: number;
6
- }
7
- /** Session data shape; `any` values let an `interface` (no index signature) satisfy it. */
8
- export type SessionRecord = Record<string, any>;
9
- export interface SessionClaims extends Required<Pick<JWTClaims, "jti" | "iat">>, StrictOmit<JWTClaims, "jti" | "iat"> {}
10
- /** Session data without the adapter-owned `jti`, `iat`, `exp` and `nbf`. */
11
- export type SessionData<T extends SessionRecord = SessionClaims> = StrictOmit<T, "jti" | "iat" | "exp" | "nbf">;
12
- /** Why `onUpdate` fired: an `update()` call, or `rolling` reissuing a session that was read. */
13
- export type SessionUpdateTrigger = "update" | "rolling";
14
- export type SessionUpdate<T extends SessionRecord = SessionClaims> = Partial<SessionData<T>> | ((oldData: SessionData<T>) => Partial<SessionData<T>> | undefined);
15
- export interface SessionManager<T extends SessionRecord = SessionClaims, ConfigMaxAge extends ExpiresIn | undefined = ExpiresIn | undefined> {
16
- readonly id: string | undefined;
17
- readonly createdAt: number;
18
- /** Expiry in ms: `exp`, or `iat + maxAge` when sooner; always a number when the session has a `maxAge`. */
19
- readonly expiresAt: ConfigMaxAge extends ExpiresIn ? number : number | undefined;
20
- readonly data: SessionData<T>;
21
- readonly token: string | undefined;
22
- /**
23
- * Issues a new token after merging `update`; `options.maxAge` overrides this token's lifetime.
24
- * Later reads see the data's JSON round trip. Rolls back if issuing or the cookie write fails;
25
- * a throwing `onUpdate` rejects but keeps the new session.
26
- */
27
- update: (update?: SessionUpdate<T>, options?: SessionIssueOptions) => Promise<SessionManager<T, ConfigMaxAge>>;
28
- clear: () => Promise<SessionManager<T, ConfigMaxAge>>;
29
- }
30
- /** The config members every session shares, whether it signs or seals its token. */
31
- interface SessionBaseConfig<MaxAge extends ExpiresIn | undefined = ExpiresIn | undefined> {
32
- /** Sets `exp = iat + maxAge`, requires `exp` on incoming tokens and ends them at `iat + maxAge` at the latest, drives cookie expiry; unset never expires. */
33
- maxAge?: MaxAge;
34
- /**
35
- * Reissue the session when it is read, needs `maxAge`.
36
- *
37
- * - `true`: every read reissues.
38
- * - a duration: a read reissues once the token is at least that old, so an active session is
39
- * re-signed at most once per duration. With `maxAge: "1h"` and `rolling: "15m"`, reads in the
40
- * first 15 minutes change nothing; the first read after that issues a fresh hour. Must be
41
- * shorter than `maxAge`.
42
- *
43
- * A read that cannot write (a read-only event, a response already sent) does not reissue;
44
- * the next request, carrying the same token, does.
45
- *
46
- * @default undefined — the session expires at `iat + maxAge` however often it is read.
47
- */
48
- rolling?: true | ExpiresIn;
49
- /** Drives the cookie name and default header; prefer `__Host-`; a trailing `.<digits>` is refused. */
50
- name?: string;
51
- /**
52
- * Header carrying a bare or `Bearer` token: a header name, `true` for `x-<name>-session` (cookie prefix stripped), or `false` for none.
53
- * A request that carries it is read from it and never from the cookie, and writes no cookie back; any other value is a token failure (`onError`).
54
- * Left unset, a session with cookies still reads `x-<name>-session`, and so does one with `cookie: false`.
55
- */
56
- sessionHeader?: boolean | string;
57
- /** Session ID (`jti`) generator. Default `crypto.randomUUID`. */
58
- generateId?: () => string;
59
- }
60
- /**
61
- * Lifecycle hooks; `onRead`, `onExpire` and `onError` are mutually exclusive per incoming token.
62
- * `session` is the live manager, so a hook can `update()` or `clear()` in place; `oldSession` is a snapshot.
63
- */
64
- interface SessionHooks<TSession, TManager, TArgs extends Record<string, unknown>, TConfig> {
65
- /** Fires once per request, when the session is read from its token. */
66
- onRead?: (args: TArgs & {
67
- session: TManager & {
68
- id: string;
69
- token: string;
70
- };
71
- config: TConfig;
72
- }) => void | Promise<void>;
73
- /** Fires after a token is issued and, on a cookie session, its cookie written, by `update()` or by `rolling`; a throw rejects without rollback. */
74
- onUpdate?: (args: TArgs & {
75
- session: TManager & {
76
- id: string;
77
- token: string;
78
- };
79
- /** Deep-copied snapshot of the session before the update. */
80
- oldSession: TSession;
81
- trigger: SessionUpdateTrigger;
82
- config: TConfig;
83
- }) => void | Promise<void>;
84
- /** Fires when the session is cleared. */
85
- onClear?: (args: TArgs & {
86
- oldSession: TSession | undefined;
87
- config: TConfig;
88
- }) => void | Promise<void>;
89
- /** Fires when the incoming token is expired. Receives the expired token's decoded claims. */
90
- onExpire?: (args: TArgs & {
91
- session: {
92
- id: string | undefined;
93
- createdAt: number | undefined;
94
- expiresAt: number | undefined;
95
- token: string;
96
- };
97
- error: Error;
98
- config: TConfig;
99
- }) => void | Promise<void>;
100
- /** Fires on read-path failures other than expiry, and on write-path issue failures. */
101
- onError?: (args: TArgs & {
102
- session: TManager;
103
- error: any;
104
- config: TConfig;
105
- }) => void | Promise<void>;
106
- }
107
- /** Per-issue overrides for a single `update()` call. */
108
- export interface SessionIssueOptions {
109
- /** Lifetime for this issue only, overriding the config's `maxAge`; a read under that `maxAge` still ends the session at `iat + maxAge`. */
110
- maxAge?: ExpiresIn;
111
- }
112
- /** In-request session state, mirroring the claims of the underlying token. */
113
- export interface SessionState<T extends SessionRecord, MaxAge extends ExpiresIn | undefined> {
114
- /** JWT `jti`; `undefined` until the session is persisted. */
115
- id: string | undefined;
116
- /** In ms; mirrors the JWT `iat` claim (seconds). */
117
- createdAt: number;
118
- /** In ms; mirrors the JWT `exp` claim (seconds), or `iat + maxAge` when sooner. */
119
- expiresAt: MaxAge extends ExpiresIn ? number : number | undefined;
120
- data: SessionData<T>;
121
- token: string | undefined;
122
- }
123
- /** Session state read back from a token: always carries its `id` and `createdAt`. */
124
- export type OpenedSessionState<T extends SessionRecord, MaxAge extends ExpiresIn | undefined> = Pick<SessionState<T, MaxAge>, "id" | "createdAt" | "expiresAt" | "data"> & {
125
- id: string;
126
- createdAt: number;
127
- };
128
- /** One session, defined once from its config and used on any request. */
129
- export interface SessionDefinition<T extends SessionRecord = SessionClaims, MaxAge extends ExpiresIn | undefined = ExpiresIn | undefined, TEvent = unknown> {
130
- /** Reads the request's session once and returns its manager; later calls on the same request share that state. */
131
- use: (event: TEvent) => Promise<SessionManager<T, MaxAge>>;
132
- /** The session's token once `use()` read or wrote it, else the one the request carries (the session header before the cookie), unopened. */
133
- token: (event: TEvent) => string | undefined;
134
- /** Mints a token for `data` with a fresh `jti` and `iat`, and `exp` from `maxAge` (`options.maxAge` overrides it); reads and writes nothing. */
135
- issue: (data?: Partial<SessionData<T>>, options?: SessionIssueOptions) => Promise<string>;
136
- /** Opens a token into session state, checking `typ`, pinned algorithms, `jti`/`iat` and `exp` when `maxAge` is set; the key-lookup hook receives no request. */
137
- open: (token: string) => Promise<OpenedSessionState<T, MaxAge>>;
138
- }
139
- interface SessionRequestBase {
140
- /**
141
- * The response being prepared; without it the session is read-only.
142
- * With `errHeaders` too (h3 v2, which sends only those for a thrown handler), every cookie write lands in both.
143
- */
144
- readonly res?: {
145
- readonly headers: Headers;
146
- readonly errHeaders?: Headers;
147
- };
148
- /** Per-request state shared with the framework, where `sessions` is kept; without it state is keyed on `req`, else on this object. */
149
- readonly context?: Record<string, unknown>;
150
- }
151
- /** A request event: by its `Request`, or by its `Headers` (a `Request` itself, a WebSocket upgrade's request). */
152
- export type SessionRequestEvent = SessionRequestBase & ({
153
- readonly req: Request;
154
- readonly headers?: Headers;
155
- } | {
156
- readonly headers: Headers;
157
- readonly req?: Request;
158
- });
159
- /** A token handed in directly; sending a re-issued one is the caller's job. */
160
- export interface SessionHandedToken {
161
- token: string | undefined;
162
- }
163
- /** What the Web session driver takes: a request event, or a token in hand. */
164
- export type WebSessionEvent = SessionRequestEvent | SessionHandedToken;
165
- /** The cookies of one request and its response, as a framework exposes them. */
166
- export interface CookieJar<A extends ExpirableCookieAttributes = ExpirableCookieAttributes> {
167
- /** The request's cookie. */
168
- read(name: string): string | undefined;
169
- /** The value this response already assigned to `name` (`""` once deleted), when the framework exposes it. */
170
- written?(name: string): string | undefined;
171
- /** Absent when this event cannot take a `Set-Cookie` (a request without a response). */
172
- write?(name: string, value: string, attrs: A): void;
173
- }
174
- /** The primitives a framework supplies; the session core builds the cookie and header transports over them. */
175
- export interface SessionDriver<TEvent> {
176
- /** Message prefix for every error the adapter emits. */
177
- prefix: string;
178
- /** The per-request record session state and the session-name registry live in. */
179
- state(event: TEvent): Record<string, unknown>;
180
- header(event: TEvent, name: string): string | null | undefined;
181
- cookies(event: TEvent): CookieJar;
182
- /** Platform signal that the response can still change (Node `headersSent`); absent = trust the jar. */
183
- writable?(event: TEvent): boolean;
184
- /** A token the event carries directly, when it does: no cookie or header is consulted. */
185
- handed?(event: TEvent): {
186
- token: string | undefined;
187
- } | undefined;
188
- }
189
- /** HS* `oct` JWK, `CryptoKey` (requires pinned `alg`), or a pair: private signs, public JWK/list/set verifies. */
190
- type JWSSessionKey = CryptoKey | JWK_oct<JWK_HMAC> | {
191
- privateKey: JWSAsymmetricPrivateJWK | CryptoKey;
192
- publicKey: JWSAsymmetricPublicJWK | JWSAsymmetricPublicJWK[] | JWKSet | CryptoKey;
193
- };
194
- /** JWS verify overrides, minus the options the adapter owns. */
195
- export type SessionVerifyOptions = StrictOmit<JWSVerifyOptions, "algorithms" | "typ" | "maxTokenAge" | "validateClaims" | "forceUint8Array" | "payload">;
196
- /** JWS sign options, minus those setting `exp`/`nbf` (the adapter mints `exp` from `maxAge`). */
197
- export type SessionSignOptions = StrictOmit<JWSSignOptions, "expiresIn" | "expiresAt" | "notBeforeIn" | "notBeforeAt">;
198
- /** JWS sign/verify overrides a session accepts. */
199
- interface JWSSessionOptions {
200
- signOptions?: SessionSignOptions;
201
- verifyOptions?: SessionVerifyOptions;
202
- }
203
- /** The config of a JWS-backed (signed, not encrypted) session, minus its hooks. */
204
- export interface JWSSessionConfig<MaxAge extends ExpiresIn | undefined = ExpiresIn | undefined, TCookie extends object = object> extends SessionBaseConfig<MaxAge> {
205
- /** Key used for signing — see {@link JWSSessionKey}. */
206
- key: JWSSessionKey;
207
- /** `false` to disable. Defaults: `path="/"`, `secure`, `sameSite: "lax"`, `httpOnly: false` (payload is client-readable). */
208
- cookie?: false | (TCookie & {
209
- chunkMaxLength?: number;
210
- });
211
- /** Pinned `signOptions.alg` restricts verification; `protectedHeader.typ` defaults to `"session+jwt"` (RFC 8725 §3.11). */
212
- jws?: JWSSessionOptions;
213
- }
214
- /** JWS session hooks, plus the verify key lookup. */
215
- export interface JWSSessionHooks<TSession, TManager, TArgs extends Record<string, unknown>, TConfig> extends SessionHooks<TSession, TManager, TArgs, TConfig> {
216
- /** Resolve the verification key(s) for the incoming token from its protected header (e.g. by `kid`). */
217
- onVerifyKeyLookup?: (args: Partial<TArgs> & {
218
- header: JWSHeaderParameters;
219
- config: TConfig;
220
- }) => JWKSet | JWSVerifyJWK | Promise<JWKSet | JWSVerifyJWK>;
221
- }
222
- /**
223
- * A symmetric `oct` JWK, or a `CryptoKey` (requires pinned `alg` and `enc`): the one key seals and unseals.
224
- *
225
- * The `{ privateKey, publicKey? }` pair members are deprecated: a pair seals with its public half,
226
- * so anyone holding the public key can mint a session the server accepts. Use an `oct` JWK, or
227
- * `defineJWSSession` for a key pair.
228
- */
229
- type JWESessionKey = CryptoKey | JWEEncryptJWK | {
230
- /**
231
- * Unseals; a private JWK alone seals with its own public half.
232
- * @deprecated A pair seals with its public half, so anyone holding the public key can mint a session the server accepts. Use an `oct` JWK, or `defineJWSSession` for a key pair.
233
- */
234
- privateKey: JWEAsymmetricPrivateJWK;
235
- /**
236
- * Seals.
237
- * @deprecated A pair seals with its public half, so anyone holding the public key can mint a session the server accepts. Use an `oct` JWK, or `defineJWSSession` for a key pair.
238
- */
239
- publicKey?: JWEAsymmetricPublicJWK | CryptoKey;
240
- } | {
241
- /**
242
- * Unseals; a private `CryptoKey` has no public half to derive, so it comes with one.
243
- * @deprecated A pair seals with its public half, so anyone holding the public key can mint a session the server accepts. Use an `oct` JWK, or `defineJWSSession` for a key pair.
244
- */
245
- privateKey: CryptoKey;
246
- /**
247
- * Seals.
248
- * @deprecated A pair seals with its public half, so anyone holding the public key can mint a session the server accepts. Use an `oct` JWK, or `defineJWSSession` for a key pair.
249
- */
250
- publicKey: JWEAsymmetricPublicJWK | CryptoKey;
251
- };
252
- /** JWE decrypt overrides, minus the options the adapter owns. */
253
- export type SessionDecryptOptions = StrictOmit<JWEDecryptOptions, "algorithms" | "encryptionAlgorithms" | "typ" | "maxTokenAge" | "validateClaims" | "forceUint8Array" | "payload">;
254
- /** JWE encrypt options, minus those setting `exp`/`nbf` (the adapter mints `exp` from `maxAge`). */
255
- export type SessionEncryptOptions = StrictOmit<JWEEncryptOptions, "expiresIn" | "expiresAt" | "notBeforeIn" | "notBeforeAt">;
256
- /** JWE encrypt/decrypt overrides a session accepts. */
257
- interface JWESessionOptions {
258
- encryptOptions?: SessionEncryptOptions;
259
- decryptOptions?: SessionDecryptOptions;
260
- }
261
- /** The config of a JWE-backed (encrypted) session, minus its hooks. */
262
- export interface JWESessionConfig<MaxAge extends ExpiresIn | undefined = ExpiresIn | undefined, TCookie extends object = object> extends SessionBaseConfig<MaxAge> {
263
- /** Key used for sealing — see {@link JWESessionKey}. */
264
- key: JWESessionKey;
265
- /** `false` to disable. Defaults: `path="/"`, `secure`, `sameSite: "lax"`, `httpOnly: true`. */
266
- cookie?: false | (TCookie & {
267
- chunkMaxLength?: number;
268
- });
269
- /** Pinned `encryptOptions.alg`/`enc` restrict unsealing; `protectedHeader.typ` defaults to `"session+jwt"` (RFC 8725 §3.11). */
270
- jwe?: JWESessionOptions;
271
- }
272
- /** JWE session hooks, plus the unseal key lookup. */
273
- export interface JWESessionHooks<TSession, TManager, TArgs extends Record<string, unknown>, TConfig> extends SessionHooks<TSession, TManager, TArgs, TConfig> {
274
- /** Resolve the decryption key for the incoming token from its protected header (e.g. by `kid`). */
275
- onUnsealKeyLookup?: (args: Partial<TArgs> & {
276
- header: JWEHeaderParameters;
277
- config: TConfig;
278
- }) => JWEDecryptJWK | Promise<JWEDecryptJWK>;
279
- }
280
- export {};