/** * The sealed cookie carries only what `verify()` reads back — the sid * is the store lookup key; everything else about the session (userId, * claims, freshAt, …) lives server-side in the {@link SessionRecord} * so it can never go stale inside an already-issued cookie. * * @typedef {object} SessionTokenPayload * @property {string} sid Server-side session ID (opaque, from CSPRNG). * @property {number} iat Issued-at (ms epoch). * @property {number} exp Absolute expiry (ms epoch). * @property {string} [fp] Fingerprint hash (IP + UA), when `bindTo` is enabled. * @property {string} [imp] Admin user ID that started the impersonation. */ /** * Generate a fresh session ID — 128 bits of CSPRNG entropy, base64url. * Comfortably beyond the birthday-collision bound for any realistic * user base. * * @returns {string} */ export function generateSessionId(): string; /** * Encode a session payload as a sealed (AES-256-GCM authenticated) * opaque token. Wraps `@exortek/crypto.seal` — the TTL of the seal * matches the payload's own `exp - now`, so the transport layer refuses * to open an expired token before we even parse it. * * @param {SessionTokenPayload} payload * @param {string | Buffer | Uint8Array} secret * @param {{ now?: number }} [options] * @returns {string} base64url token. */ export function encodeToken(payload: SessionTokenPayload, secret: string | Buffer | Uint8Array, options?: { now?: number; }): string; /** * Decode + authenticate a session token. Returns the payload on * success, or a structured failure via {@link SessionError}. Callers * generally want to catch and translate to `null` — the manager does * this so `verify(req)` never throws for a wrong-shape stored value. * * `secret` may be a single key or an array `[newest, …older]` for * secret rotation. `crypto.unseal` walks the list; the first that * authenticates wins. * * @param {string} token * @param {string | Buffer | Uint8Array | Array} secret * @param {{ now?: number }} [options] * @returns {SessionTokenPayload} * @throws {SessionError} — with `INVALID_TOKEN` / `EXPIRED` / `INVALID_ARGUMENT`. */ export function decodeToken(token: string, secret: string | Buffer | Uint8Array | Array, options?: { now?: number; }): SessionTokenPayload; /** * The sealed cookie carries only what `verify()` reads back — the sid * is the store lookup key; everything else about the session (userId, * claims, freshAt, …) lives server-side in the {@link SessionRecord} * so it can never go stale inside an already-issued cookie. */ export type SessionTokenPayload = { /** * Server-side session ID (opaque, from CSPRNG). */ sid: string; /** * Issued-at (ms epoch). */ iat: number; /** * Absolute expiry (ms epoch). */ exp: number; /** * Fingerprint hash (IP + UA), when `bindTo` is enabled. */ fp?: string | undefined; /** * Admin user ID that started the impersonation. */ imp?: string | undefined; };