import type { AuthConfig, LockoutConfig, RateLimitConfig } from '../types.js'; import type { FailedLoginLock } from './adapters/types.js'; /** * Every key `AuthConfig.rateLimit` declares, derived from the interface rather * than listed again. {@link RATE_LIMIT_DEFAULTS} is typed `Record`, so adding a key in `types.ts` without a default is a compile error — * which is the whole point: the previous hand-maintained list had drifted to * cover 5 of 12 keys, and nothing reported the gap. */ export type RateLimitKey = keyof NonNullable; /** * The per-key brute-force defaults. Complete by construction (see * {@link RateLimitKey}) and applied through {@link rateLimitFor}, so no entry * point can carry a config that is missing one. */ export declare const RATE_LIMIT_DEFAULTS: Record; /** * Account-lockout policy applied when the consumer engaged with brute-force * config not at all. Carries a lock-out-DoS trade-off (AUTH.md → Known * Limitations), which is why it is not imposed on a consumer who configured * rate-limiting themselves. * * Also the per-field default for a lockout the consumer configured *partially* * (`{ maxAttempts: 3 }`): {@link lockoutFor} fills every missing field from * here, so nothing downstream — handler or adapter — holds a number of its own. */ export declare const DEFAULT_LOCKOUT: Required; /** * The effective limit for one endpoint. Handlers read their limit through this * rather than off `config.rateLimit` directly, so a hand-built `AuthDeps` — an * exported type the package explicitly expects consumers to build * (`establishSession`'s defense-in-depth note) — gets the same protection as * one from `createAuthDeps`. Before, `resolveSecurityDefaults` ran only inside * `createAuthDeps` and the hand-built path arrived at the login endpoint with * no limiter and no lockout at all. * * `rateLimit: null` is the deliberate opt-out and is honoured here too. */ export declare function rateLimitFor(config: AuthConfig, key: RateLimitKey): RateLimitConfig | undefined; /** * The effective lockout policy, every field resolved. Defaulted only when the * consumer set neither `rateLimit` nor `lockout` — configuring rate-limiting is * engagement with the defense, so an omitted lockout is respected rather than * overridden with the DoS-prone mechanism. */ export declare function lockoutFor(config: AuthConfig): Required | undefined; /** * The lock a failed attempt hands to `recordFailedLogin`: the threshold, and * the instant the account stays locked until once it is reached. Computed here, * from this process's clock, so the adapter compares and stores two values and * owns no duration arithmetic (`AUTH.md` → adapter contract). */ export declare function failedLoginLock(lockout: Required, now?: number): FailedLoginLock; /** * The resolved `rateLimit` slice carried on `AuthDeps.config`: every key either * a limit or `null` (opted out), or `null` for the whole object. * * `null` rather than `undefined` for an opt-out is load-bearing **here**. Every * handler reads the resolved config back through {@link rateLimitFor}, so it has * to be a **fixed point**: normalizing an opt-out to `undefined` would make the * next read say "consumer configured nothing" and re-inject the default — the * opt-out would survive exactly one resolution. * * `lockout` needs no such treatment and keeps `undefined`, because * `resolveRateLimits` never yields `undefined`: {@link lockoutFor}'s defaulting * branch is gated on `config.rateLimit === undefined`, which is unreachable on * an already-resolved config. Measured stable across five successive * resolutions of every input shape. */ export declare function resolveRateLimits(config: AuthConfig): AuthConfig['rateLimit'];