import type { Cookies } from '@sveltejs/kit'; import type { AuthConfig, JwtConfig, RefreshTokenConfig } from '../types.js'; import type { FullAuthUser, RefreshTokenRecord, RefreshTokenRepository } from './adapters/types.js'; /** * Resolve the effective JWT config when refresh-token rotation is opted in: * shortens the access-token TTL to `refreshToken.accessTokenTtl` (default 15m) * unless the caller has explicitly overridden `jwt.expiresIn`. */ export declare function resolveJwtConfig(config: AuthConfig): JwtConfig; export declare function refreshCookieName(config: RefreshTokenConfig): string; /** * Optional per-session metadata captured at issue time and carried forward * across rotations — surfaced by the session-listing feature so a user can * tell their devices apart. `ip` is only populated when the consumer opts in * via `config.sessions.storeIp`. */ export interface SessionMeta { userAgent?: string; ip?: string; } /** * Issue a brand-new refresh token (new family). Called from login / register / * passkey-auth after the access-token cookie has been set. Returns the raw * token so callers can write it to the cookie themselves — the hash is the * only thing stored server-side. `meta` (user-agent / ip) is persisted on the * row for session listing and is backward-compatible — omit it for the prior * behaviour. */ export declare function issueRefreshToken(repo: RefreshTokenRepository, userId: string, config: RefreshTokenConfig, meta?: SessionMeta): Promise<{ token: string; record: RefreshTokenRecord; }>; export declare function setRefreshCookie(cookies: Cookies, token: string, config: RefreshTokenConfig): void; export declare function clearRefreshCookie(cookies: Cookies, config: RefreshTokenConfig): void; export declare function readRefreshCookie(cookies: Cookies, config: RefreshTokenConfig): string | null; export type RotateOutcome = { kind: 'rotated'; user: FullAuthUser; token: string; record: RefreshTokenRecord; } | { kind: 'race_ok'; user: FullAuthUser; } | { kind: 'reused'; userId: string; } | { kind: 'expired'; } | { kind: 'revoked'; } | { kind: 'not_found'; }; /** * Validate a refresh token and — if it's the current one in its family — * rotate it. Any of the following invalidate the attempt: * * - token not found → `not_found` * - token already revoked, outside grace → `reused` (full family is revoked) * - token already revoked, inside grace + has successor + family still live * → `race_ok` (concurrent rotation) * - token already revoked, family dead → `reused` (a killed family has no race to lose) * - token past `expiresAt` → `expired` * * On success the old token is marked revoked with `replacedById` pointing at * the newly-issued successor, and both the raw token and its DB record are * returned so the caller can set the new cookie. * * Callers are responsible for (a) reading the user with `findUserById` and * passing it in, (b) clearing the cookie on any failure outcome, and (c) * setting the new cookie on `rotated`. On `race_ok`, callers should re-issue * the access token but leave the refresh cookie untouched — the winner of * the race has already written the successor cookie to the same browser jar. */ export declare function rotateRefreshToken(repo: RefreshTokenRepository, rawToken: string, findUser: (userId: string) => Promise | null>, config: RefreshTokenConfig): Promise>; /** * Revoke the refresh token sitting in the request cookie (if any). Used by * logout to invalidate the current device's token without touching other * active sessions. No-ops when the cookie is absent or the DB row is missing. * * Replay of an already-revoked token at `/logout` is treated the same as at * the rotation path: the whole family is revoked (someone with a stolen copy * is presenting it, the stolen-token threat model applies). */ export declare function revokeRefreshFromCookie(cookies: Cookies, repo: RefreshTokenRepository, config: RefreshTokenConfig): Promise;