auth/session_cookie.ts

Generic session management for cookie-based auth.

Parameterized on identity type via SessionOptions<TIdentity>. Handles signing, expiration, and key rotation. Apps provide encode/decode for their specific identity format.

Cookie value format: ${encode(identity)}:${expires_at} (signed with HMAC-SHA256).

view source

Declarations
#

11 declarations

create_session_config
#

auth/session_cookie.ts view source

(cookie_name: string): SessionOptions<string> import {create_session_config} from '@fuzdev/fuz_app/auth/session_cookie.js';

Create a session config for raw session token identity.

The standard pattern: cookie stores the raw session token, server hashes it (blake3) to look up the auth_session row. Only the cookie_name varies per app.

cookie_name

cookie name (e.g. 'zap_session', 'visiones_session')

type string

returns

SessionOptions<string>

a SessionOptions<string> ready for use with session middleware

create_session_cookie_value
#

fuz_session_config
#

auth/session_cookie.ts view source

SessionOptions<string> import {fuz_session_config} from '@fuzdev/fuz_app/auth/session_cookie.js';

Canonical session config for fuz_app auth.

parse_session
#

auth/session_cookie.ts view source

<TIdentity>(signed_value: string | undefined, keyring: Keyring, options: SessionOptions<TIdentity>, now_seconds?: number | undefined): Promise<ParsedSession<...> | null | undefined> import {parse_session} from '@fuzdev/fuz_app/auth/session_cookie.js';

Parse a signed session cookie value.

The signed value format is ${encode(identity)}:${expires_at}. Tries all keys in order to support key rotation.

signed_value

the raw cookie value (signed)

type string | undefined

keyring

key ring for verification

type Keyring

options

session configuration with decode logic

type SessionOptions<TIdentity>

now_seconds?

current time in seconds (for testing)

type number | undefined
optional

returns

Promise<ParsedSession<TIdentity> | null | undefined>

ParsedSession if valid, null if invalid/expired, undefined if empty/missing

generics

parse_session<TIdentity>
TIdentity

ParsedSession
#

auth/session_cookie.ts view source

ParsedSession<TIdentity> import type {ParsedSession} from '@fuzdev/fuz_app/auth/session_cookie.js';

Result of parsing a signed session cookie.

generics

ParsedSession<TIdentity>
TIdentity

identity

The decoded identity.

type TIdentity

key_index

Index of the key that verified the signature (0 = primary).

type number

process_session_cookie
#

ProcessSessionResult
#

auth/session_cookie.ts view source

ProcessSessionResult<TIdentity> import type {ProcessSessionResult} from '@fuzdev/fuz_app/auth/session_cookie.js';

Result of processing a session cookie.

generics

ProcessSessionResult<TIdentity>
TIdentity

valid

Whether the session is valid.

type boolean

action

Action the adapter should take.

type 'none' | 'clear'

identity?

The decoded identity if the cookie was valid.

type TIdentity

SESSION_AGE_MAX
#

auth/session_cookie.ts view source

number import {SESSION_AGE_MAX} from '@fuzdev/fuz_app/auth/session_cookie.js';

Cookie max age in seconds (30 days — aligned with AUTH_SESSION_LIFETIME_MS).

This is an absolute session lifetime: the cookie is signed once at mint (expires_at = mint + max_age) and never re-signed, matching the DB row's fixed expires_at. There is deliberately no sliding renewal on either leg — see docs/security.md §Session Security.

session_cookie_options
#

SessionCookieOptions
#

auth/session_cookie.ts view source

SessionCookieOptions import type {SessionCookieOptions} from '@fuzdev/fuz_app/auth/session_cookie.js';

Cookie options for session cookies.

path

type string

httpOnly

type boolean

secure

type boolean

sameSite

type 'strict' | 'lax' | 'none'

maxAge

type number

SessionOptions
#

auth/session_cookie.ts view source

SessionOptions<TIdentity> import type {SessionOptions} from '@fuzdev/fuz_app/auth/session_cookie.js';

Configuration for a session cookie format.

Apps provide encode/decode to control the identity portion of the cookie payload.

The TIdentity type parameter determines the trust model:

  • string (e.g. a session_id) — the cookie references a server-side session record, enabling per-session revocation and metadata. Use when you need admin controls like "revoke all sessions" or per-session audit trails.
  • number (e.g. an account_id) — the cookie directly encodes the user identity, requiring no server-side session state. Simpler, but individual sessions can only be invalidated by rotating the signing key (which invalidates all sessions).

generics

SessionOptions<TIdentity>
TIdentity

examples

// zap: 3-part format (admin:session_id) const zap_config: SessionOptions<string> = { cookie_name: 'zap_session', context_key: 'auth_session_id', encode_identity: (session_id) => `admin:${session_id}`, decode_identity: (payload) => { const parts = payload.split(':'); if (parts.length !== 2 || parts[0] !== 'admin') return null; return parts[1] || null; }, }; // visiones: 1-part format (account_id) const visiones_config: SessionOptions<number> = { cookie_name: 'session_id', context_key: 'auth_session_id', encode_identity: (id) => String(id), decode_identity: (payload) => { const n = parseInt(payload, 10); return Number.isFinite(n) && n > 0 ? n : null; }, };

cookie_name

type string

context_key

Hono context variable name for the identity.

type string

max_age?

Cookie lifetime in seconds. Single source of truth for both the embedded expires_at (via create_session_cookie_value) and the cookie's HTTP Max-Age attribute (via set_session_cookie). Defaults to SESSION_AGE_MAX (30 days). The cookie_options slot intentionally cannot carry maxAge so the two values can't drift.

type number

cookie_options?

type Partial<Omit<SessionCookieOptions, 'maxAge'>>

encode_identity

Encode identity into the cookie payload (before the :expires_at suffix).

type (identity: TIdentity) => string

decode_identity

Decode identity from cookie payload. Return null if invalid.

type (payload: string) => TIdentity | null

Depends on
#

Imported by
#