unjwt 0.8.2 → 0.8.3

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.
@@ -39,7 +39,7 @@ interface SessionBaseConfig<MaxAge extends ExpiresIn | undefined = ExpiresIn | u
39
39
  * first 15 minutes change nothing; the first read after that issues a fresh hour. Must be
40
40
  * shorter than `maxAge`.
41
41
  *
42
- * A read that cannot write (a read-only context, a response already sent) does not reissue;
42
+ * A read that cannot write (a read-only event, a response already sent) does not reissue;
43
43
  * the next request, carrying the same token, does.
44
44
  *
45
45
  * @default undefined — the session expires at `iat + maxAge` however often it is read.
@@ -124,63 +124,59 @@ export type OpenedSessionState<T extends SessionRecord, MaxAge extends ExpiresIn
124
124
  createdAt: number;
125
125
  };
126
126
  /** One session, defined once from its config and used on any request. */
127
- export interface SessionDefinition<T extends SessionRecord = SessionClaims, MaxAge extends ExpiresIn | undefined = ExpiresIn | undefined, TContext = unknown> {
127
+ export interface SessionDefinition<T extends SessionRecord = SessionClaims, MaxAge extends ExpiresIn | undefined = ExpiresIn | undefined, TEvent = unknown> {
128
128
  /** Reads the request's session once and returns its manager; later calls on the same request share that state. */
129
- use: (context: TContext) => Promise<SessionManager<T, MaxAge>>;
129
+ use: (event: TEvent) => Promise<SessionManager<T, MaxAge>>;
130
130
  /** The token the request carries (this response's own write first), unopened. */
131
- token: (context: TContext) => string | undefined;
131
+ token: (event: TEvent) => string | undefined;
132
132
  /** Mints a token for `data` with a fresh `jti` and `iat`, and `exp` from `maxAge` (`options.maxAge` overrides it); reads and writes nothing. */
133
133
  issue: (data?: Partial<SessionData<T>>, options?: SessionIssueOptions) => Promise<string>;
134
134
  /** 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. */
135
135
  open: (token: string) => Promise<OpenedSessionState<T, MaxAge>>;
136
136
  }
137
- /** A web-standard request event: reads, and writes while `res` is there. */
138
- export interface SessionRequestEvent {
139
- readonly req: Request;
137
+ interface SessionRequestBase {
140
138
  /** The response being prepared; without it the session is read-only. */
141
139
  readonly res?: {
142
140
  readonly headers: Headers;
143
141
  };
144
- /** The framework's per-request state, where `sessions` is kept; without it state is keyed on `req`. */
142
+ /** Per-request state shared with the framework, where `sessions` is kept; without it state is keyed on `req`, else on this object. */
145
143
  readonly context?: Record<string, unknown>;
146
144
  }
147
- /** A request by its headers: a `Request` itself, a WebSocket upgrade's request, a peer's `request` with its `context`. */
148
- export interface SessionRequestHeaders {
145
+ /** A request event: by its `Request`, or by its `Headers` (a `Request` itself, a WebSocket upgrade's request). */
146
+ export type SessionRequestEvent = SessionRequestBase & ({
147
+ readonly req: Request;
148
+ readonly headers?: Headers;
149
+ } | {
149
150
  readonly headers: Headers;
150
- /** The response being prepared, such as the headers a WebSocket `upgrade` returns; without it the session is read-only. */
151
- readonly res?: {
152
- readonly headers: Headers;
153
- };
154
- /** Per-request state shared with the framework; without it state is keyed on this object. */
155
- readonly context?: Record<string, unknown>;
156
- }
151
+ readonly req?: Request;
152
+ });
157
153
  /** A token handed in directly; sending a re-issued one is the caller's job. */
158
- export interface SessionToken {
154
+ export interface SessionHandedToken {
159
155
  token: string | undefined;
160
156
  }
161
- /** What `use()` takes: a request event, a request by its headers, or a token in hand. */
162
- export type SessionContext = SessionRequestEvent | SessionRequestHeaders | SessionToken;
157
+ /** What the Web session driver takes: a request event, or a token in hand. */
158
+ export type WebSessionEvent = SessionRequestEvent | SessionHandedToken;
163
159
  /** The cookies of one request and its response, as a framework exposes them. */
164
160
  export interface CookieJar<A extends ExpirableCookieAttributes = ExpirableCookieAttributes> {
165
161
  /** The request's cookie. */
166
162
  read(name: string): string | undefined;
167
163
  /** The value this response already assigned to `name` (`""` once deleted), when the framework exposes it. */
168
164
  written?(name: string): string | undefined;
169
- /** Absent when this context cannot take a `Set-Cookie` (a headers-only event). */
165
+ /** Absent when this event cannot take a `Set-Cookie` (a request without a response). */
170
166
  write?(name: string, value: string, attrs: A): void;
171
167
  }
172
168
  /** The primitives a framework supplies; the session core builds the cookie and header transports over them. */
173
- export interface SessionDriver<TContext> {
169
+ export interface SessionDriver<TEvent> {
174
170
  /** Message prefix for every error the adapter emits. */
175
171
  prefix: string;
176
172
  /** The per-request record session state and the session-name registry live in. */
177
- state(context: TContext): Record<string, unknown>;
178
- header(context: TContext, name: string): string | null | undefined;
179
- cookies(context: TContext): CookieJar;
173
+ state(event: TEvent): Record<string, unknown>;
174
+ header(event: TEvent, name: string): string | null | undefined;
175
+ cookies(event: TEvent): CookieJar;
180
176
  /** Platform signal that the response can still change (Node `headersSent`); absent = trust the jar. */
181
- writable?(context: TContext): boolean;
182
- /** A token the context carries directly, when it does: no cookie or header is consulted. */
183
- handed?(context: TContext): {
177
+ writable?(event: TEvent): boolean;
178
+ /** A token the event carries directly, when it does: no cookie or header is consulted. */
179
+ handed?(event: TEvent): {
184
180
  token: string | undefined;
185
181
  } | undefined;
186
182
  }
@@ -409,21 +409,21 @@ function decodeValue(value) {
409
409
  return value;
410
410
  }
411
411
  }
412
- function resolveTransport(driver, context, options) {
413
- const handed = driver.handed?.(context);
412
+ function resolveTransport(driver, event, options) {
413
+ const handed = driver.handed?.(event);
414
414
  if (handed) return {
415
415
  read: () => handed.token,
416
416
  readonly: false,
417
417
  writable: () => true
418
418
  };
419
419
  const { config, name } = options;
420
- const header = headerReader(driver, context, options);
420
+ const header = headerReader(driver, event, options);
421
421
  if (config.cookie === false) return {
422
422
  read: header,
423
423
  readonly: false,
424
424
  writable: () => true
425
425
  };
426
- const jar = driver.cookies(context);
426
+ const jar = driver.cookies(event);
427
427
  const store = responseStore(jar);
428
428
  const transport = {
429
429
  read: () => {
@@ -432,7 +432,7 @@ function resolveTransport(driver, context, options) {
432
432
  return (written ?? readChunked(jar, name)) || header?.() || void 0;
433
433
  },
434
434
  readonly: !store,
435
- writable: () => driver.writable?.(context) ?? true
435
+ writable: () => driver.writable?.(event) ?? true
436
436
  };
437
437
  if (!store) return transport;
438
438
  transport.write = (token, { attrs, chunkMaxLength }) => {
@@ -471,11 +471,11 @@ function headerToken(value) {
471
471
  if (/^bearer$/i.test(first)) return words.length === 2 ? second : void 0;
472
472
  return words.length === 1 && first ? first : void 0;
473
473
  }
474
- function headerReader(driver, context, options) {
474
+ function headerReader(driver, event, options) {
475
475
  const { config, name } = options;
476
476
  if (config.sessionHeader === false) return void 0;
477
477
  const header = sessionHeaderName(name, config.sessionHeader);
478
- return () => headerToken(driver.header(context, header));
478
+ return () => headerToken(driver.header(event, header));
479
479
  }
480
480
  function responseStore(jar) {
481
481
  const write = jar.write?.bind(jar);
@@ -486,7 +486,7 @@ function responseStore(jar) {
486
486
  };
487
487
  }
488
488
  const kSessionNames = Symbol("unjwt_session_names");
489
- function bindSession(context, config, options) {
489
+ function bindSession(event, config, options) {
490
490
  const { driver, codec, actions, hookArgs } = options;
491
491
  const { prefix } = driver;
492
492
  const name = config.name || codec.defaultName;
@@ -497,22 +497,22 @@ function bindSession(context, config, options) {
497
497
  ...config.cookie
498
498
  }, { prefix });
499
499
  assertRolling(config, { prefix });
500
- const record = driver.state(context);
500
+ const record = driver.state(event);
501
501
  claimSessionName(record, {
502
502
  name,
503
503
  family: codec.family,
504
504
  prefix
505
505
  });
506
506
  return {
507
- context,
507
+ event,
508
508
  config,
509
509
  driver,
510
510
  codec,
511
511
  actions,
512
512
  name,
513
- args: hookArgs(context),
513
+ args: hookArgs(event),
514
514
  store: recordSlotStore(record, `${codec.family}:${name}`),
515
- transport: resolveTransport(driver, context, {
515
+ transport: resolveTransport(driver, event, {
516
516
  config,
517
517
  name
518
518
  })
@@ -828,19 +828,19 @@ function snapshotSession(session) {
828
828
  function defineSession(config, options) {
829
829
  const { driver, codec, hookArgs } = options;
830
830
  const actions = sessionActions();
831
- const bind = (context) => bindSession(context, config, {
831
+ const bind = (event) => bindSession(event, config, {
832
832
  driver,
833
833
  codec,
834
834
  actions,
835
835
  hookArgs
836
836
  });
837
837
  return {
838
- use: async (context) => {
839
- const binding = bind(context);
838
+ use: async (event) => {
839
+ const binding = bind(event);
840
840
  await loadSession(binding);
841
841
  return sessionManager(binding);
842
842
  },
843
- token: (context) => sessionToken(bind(context)),
843
+ token: (event) => sessionToken(bind(event)),
844
844
  issue: async (data, issueOptions) => {
845
845
  await codec.assertKeys(config);
846
846
  const issue = codec.issuer(config);
@@ -283,29 +283,32 @@ function getPlaintextBytes(payload) {
283
283
  throw new JWTError("Plaintext must be a string, Uint8Array, or a JSON-serializable object.", "ERR_INVALID_OPTION");
284
284
  }
285
285
  function computeJwtTimeClaims(payload, options) {
286
- const { currentDate, expiresIn, expiresAt, notBeforeIn, notBeforeAt } = options ?? {};
286
+ const { currentDate, issuedAt, expiresIn, expiresAt, notBeforeIn, notBeforeAt } = options ?? {};
287
+ if (issuedAt !== void 0 && typeof issuedAt !== "boolean" && !(issuedAt instanceof Date)) throw new JWTError("\"issuedAt\" must be a boolean or a Date.", "ERR_INVALID_OPTION");
287
288
  if (expiresIn !== void 0 && expiresAt !== void 0) throw new JWTError("\"expiresIn\" and \"expiresAt\" are mutually exclusive; pass only one.", "ERR_JWT_CLAIM_INVALID");
288
289
  if (notBeforeIn !== void 0 && notBeforeAt !== void 0) throw new JWTError("\"notBeforeIn\" and \"notBeforeAt\" are mutually exclusive; pass only one.", "ERR_JWT_CLAIM_INVALID");
289
290
  const hasExpHint = expiresIn !== void 0 || expiresAt !== void 0;
290
291
  const hasNbfHint = notBeforeIn !== void 0 || notBeforeAt !== void 0;
291
- if (!hasExpHint && !hasNbfHint) return void 0;
292
+ const hasIatHint = issuedAt === true || issuedAt instanceof Date;
293
+ if (!hasExpHint && !hasNbfHint && !hasIatHint) return void 0;
292
294
  if (!payload || typeof payload !== "object" || payload instanceof Uint8Array) return void 0;
293
295
  const wantsExp = hasExpHint && (!("exp" in payload) || payload.exp === void 0);
294
296
  const wantsNbf = hasNbfHint && (!("nbf" in payload) || payload.nbf === void 0);
295
- if (!wantsExp && !wantsNbf) return void 0;
297
+ const wantsIat = hasIatHint && (!("iat" in payload) || payload.iat === void 0);
298
+ if (!wantsExp && !wantsNbf && !wantsIat) return void 0;
296
299
  const now = Math.round((currentDate ?? /* @__PURE__ */ new Date()).getTime() / 1e3);
297
300
  const claims = { ...payload };
298
- claims.iat ||= now;
301
+ claims.iat ||= issuedAt instanceof Date ? Math.floor(_instantOf(issuedAt, "issuedAt") / 1e3) : now;
299
302
  if (wantsExp) {
300
303
  if (expiresAt !== void 0) claims.exp = Math.floor(_instantOf(expiresAt, "expiresAt") / 1e3);
301
- else if (expiresIn !== void 0) claims.exp = claims.iat + computeDurationInSeconds(expiresIn);
304
+ else if (expiresIn !== void 0) claims.exp = now + computeDurationInSeconds(expiresIn);
302
305
  }
303
306
  if (wantsNbf) {
304
307
  if (notBeforeAt !== void 0) claims.nbf = Math.floor(_instantOf(notBeforeAt, "notBeforeAt") / 1e3);
305
308
  else if (notBeforeIn !== void 0) {
306
309
  const offset = parseDurationSeconds(notBeforeIn);
307
310
  if (offset < 0) throw new JWTError("\"notBeforeIn\" must be zero or a positive duration.", "ERR_JWT_CLAIM_INVALID");
308
- claims.nbf = claims.iat + offset;
311
+ claims.nbf = now + offset;
309
312
  }
310
313
  }
311
314
  return claims;
@@ -210,13 +210,15 @@ export interface JWTClaimValidationOptions {
210
210
  }
211
211
  /** Time claims a producer computes; a claim already in the payload is kept as given. */
212
212
  export interface JWTTimeClaimOptions {
213
- /** Reference moment for `iat` and relative durations. @default new Date() */
213
+ /** The clock: `iat` when written, and the base of `expiresIn` / `notBeforeIn`. @default new Date() */
214
214
  currentDate?: Date;
215
- /** Duration until `exp`; exclusive with `expiresAt`. */
215
+ /** Writes `iat` on its own: `true` as `currentDate`, a `Date` as that instant; `false` is unset. `exp`/`nbf` options write it either way. */
216
+ issuedAt?: boolean | Date;
217
+ /** Duration from `currentDate` until `exp`; exclusive with `expiresAt`. */
216
218
  expiresIn?: ExpiresIn;
217
219
  /** Absolute `exp`; exclusive with `expiresIn`. */
218
220
  expiresAt?: Date;
219
- /** Duration from `iat` until `nbf` (`0` sets `nbf = iat`); exclusive with `notBeforeAt`. */
221
+ /** Duration from `currentDate` until `nbf` (`0` sets `nbf` to it); exclusive with `notBeforeAt`. */
220
222
  notBeforeIn?: ExpiresIn;
221
223
  /** Absolute `nbf` (RFC 7519 §4.1.5); exclusive with `notBeforeIn`. */
222
224
  notBeforeAt?: Date;
@@ -24,7 +24,8 @@ export declare function getPlaintextBytes(payload: JOSEPayload): Uint8Array<Arra
24
24
  export type ComputeJwtTimeClaimsOptions = JWTTimeClaimOptions;
25
25
  /**
26
26
  * Return a copy of an object payload with `iat` and the requested `exp` / `nbf`, or `undefined` when none applies.
27
- * Both members of `expiresIn`/`expiresAt` or `notBeforeIn`/`notBeforeAt` throw `ERR_JWT_CLAIM_INVALID`.
27
+ * `currentDate` is the clock: `iat` when written, and the base of `expiresIn` / `notBeforeIn`;
28
+ * `issuedAt` writes `iat` alone, a `Date` as that instant. Both members of `expiresIn`/`expiresAt` or `notBeforeIn`/`notBeforeAt` throw `ERR_JWT_CLAIM_INVALID`.
28
29
  */
29
30
  export declare function computeJwtTimeClaims(payload: unknown, options?: ComputeJwtTimeClaimsOptions): JWTClaims | undefined;
30
31
  /** Validate critical headers in JWS semantics. */
@@ -1,4 +1,4 @@
1
- import { CookieJar, JWESessionConfig, JWESessionHooks, JWSSessionConfig, JWSSessionHooks, OpenedSessionState, SessionClaims, SessionContext, SessionData, SessionDecryptOptions, SessionDefinition, SessionDriver, SessionEncryptOptions, SessionIssueOptions, SessionManager, SessionRecord, SessionRequestEvent, SessionRequestHeaders, SessionSignOptions, SessionState, SessionToken, SessionUpdate, SessionUpdateTrigger, SessionVerifyOptions } from "../_chunks/_codec-jwe.mjs";
1
+ import { CookieJar, JWESessionConfig, JWESessionHooks, JWSSessionConfig, JWSSessionHooks, OpenedSessionState, SessionClaims, SessionData, SessionDecryptOptions, SessionDefinition, SessionDriver, SessionEncryptOptions, SessionHandedToken, SessionIssueOptions, SessionManager, SessionRecord, SessionRequestEvent, SessionSignOptions, SessionState, SessionUpdate, SessionUpdateTrigger, SessionVerifyOptions, WebSessionEvent } from "../_chunks/_codec-jwe.mjs";
2
2
  import { CookieAttributes } from "../_chunks/_cookie-attributes.mjs";
3
3
  import { CompositeKey, ContentEncryptionAlgorithm, DeriveJWKOptions, DeriveJWKReturn, DeriveKeyOptions, DeriveKeyReturn, Duration, ECDHEphemeralKeyInput, ExpiresIn, GenerateJWKOptions, GenerateJWKReturn, GenerateKeyAlgorithm, GenerateKeyOptions, GenerateKeyReturn, GeneratedJWKMap, GeneratedKeyMap, ImportedKey, ImportedKeyMap, ImportedPEMJWK, JOSEConsumerOptions, JOSELimits, JOSEPayload, JOSEPayloadMode, JOSEPayloadTypeMap, JWEAsymmetricPrivateJWK, JWEAsymmetricPublicJWK, JWEDecryptJWK, JWEDecryptOptions, JWEDecryptResult, JWEEncryptJWK, JWEEncryptOptions, JWEFlattenedSerialization, JWEGeneralRecipient, JWEGeneralSerialization, JWEHeaderParameters, JWEKeyLookup, JWEKeyManagementHeaderParameters, JWELibraryHeaderName, JWEMultiDecryptKey, JWEMultiDecryptOptions, JWEMultiDecryptResult, JWEMultiEncryptOptions, JWEMultiRecipient, JWEProtectedHeader, JWK, JWKAlgorithm, JWKCacheAdapter, JWKLookupFunction, JWKLookupFunctionHeader, JWKMetadata, JWKPEMAlgorithm, JWKParameters, JWKSet, JWK_AES_Algorithm, JWK_AES_CBC_HMAC, JWK_AES_GCM, JWK_AES_GCM_KW, JWK_AES_KW, JWK_Asymmetric, JWK_Asymmetric_Algorithm, JWK_EC, JWK_ECDH_ES, JWK_ECDSA, JWK_EC_Private, JWK_EC_Public, JWK_HMAC, JWK_OKP, JWK_OKP_Private, JWK_OKP_Public, JWK_OKP_SIGN, JWK_PBES2, JWK_Pair, JWK_Private, JWK_Public, JWK_RSA, JWK_RSA_ENC, JWK_RSA_PSS, JWK_RSA_Private, JWK_RSA_Public, JWK_RSA_SIGN, JWK_Symmetric, JWK_Symmetric_Algorithm, JWK_oct, JWSAlgorithm, JWSAsymmetricPrivateJWK, JWSAsymmetricPublicJWK, JWSFlattenedSerialization, JWSGeneralSerialization, JWSGeneralSignature, JWSHashedAlgorithm, JWSHeaderParameters, JWSKeyLookup, JWSMultiSignOptions, JWSMultiSigner, JWSMultiVerifyAllOptions, JWSMultiVerifyOptions, JWSMultiVerifyOutcome, JWSMultiVerifyResult, JWSProtectedHeader, JWSSignJWK, JWSSignOptions, JWSVerifyJWK, JWSVerifyOptions, JWSVerifyResult, JWT, JWTClaimValidationOptions, JWTClaims, JWTConfirmation, JWTTimeClaimOptions, JoseHeaderParameters, KeyManagementAlgorithm, KeyWrapAlgorithmOf, KeyWrappingAlgorithm, MaxTokenAge, NotBeforeIn, PEMType, PayloadOf, ToPublicJWKReturn, UnwrapKeyOptions, UnwrapKeyResult, UnwrappingKeyFor, WrapKeyOptions, WrapKeyResult, WrappingKeyFor } from "../_chunks/index.mjs";
4
4
  import { thumbprint } from "../_chunks/index2.mjs";
@@ -6,39 +6,39 @@ import { deriveJWKFromPassword, exportPEM, generateJWK, importPEM, toPublicJWK }
6
6
  /** Session state for the current request, mirroring the claims of its JWS token. */
7
7
  interface SessionJWS<T extends SessionRecord = SessionClaims, MaxAge extends ExpiresIn | undefined = ExpiresIn | undefined> extends SessionState<T, MaxAge> {}
8
8
  /** JWS session hooks; `onRead`, `onExpire` and `onError` are mutually exclusive per token. */
9
- interface SessionHooksJWS<T extends SessionRecord = SessionClaims, MaxAge extends ExpiresIn | undefined = ExpiresIn | undefined, TContext = SessionContext> extends JWSSessionHooks<SessionJWS<T, MaxAge>, SessionManager<T, MaxAge>, {
10
- context: TContext;
11
- }, SessionConfigJWS<T, MaxAge, TContext>> {}
9
+ interface SessionHooksJWS<T extends SessionRecord = SessionClaims, MaxAge extends ExpiresIn | undefined = ExpiresIn | undefined, TEvent = WebSessionEvent> extends JWSSessionHooks<SessionJWS<T, MaxAge>, SessionManager<T, MaxAge>, {
10
+ event: TEvent;
11
+ }, SessionConfigJWS<T, MaxAge, TEvent>> {}
12
12
  /** Configuration for a JWS-backed (signed, not encrypted) session. */
13
- interface SessionConfigJWS<T extends SessionRecord = SessionClaims, MaxAge extends ExpiresIn | undefined = ExpiresIn | undefined, TContext = SessionContext> extends JWSSessionConfig<MaxAge, CookieAttributes> {
13
+ interface SessionConfigJWS<T extends SessionRecord = SessionClaims, MaxAge extends ExpiresIn | undefined = ExpiresIn | undefined, TEvent = WebSessionEvent> extends JWSSessionConfig<MaxAge, CookieAttributes> {
14
14
  /** Cookie and session-header name. Default `"unjwt-jws"`; a `.<digits>` suffix throws `ERR_SESSION_CONFIG_INVALID`. */
15
15
  name?: string;
16
- hooks?: SessionHooksJWS<T, MaxAge, TContext>;
16
+ hooks?: SessionHooksJWS<T, MaxAge, TEvent>;
17
17
  }
18
18
  /** Defines a JWS (signed, not encrypted) session once, its data readable by clients; `use`, `token`, `issue` and `open` serve every request. */
19
- export declare function defineJWSSession<T extends SessionRecord = SessionClaims, MaxAge extends ExpiresIn | undefined = ExpiresIn | undefined, TContext extends SessionContext = SessionContext>(config: SessionConfigJWS<T, MaxAge, TContext>): SessionDefinition<T, MaxAge, TContext>;
19
+ export declare function defineJWSSession<T extends SessionRecord = SessionClaims, MaxAge extends ExpiresIn | undefined = ExpiresIn | undefined, TEvent extends WebSessionEvent = WebSessionEvent>(config: SessionConfigJWS<T, MaxAge, TEvent>): SessionDefinition<T, MaxAge, TEvent>;
20
20
  /** Defines a JWS (signed, not encrypted) session over a framework driver of your own. */
21
- export declare function defineJWSSession<T extends SessionRecord = SessionClaims, MaxAge extends ExpiresIn | undefined = ExpiresIn | undefined, TContext = SessionContext>(config: SessionConfigJWS<T, MaxAge, TContext>, options: {
22
- driver: SessionDriver<TContext>;
23
- }): SessionDefinition<T, MaxAge, TContext>;
21
+ export declare function defineJWSSession<T extends SessionRecord = SessionClaims, MaxAge extends ExpiresIn | undefined = ExpiresIn | undefined, TEvent = WebSessionEvent>(config: SessionConfigJWS<T, MaxAge, TEvent>, options: {
22
+ driver: SessionDriver<TEvent>;
23
+ }): SessionDefinition<T, MaxAge, TEvent>;
24
24
  /** Session state for the current request, mirroring the claims of its JWE token. */
25
25
  interface SessionJWE<T extends SessionRecord = SessionClaims, MaxAge extends ExpiresIn | undefined = ExpiresIn | undefined> extends SessionState<T, MaxAge> {}
26
26
  /** JWE session hooks; `onRead`, `onExpire` and `onError` are mutually exclusive per token. */
27
- interface SessionHooksJWE<T extends SessionRecord = SessionClaims, MaxAge extends ExpiresIn | undefined = ExpiresIn | undefined, TContext = SessionContext> extends JWESessionHooks<SessionJWE<T, MaxAge>, SessionManager<T, MaxAge>, {
28
- context: TContext;
29
- }, SessionConfigJWE<T, MaxAge, TContext>> {}
27
+ interface SessionHooksJWE<T extends SessionRecord = SessionClaims, MaxAge extends ExpiresIn | undefined = ExpiresIn | undefined, TEvent = WebSessionEvent> extends JWESessionHooks<SessionJWE<T, MaxAge>, SessionManager<T, MaxAge>, {
28
+ event: TEvent;
29
+ }, SessionConfigJWE<T, MaxAge, TEvent>> {}
30
30
  /** Configuration for a JWE-backed (encrypted) session. */
31
- interface SessionConfigJWE<T extends SessionRecord = SessionClaims, MaxAge extends ExpiresIn | undefined = ExpiresIn | undefined, TContext = SessionContext> extends JWESessionConfig<MaxAge, CookieAttributes> {
31
+ interface SessionConfigJWE<T extends SessionRecord = SessionClaims, MaxAge extends ExpiresIn | undefined = ExpiresIn | undefined, TEvent = WebSessionEvent> extends JWESessionConfig<MaxAge, CookieAttributes> {
32
32
  /** Cookie and session-header name. Default `"unjwt-jwe"`; a `.<digits>` suffix throws `ERR_SESSION_CONFIG_INVALID`. */
33
33
  name?: string;
34
- hooks?: SessionHooksJWE<T, MaxAge, TContext>;
34
+ hooks?: SessionHooksJWE<T, MaxAge, TEvent>;
35
35
  }
36
36
  /** Defines a JWE (encrypted) session once; `use`, `token`, `issue` and `open` serve every request. */
37
- export declare function defineJWESession<T extends SessionRecord = SessionClaims, MaxAge extends ExpiresIn | undefined = ExpiresIn | undefined, TContext extends SessionContext = SessionContext>(config: SessionConfigJWE<T, MaxAge, TContext>): SessionDefinition<T, MaxAge, TContext>;
37
+ export declare function defineJWESession<T extends SessionRecord = SessionClaims, MaxAge extends ExpiresIn | undefined = ExpiresIn | undefined, TEvent extends WebSessionEvent = WebSessionEvent>(config: SessionConfigJWE<T, MaxAge, TEvent>): SessionDefinition<T, MaxAge, TEvent>;
38
38
  /** Defines a JWE (encrypted) session over a framework driver of your own. */
39
- export declare function defineJWESession<T extends SessionRecord = SessionClaims, MaxAge extends ExpiresIn | undefined = ExpiresIn | undefined, TContext = SessionContext>(config: SessionConfigJWE<T, MaxAge, TContext>, options: {
40
- driver: SessionDriver<TContext>;
41
- }): SessionDefinition<T, MaxAge, TContext>;
39
+ export declare function defineJWESession<T extends SessionRecord = SessionClaims, MaxAge extends ExpiresIn | undefined = ExpiresIn | undefined, TEvent = WebSessionEvent>(config: SessionConfigJWE<T, MaxAge, TEvent>, options: {
40
+ driver: SessionDriver<TEvent>;
41
+ }): SessionDefinition<T, MaxAge, TEvent>;
42
42
  /** Types a session driver for a framework; pass it to `defineJWSSession` / `defineJWESession` as `{ driver }`. */
43
- export declare function defineSessionDriver<TContext>(driver: SessionDriver<TContext>): SessionDriver<TContext>;
44
- export { type CompositeKey, type ContentEncryptionAlgorithm, type CookieAttributes, type CookieJar, type DeriveJWKOptions, type DeriveJWKReturn, type DeriveKeyOptions, type DeriveKeyReturn, type Duration, type ECDHEphemeralKeyInput, type ExpiresIn, type GenerateJWKOptions, type GenerateJWKReturn, type GenerateKeyAlgorithm, type GenerateKeyOptions, type GenerateKeyReturn, type GeneratedJWKMap, type GeneratedKeyMap, type ImportedKey, type ImportedKeyMap, type ImportedPEMJWK, type JOSEConsumerOptions, type JOSELimits, type JOSEPayload, type JOSEPayloadMode, type JOSEPayloadTypeMap, type JWEAsymmetricPrivateJWK, type JWEAsymmetricPublicJWK, type JWEDecryptJWK, type JWEDecryptOptions, type JWEDecryptResult, type JWEEncryptJWK, type JWEEncryptOptions, type JWEFlattenedSerialization, type JWEGeneralRecipient, type JWEGeneralSerialization, type JWEHeaderParameters, type JWEKeyLookup, type JWEKeyManagementHeaderParameters, type JWELibraryHeaderName, type JWEMultiDecryptKey, type JWEMultiDecryptOptions, type JWEMultiDecryptResult, type JWEMultiEncryptOptions, type JWEMultiRecipient, type JWEProtectedHeader, type JWK, type JWKAlgorithm, type JWKCacheAdapter, type JWKLookupFunction, type JWKLookupFunctionHeader, type JWKMetadata, type JWKPEMAlgorithm, type JWKParameters, type JWKSet, type JWK_AES_Algorithm, type JWK_AES_CBC_HMAC, type JWK_AES_GCM, type JWK_AES_GCM_KW, type JWK_AES_KW, type JWK_Asymmetric, type JWK_Asymmetric_Algorithm, type JWK_EC, type JWK_ECDH_ES, type JWK_ECDSA, type JWK_EC_Private, type JWK_EC_Public, type JWK_HMAC, type JWK_OKP, type JWK_OKP_Private, type JWK_OKP_Public, type JWK_OKP_SIGN, type JWK_PBES2, type JWK_Pair, type JWK_Private, type JWK_Public, type JWK_RSA, type JWK_RSA_ENC, type JWK_RSA_PSS, type JWK_RSA_Private, type JWK_RSA_Public, type JWK_RSA_SIGN, type JWK_Symmetric, type JWK_Symmetric_Algorithm, type JWK_oct, type JWSAlgorithm, type JWSAsymmetricPrivateJWK, type JWSAsymmetricPublicJWK, type JWSFlattenedSerialization, type JWSGeneralSerialization, type JWSGeneralSignature, type JWSHashedAlgorithm, type JWSHeaderParameters, type JWSKeyLookup, type JWSMultiSignOptions, type JWSMultiSigner, type JWSMultiVerifyAllOptions, type JWSMultiVerifyOptions, type JWSMultiVerifyOutcome, type JWSMultiVerifyResult, type JWSProtectedHeader, type JWSSignJWK, type JWSSignOptions, type JWSVerifyJWK, type JWSVerifyOptions, type JWSVerifyResult, type JWT, type JWTClaimValidationOptions, type JWTClaims, type JWTConfirmation, type JWTTimeClaimOptions, type JoseHeaderParameters, type KeyManagementAlgorithm, type KeyWrapAlgorithmOf, type KeyWrappingAlgorithm, type MaxTokenAge, type NotBeforeIn, type OpenedSessionState, type PEMType, type PayloadOf, type SessionClaims, type SessionConfigJWE, type SessionConfigJWS, type SessionContext, type SessionData, type SessionDecryptOptions, type SessionDefinition, type SessionDriver, type SessionEncryptOptions, type SessionHooksJWE, type SessionHooksJWS, type SessionIssueOptions, type SessionJWE, type SessionJWS, type SessionManager, type SessionRequestEvent, type SessionRequestHeaders, type SessionSignOptions, type SessionToken, type SessionUpdate, type SessionUpdateTrigger, type SessionVerifyOptions, type ToPublicJWKReturn, type UnwrapKeyOptions, type UnwrapKeyResult, type UnwrappingKeyFor, type WrapKeyOptions, type WrapKeyResult, type WrappingKeyFor, deriveJWKFromPassword, exportPEM, generateJWK, importPEM, thumbprint, toPublicJWK };
43
+ export declare function defineSessionDriver<TEvent>(driver: SessionDriver<TEvent>): SessionDriver<TEvent>;
44
+ export { type CompositeKey, type ContentEncryptionAlgorithm, type CookieAttributes, type CookieJar, type DeriveJWKOptions, type DeriveJWKReturn, type DeriveKeyOptions, type DeriveKeyReturn, type Duration, type ECDHEphemeralKeyInput, type ExpiresIn, type GenerateJWKOptions, type GenerateJWKReturn, type GenerateKeyAlgorithm, type GenerateKeyOptions, type GenerateKeyReturn, type GeneratedJWKMap, type GeneratedKeyMap, type ImportedKey, type ImportedKeyMap, type ImportedPEMJWK, type JOSEConsumerOptions, type JOSELimits, type JOSEPayload, type JOSEPayloadMode, type JOSEPayloadTypeMap, type JWEAsymmetricPrivateJWK, type JWEAsymmetricPublicJWK, type JWEDecryptJWK, type JWEDecryptOptions, type JWEDecryptResult, type JWEEncryptJWK, type JWEEncryptOptions, type JWEFlattenedSerialization, type JWEGeneralRecipient, type JWEGeneralSerialization, type JWEHeaderParameters, type JWEKeyLookup, type JWEKeyManagementHeaderParameters, type JWELibraryHeaderName, type JWEMultiDecryptKey, type JWEMultiDecryptOptions, type JWEMultiDecryptResult, type JWEMultiEncryptOptions, type JWEMultiRecipient, type JWEProtectedHeader, type JWK, type JWKAlgorithm, type JWKCacheAdapter, type JWKLookupFunction, type JWKLookupFunctionHeader, type JWKMetadata, type JWKPEMAlgorithm, type JWKParameters, type JWKSet, type JWK_AES_Algorithm, type JWK_AES_CBC_HMAC, type JWK_AES_GCM, type JWK_AES_GCM_KW, type JWK_AES_KW, type JWK_Asymmetric, type JWK_Asymmetric_Algorithm, type JWK_EC, type JWK_ECDH_ES, type JWK_ECDSA, type JWK_EC_Private, type JWK_EC_Public, type JWK_HMAC, type JWK_OKP, type JWK_OKP_Private, type JWK_OKP_Public, type JWK_OKP_SIGN, type JWK_PBES2, type JWK_Pair, type JWK_Private, type JWK_Public, type JWK_RSA, type JWK_RSA_ENC, type JWK_RSA_PSS, type JWK_RSA_Private, type JWK_RSA_Public, type JWK_RSA_SIGN, type JWK_Symmetric, type JWK_Symmetric_Algorithm, type JWK_oct, type JWSAlgorithm, type JWSAsymmetricPrivateJWK, type JWSAsymmetricPublicJWK, type JWSFlattenedSerialization, type JWSGeneralSerialization, type JWSGeneralSignature, type JWSHashedAlgorithm, type JWSHeaderParameters, type JWSKeyLookup, type JWSMultiSignOptions, type JWSMultiSigner, type JWSMultiVerifyAllOptions, type JWSMultiVerifyOptions, type JWSMultiVerifyOutcome, type JWSMultiVerifyResult, type JWSProtectedHeader, type JWSSignJWK, type JWSSignOptions, type JWSVerifyJWK, type JWSVerifyOptions, type JWSVerifyResult, type JWT, type JWTClaimValidationOptions, type JWTClaims, type JWTConfirmation, type JWTTimeClaimOptions, type JoseHeaderParameters, type KeyManagementAlgorithm, type KeyWrapAlgorithmOf, type KeyWrappingAlgorithm, type MaxTokenAge, type NotBeforeIn, type OpenedSessionState, type PEMType, type PayloadOf, type SessionClaims, type SessionConfigJWE, type SessionConfigJWS, type SessionData, type SessionDecryptOptions, type SessionDefinition, type SessionDriver, type SessionEncryptOptions, type SessionHandedToken, type SessionHooksJWE, type SessionHooksJWS, type SessionIssueOptions, type SessionJWE, type SessionJWS, type SessionManager, type SessionRequestEvent, type SessionSignOptions, type SessionUpdate, type SessionUpdateTrigger, type SessionVerifyOptions, type ToPublicJWKReturn, type UnwrapKeyOptions, type UnwrapKeyResult, type UnwrappingKeyFor, type WebSessionEvent, type WrapKeyOptions, type WrapKeyResult, type WrappingKeyFor, deriveJWKFromPassword, exportPEM, generateJWK, importPEM, thumbprint, toPublicJWK };
@@ -47,26 +47,28 @@ const PREFIX = "[unjwt/session]";
47
47
  const SESSIONS = /* @__PURE__ */ new WeakMap();
48
48
  const webSessionDriver = {
49
49
  prefix: PREFIX,
50
- state: (context) => {
51
- if (isHanded(context)) return sessionsOf(context);
52
- if (context.context) return contextSessions(context.context);
53
- return sessionsOf("req" in context ? webRequest(context) : context);
50
+ state: (event) => {
51
+ if (isHanded(event)) return sessionsOf(event);
52
+ if (event.context) return contextSessions(event.context);
53
+ return sessionsOf(event.req ? webRequest(event.req) : event);
54
54
  },
55
- header: (context, name) => isHanded(context) ? void 0 : requestHeaders(context).get(name),
56
- cookies: (context) => isHanded(context) ? { read: () => void 0 } : webCookieJar(requestHeaders(context), context.res?.headers),
57
- handed: (context) => isHanded(context) ? { token: context.token } : void 0
55
+ header: (event, name) => isHanded(event) ? void 0 : requestHeaders(event).get(name),
56
+ cookies: (event) => isHanded(event) ? { read: () => void 0 } : webCookieJar(requestHeaders(event), event.res?.headers),
57
+ handed: (event) => isHanded(event) ? { token: event.token } : void 0
58
58
  };
59
- function isHanded(context) {
60
- if ("req" in context || "headers" in context) return false;
61
- if ("token" in context) return true;
62
- throw invalidConfigError(`${PREFIX} use() got neither a request event, a request's headers, nor a token.`);
59
+ function isHanded(event) {
60
+ if ("req" in event || "headers" in event) return false;
61
+ if ("token" in event) return true;
62
+ throw invalidConfigError(`${PREFIX} use() got neither a request event nor a token.`);
63
63
  }
64
- function requestHeaders(context) {
65
- return "req" in context ? webRequest(context).headers : context.headers;
64
+ function requestHeaders(event) {
65
+ if (event.req) return webRequest(event.req).headers;
66
+ if (event.headers) return event.headers;
67
+ throw invalidConfigError(`${PREFIX} use() got a request event with neither "req" nor "headers".`);
66
68
  }
67
- function webRequest(context) {
68
- const headers = context.req.headers;
69
- if (typeof headers === "object" && headers !== null && "get" in headers) return context.req;
69
+ function webRequest(req) {
70
+ const headers = req.headers;
71
+ if (typeof headers === "object" && headers !== null && "get" in headers) return req;
70
72
  throw invalidConfigError(`${PREFIX} use() got an event whose "req" is not a web Request.`);
71
73
  }
72
74
  function contextSessions(context) {
@@ -87,7 +89,7 @@ function defineJWSSession(config, options) {
87
89
  const driver = options?.driver ?? webSessionDriver;
88
90
  return defineSession(config, {
89
91
  driver,
90
- hookArgs: (context) => ({ context }),
92
+ hookArgs: (event) => ({ event }),
91
93
  codec: createJWSCodec({
92
94
  prefix: driver.prefix,
93
95
  defaultName: "unjwt-jws"
@@ -98,7 +100,7 @@ function defineJWESession(config, options) {
98
100
  const driver = options?.driver ?? webSessionDriver;
99
101
  return defineSession(config, {
100
102
  driver,
101
- hookArgs: (context) => ({ context }),
103
+ hookArgs: (event) => ({ event }),
102
104
  codec: createJWECodec({
103
105
  prefix: driver.prefix,
104
106
  defaultName: "unjwt-jwe"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "unjwt",
3
- "version": "0.8.2",
3
+ "version": "0.8.3",
4
4
  "description": "A collection of JWT utilities based on the Web Crypto API.",
5
5
  "keywords": [
6
6
  "auth",