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.
- package/dist/_chunks/_codec-jwe.d.mts +24 -28
- package/dist/_chunks/_codec-jws.mjs +16 -16
- package/dist/_chunks/_jwt-internal.mjs +9 -6
- package/dist/_chunks/index.d.mts +5 -3
- package/dist/_chunks/jwt.d.mts +2 -1
- package/dist/session/index.d.mts +21 -21
- package/dist/session/index.mjs +20 -18
- package/package.json +1 -1
|
@@ -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
|
|
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,
|
|
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: (
|
|
129
|
+
use: (event: TEvent) => Promise<SessionManager<T, MaxAge>>;
|
|
130
130
|
/** The token the request carries (this response's own write first), unopened. */
|
|
131
|
-
token: (
|
|
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
|
-
|
|
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
|
-
/**
|
|
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
|
|
148
|
-
export
|
|
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
|
-
|
|
151
|
-
|
|
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
|
|
154
|
+
export interface SessionHandedToken {
|
|
159
155
|
token: string | undefined;
|
|
160
156
|
}
|
|
161
|
-
/** What
|
|
162
|
-
export type
|
|
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
|
|
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<
|
|
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(
|
|
178
|
-
header(
|
|
179
|
-
cookies(
|
|
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?(
|
|
182
|
-
/** A token the
|
|
183
|
-
handed?(
|
|
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,
|
|
413
|
-
const handed = driver.handed?.(
|
|
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,
|
|
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(
|
|
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?.(
|
|
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,
|
|
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(
|
|
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(
|
|
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(
|
|
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
|
-
|
|
507
|
+
event,
|
|
508
508
|
config,
|
|
509
509
|
driver,
|
|
510
510
|
codec,
|
|
511
511
|
actions,
|
|
512
512
|
name,
|
|
513
|
-
args: hookArgs(
|
|
513
|
+
args: hookArgs(event),
|
|
514
514
|
store: recordSlotStore(record, `${codec.family}:${name}`),
|
|
515
|
-
transport: resolveTransport(driver,
|
|
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 = (
|
|
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 (
|
|
839
|
-
const binding = bind(
|
|
838
|
+
use: async (event) => {
|
|
839
|
+
const binding = bind(event);
|
|
840
840
|
await loadSession(binding);
|
|
841
841
|
return sessionManager(binding);
|
|
842
842
|
},
|
|
843
|
-
token: (
|
|
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
|
-
|
|
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
|
-
|
|
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 =
|
|
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 =
|
|
311
|
+
claims.nbf = now + offset;
|
|
309
312
|
}
|
|
310
313
|
}
|
|
311
314
|
return claims;
|
package/dist/_chunks/index.d.mts
CHANGED
|
@@ -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
|
-
/**
|
|
213
|
+
/** The clock: `iat` when written, and the base of `expiresIn` / `notBeforeIn`. @default new Date() */
|
|
214
214
|
currentDate?: Date;
|
|
215
|
-
/**
|
|
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 `
|
|
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;
|
package/dist/_chunks/jwt.d.mts
CHANGED
|
@@ -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
|
-
*
|
|
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. */
|
package/dist/session/index.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CookieJar, JWESessionConfig, JWESessionHooks, JWSSessionConfig, JWSSessionHooks, OpenedSessionState, SessionClaims,
|
|
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,
|
|
10
|
-
|
|
11
|
-
}, SessionConfigJWS<T, MaxAge,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
22
|
-
driver: SessionDriver<
|
|
23
|
-
}): SessionDefinition<T, MaxAge,
|
|
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,
|
|
28
|
-
|
|
29
|
-
}, SessionConfigJWE<T, MaxAge,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
40
|
-
driver: SessionDriver<
|
|
41
|
-
}): SessionDefinition<T, MaxAge,
|
|
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<
|
|
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
|
|
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 };
|
package/dist/session/index.mjs
CHANGED
|
@@ -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: (
|
|
51
|
-
if (isHanded(
|
|
52
|
-
if (
|
|
53
|
-
return sessionsOf(
|
|
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: (
|
|
56
|
-
cookies: (
|
|
57
|
-
handed: (
|
|
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(
|
|
60
|
-
if ("req" in
|
|
61
|
-
if ("token" in
|
|
62
|
-
throw invalidConfigError(`${PREFIX} use() got neither a request event
|
|
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(
|
|
65
|
-
|
|
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(
|
|
68
|
-
const headers =
|
|
69
|
-
if (typeof headers === "object" && headers !== null && "get" in headers) return
|
|
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: (
|
|
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: (
|
|
103
|
+
hookArgs: (event) => ({ event }),
|
|
102
104
|
codec: createJWECodec({
|
|
103
105
|
prefix: driver.prefix,
|
|
104
106
|
defaultName: "unjwt-jwe"
|