/**
 * 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).
 *
 * @module
 */
import type { Keyring } from './keyring.js';
/** Cookie max age in seconds (30 days — aligned with AUTH_SESSION_LIFETIME_MS). */
export declare const SESSION_AGE_MAX: number;
/**
 * Threshold (seconds) at which `process_session_cookie` re-signs a still-valid
 * cookie to extend its embedded expiration. Mirrors the DB-side
 * `AUTH_SESSION_EXTEND_THRESHOLD_MS` so a continuously-active user's cookie
 * stays in sync with their server-side session lifetime. Set
 * `SessionOptions.refresh_threshold_seconds = 0` to disable.
 */
export declare const SESSION_REFRESH_THRESHOLD_S: number;
/**
 * Cookie options for session cookies.
 */
export interface SessionCookieOptions {
    path: string;
    httpOnly: boolean;
    secure: boolean;
    sameSite: 'strict' | 'lax' | 'none';
    maxAge: number;
}
/**
 * Default cookie options for session cookies.
 *
 * Uses strict security settings:
 * - `secure: true` - Works on localhost in Chrome/Firefox (treated as secure context)
 * - `sameSite: 'strict'` - Prevents CSRF
 * - `httpOnly: true` - Prevents XSS access to cookie
 */
export declare const session_cookie_options: SessionCookieOptions;
/**
 * 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).
 *
 * @example
 * ```ts
 * // 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;
 *   },
 * };
 * ```
 */
export interface SessionOptions<TIdentity> {
    cookie_name: string;
    /** Hono context variable name for the identity. */
    context_key: string;
    /**
     * 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.
     */
    max_age?: number;
    /**
     * Threshold (seconds) for expiration-based cookie refresh. When a parsed
     * cookie's `expires_at - now <= refresh_threshold_seconds`,
     * `process_session_cookie` returns `action: 'refresh'` with a freshly-signed
     * value (extending the embedded expiration by `max_age`). Defaults to
     * `SESSION_REFRESH_THRESHOLD_S` (1 day). Set to `0` to disable.
     */
    refresh_threshold_seconds?: number;
    cookie_options?: Partial<Omit<SessionCookieOptions, 'maxAge'>>;
    /** Encode identity into the cookie payload (before the `:expires_at` suffix). */
    encode_identity: (identity: TIdentity) => string;
    /** Decode identity from cookie payload. Return null if invalid. */
    decode_identity: (payload: string) => TIdentity | null;
}
/**
 * Result of parsing a signed session cookie.
 */
export interface ParsedSession<TIdentity> {
    /** The decoded identity. */
    identity: TIdentity;
    /** True if verified with a non-primary key (needs re-signing). */
    should_refresh_signature: boolean;
    /**
     * True if the embedded `expires_at` is within
     * `options.refresh_threshold_seconds` of `now`. Signals that the cookie is
     * valid but should be re-signed to extend its lifetime — mirrors
     * `query_session_touch`'s DB-side extension so the cookie and server
     * session don't drift. Always false when the threshold is `0`.
     */
    should_refresh_expiration: boolean;
    /** Index of the key that verified the signature. */
    key_index: number;
}
/**
 * Parse a signed session cookie value.
 *
 * The signed value format is `${encode(identity)}:${expires_at}`.
 * Tries all keys in order to support key rotation. The result's
 * `should_refresh_expiration` flag fires when the cookie is within
 * `options.refresh_threshold_seconds` of `expires_at`.
 *
 * @param signed_value - the raw cookie value (signed)
 * @param keyring - key ring for verification
 * @param options - session configuration with decode logic
 * @param now_seconds - current time in seconds (for testing)
 * @returns `ParsedSession` if valid, null if invalid/expired, undefined if empty/missing
 */
export declare const parse_session: <TIdentity>(signed_value: string | undefined, keyring: Keyring, options: SessionOptions<TIdentity>, now_seconds?: number) => Promise<ParsedSession<TIdentity> | null | undefined>;
/**
 * Create a signed session cookie value.
 *
 * Format: `${encode(identity)}:${expires_at}` signed with HMAC-SHA256.
 * Embeds expiration in the signed value itself for defense-in-depth.
 *
 * @param keyring - key ring for signing
 * @param identity - the identity to encode
 * @param options - session configuration with encode logic
 * @param now_seconds - current time in seconds (for testing)
 * @returns signed cookie value string
 */
export declare const create_session_cookie_value: <TIdentity>(keyring: Keyring, identity: TIdentity, options: SessionOptions<TIdentity>, now_seconds?: number) => Promise<string>;
/**
 * Result of processing a session cookie.
 */
export interface ProcessSessionResult<TIdentity> {
    /** Whether the session is valid. */
    valid: boolean;
    /** Action the adapter should take. */
    action: 'none' | 'clear' | 'refresh';
    /** New signed value when action is 'refresh'. */
    new_signed_value?: string;
    /** The decoded identity if the cookie was valid. */
    identity?: TIdentity;
}
/**
 * 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.
 *
 * @param cookie_name - cookie name (e.g. `'zap_session'`, `'visiones_session'`)
 * @returns a `SessionOptions<string>` ready for use with session middleware
 */
export declare const create_session_config: (cookie_name: string) => SessionOptions<string>;
/** Canonical session config for fuz_app auth. */
export declare const fuz_session_config: SessionOptions<string>;
/**
 * Process a session cookie and determine what action to take.
 *
 * `action: 'refresh'` fires on key rotation **or** impending expiration
 * (within `options.refresh_threshold_seconds`); both produce a freshly-signed
 * `new_signed_value`.
 *
 * @param signed_value - the raw cookie value (may be undefined)
 * @param keyring - key ring for verification and signing
 * @param options - session configuration
 * @param now_seconds - current time in seconds (for testing)
 * @returns result with validity and action to take
 */
export declare const process_session_cookie: <TIdentity>(signed_value: string | undefined, keyring: Keyring, options: SessionOptions<TIdentity>, now_seconds?: number) => Promise<ProcessSessionResult<TIdentity>>;
//# sourceMappingURL=session_cookie.d.ts.map