auth/account_routes.ts

Account route specs for cookie-based session management.

Returns RouteSpec[] — caller applies them to Hono via apply_route_specs.

Four REST flows remain here; each has a concrete reason to stay REST rather than moving to auth/account_actions.ts:

- POST /login — issues a signed Set-Cookie and pre-handler rate-limits by IP + per-canonical-account before password hashing. - POST /logout — clears the session cookie. - POST /password — cookie clear + revoke-all cascade; rate-limit-shaped error envelope on 429. - GET /verify — empty-body nginx auth_request probe. Programmatic callers should use the account_verify RPC action for the typed payload.

Session listing/revocation and API token CRUD are on the RPC endpoint — see auth/account_actions.ts. Signup is in auth/signup_routes.ts. Defaults are closed/safe: accounts are created through bootstrap, admin action, or invite.

Declarations
#

18 declarations

view source

AccountRouteOptions
#

auth/account_routes.ts view source

AccountRouteOptions

Per-factory configuration for account route specs.

inheritance

login_account_rate_limiter

Rate limiter for login attempts, keyed by submitted username. Pass null to disable.

type RateLimiter | null

max_sessions

Max active sessions per account. Evicts oldest on login. Default 5, null disables.

type number | null

login_fail_floor_ms

Minimum wall-clock time (ms) for login 401 responses. Set to 0 or a negative number to disable (e.g., in tests). Default DEFAULT_LOGIN_FAIL_FLOOR_MS.

type number

login_fail_jitter_ms

Uniform jitter window (±ms) layered on the floor. Set to 0 to disable jitter while keeping the floor. Default DEFAULT_LOGIN_FAIL_JITTER_MS.

type number

AccountStatusInput
#

AccountStatusOptions
#

auth/account_routes.ts view source

AccountStatusOptions

Options for the account status route spec.

path

Override the default path (/api/account/status).

type string

bootstrap_status

Runtime bootstrap status — when available, 401 responses include bootstrap_available.

type {available: boolean}

AccountStatusOutput
#

auth/account_routes.ts view source

ZodObject<{ account: ZodObject<{ id: $ZodBranded<ZodUUID, "Uuid", "out">; username: ZodString; email: ZodNullable<ZodEmail>; email_verified: ZodBoolean; created_at: ZodString; }, $strict>; actor: ZodNullable<...>; role_grants: ZodArray<...>; }, $strict>

Output for GET /api/account/status on the authenticated path.

account is always populated for authenticated callers. actor and role_grants are populated when the caller's account has a unique actor or the request supplies ?acting=<actor_id>; on multi-actor accounts without an acting query, actor is null and role_grants is empty so the frontend can show a persona picker without a separate roundtrip.

AccountStatusUnauthenticatedError
#

auth/account_routes.ts view source

ZodObject<{ error: ZodLiteral<"authentication_required">; bootstrap_available: ZodOptional<ZodBoolean>; }, $loose>

Error body for GET /api/account/status on the unauthenticated path.

AuthSessionRouteOptions
#

auth/account_routes.ts view source

AuthSessionRouteOptions

Shared options for route factories that create sessions and rate-limit by IP.

Extended by AccountRouteOptions and SignupRouteOptions. Consumers can destructure these from AppServerContext once and spread into multiple factories.

session_options

type SessionOptions<string>

ip_rate_limiter

Rate limiter for auth attempts, keyed by client IP. Pass null to disable.

type RateLimiter | null

create_account_route_specs
#

auth/account_routes.ts view source

(deps: RouteFactoryDeps, options: AccountRouteOptions): RouteSpec[]

Create account route specs for session-based auth.

The returned specs cover the three flows that stay REST after the RPC migration (login, logout, password change). Self-service session/token management and verify are on auth/account_actions.ts.

deps

stateless capabilities (keyring, password, log)

options

per-factory configuration (session_options, ip_rate_limiter, login_account_rate_limiter)

returns

RouteSpec[]

route specs (not yet applied to Hono)

create_account_status_route_spec
#

auth/account_routes.ts view source

(options?: AccountStatusOptions | undefined): RouteSpec

Create the account status route spec.

Handles both authenticated and unauthenticated requests: - Authenticated: returns {account} with 200 - Unauthenticated: returns 401 with optional bootstrap_available flag

This eliminates the need for a separate /health fetch on page load — the frontend gets both session state and bootstrap availability in one request.

options?

optional configuration (bootstrap_status for bootstrap detection)

type AccountStatusOptions | undefined
optional

returns

RouteSpec

a single account status route spec

DEFAULT_LOGIN_FAIL_FLOOR_MS
#

auth/account_routes.ts view source

250

Default minimum wall-clock time (ms) for a login failure (401) response.

Picked to exceed the p99 of every 401 code path (Argon2id dominates at ~100ms, plus DB + overhead). The handler races failure work against sleep(floor + jitter) via await, so observed response time = max(work, delay). Found-vs-not-found and rate-limit-skipped-vs-not paths converge. Only 401 is padded — 429 stays fast by design to keep rate-limit DoS handling cheap.

DEFAULT_LOGIN_FAIL_JITTER_MS
#

auth/account_routes.ts view source

25

Default uniform jitter window (±ms) layered on the floor.

Random jitter prevents a stable clamp point from leaking whenever a path occasionally exceeds the floor. Math.random is sufficient — we only need unpredictability of the exact delay, not cryptographic guarantees.

DEFAULT_MAX_SESSIONS
#

DEFAULT_MAX_TOKENS
#

LoginInput
#

auth/account_routes.ts view source

ZodObject<{ username: ZodString; password: ZodString; }, $strict>

Input for POST /login. Accepts a username or email in the username field.

LoginOutput
#

LogoutInput
#

LogoutOutput
#

auth/account_routes.ts view source

ZodObject<{ ok: ZodLiteral<true>; username: ZodString; }, $strict>

Output for POST /logout. Includes the revoked account's username for UI redraw.

PasswordChangeInput
#

auth/account_routes.ts view source

ZodObject<{ current_password: ZodString; new_password: ZodString; }, $strict>

Input for POST /password. current_password is minimally validated; new_password enforces the full policy.

PasswordChangeOutput
#

auth/account_routes.ts view source

ZodObject<{ ok: ZodLiteral<true>; sessions_revoked: ZodNumber; tokens_revoked: ZodNumber; }, $strict>

Output for POST /password. Counts are returned so the UI can summarize the revoke-all cascade.

Depends on
#

Imported by
#