/**
 * Login throttling.
 *
 * The dashboard's login is internet-facing, and it is the door to a box that
 * hosts other people's sites. scrypt makes each guess cost ~50ms, which slows
 * an attacker but does not stop one — and while generated passwords are strong,
 * an operator can set their own via `TS_CLOUD_UI_PASSWORD`.
 *
 * Failures are counted per key (username + client address) and lock that key
 * out for a window once they pass a threshold. In-memory on purpose: the
 * dashboard is a single process per box, and a restart clearing the counters is
 * an acceptable trade for having no store to keep.
 *
 * Keyed on username *and* address so one attacker cannot lock a legitimate
 * operator out of their own box by failing logins against their username
 * (a denial of service dressed up as a security control).
 */
/** Failures before a key is locked out. */
export declare const MAX_ATTEMPTS: number;
/** How long a locked key stays locked. */
export declare const LOCKOUT_MS: number;
/** Failures older than this stop counting, so occasional typos never lock. */
export declare const WINDOW_MS: number;
export interface ThrottleDecision {
    allowed: boolean;
    /** Seconds until the caller may try again. Only set when blocked. */
    retryAfterSeconds?: number;
}
export declare class LoginThrottle {
    private readonly maxAttempts;
    private readonly lockoutMs;
    private readonly windowMs;
    private attempts;
    constructor(maxAttempts?: number, lockoutMs?: number, windowMs?: number);
    private key;
    /** Whether a login attempt for this key may proceed. */
    check(username: string, address: string, now?: number): ThrottleDecision;
    /** Record a failed attempt, locking the key once it passes the threshold. */
    recordFailure(username: string, address: string, now?: number): void;
    /** Clear the counter for a key after a successful login. */
    recordSuccess(username: string, address: string): void;
    /** Drop expired entries so the map cannot grow without bound. */
    prune(now?: number): void;
    /** Tracked keys. For tests and diagnostics. */
    get size(): number;
}
