/** * @module @arcis/node/middleware/brute-force * * Brute-force protection middleware built on the bursty limiter * primitive. Designed for login + password-reset endpoints where the * defense isn't just "X requests per minute" but "if this IP keeps * trying after the rate-limit window resets, block it for longer". * * Two-tier semantics: * - Steady-state: `fastPoints` consumes per `fastDuration` seconds. * Once exhausted, normal traffic gets a 429 until the window * resets. * - Brute-force: `slowPoints` failed attempts over `slowDuration` * seconds trips a `blockDuration` semi-permanent block. * * The middleware only consumes on `next()` by default, meaning every * request counts, even successful ones. Pass `{ consumeOn: 'failure' }` * plus a custom `failure` predicate to count only failed responses. * The handler also exposes `req.arcisBruteForce.reward(key)` / `.delete(key)` * to let the application reset counters on successful login. */ import type { Request, RequestHandler } from 'express'; import type { IRateLimiterRes } from '../_third_party/rate-limit'; export interface BruteForceOptions { /** Points allowed in the fast window. */ fastPoints?: number; /** Fast window length in seconds. */ fastDuration?: number; /** Points allowed in the slow window. */ slowPoints?: number; /** Slow window length in seconds. */ slowDuration?: number; /** Seconds to semi-permanently block a key after slow-window exhaustion. */ blockDuration?: number; /** Custom key resolver. Defaults to client IP. */ keyGenerator?: (req: Request) => string; /** HTTP status to return when blocked. */ statusCode?: number; /** Response message when blocked. */ message?: string; /** Skip predicate. Return true to bypass the limiter for this request. */ skip?: (req: Request) => boolean; } export interface BruteForceController { /** Reset the failure counter for a key (call after successful auth). */ reward(key: string, points?: number): Promise; /** Drop the key entirely. */ delete(key: string): Promise; /** Inspect the current counter without consuming. */ get(key: string): Promise; /** Manually trip the block (e.g. after N suspicious logins). */ block(key: string, secDuration: number): Promise; } declare global { namespace Express { interface Request { arcisBruteForce?: BruteForceController; } } } /** * Build a brute-force middleware backed by a bursty limiter. The * returned function is an Express RequestHandler with a `controller` * property exposing reward/delete/get/block for the application layer. */ export declare function bruteForceProtection(options?: BruteForceOptions): RequestHandler & { controller: BruteForceController; }; //# sourceMappingURL=brute-force.d.ts.map