/**
 * Brute Force Protection System
 *
 * Provides comprehensive protection against brute force login attacks.
 * Features include:
 * - Redis-backed distributed attempt tracking
 * - Progressive lockout with configurable escalation
 * - IP-based rate limiting
 * - CAPTCHA triggering after threshold attempts
 * - Automatic cleanup of stale records
 * - Admin unlock capabilities with audit logging
 *
 * @packageDocumentation
 * @module security/brute-force
 */
import type { FastifyRequest, preHandlerHookHandler } from 'fastify';
import type { Redis } from 'ioredis';
/**
 * Configuration options for brute force protection
 */
export interface BruteForceConfig {
    /**
     * Maximum number of failed login attempts before lockout
     * @default 5
     */
    maxAttempts: number;
    /**
     * Time window in minutes to track failed attempts
     * @default 15
     */
    windowMinutes: number;
    /**
     * Base lockout duration in minutes
     * @default 30
     */
    lockoutMinutes: number;
    /**
     * Whether to double lockout duration for each subsequent lockout
     * @default true
     */
    progressiveLockout: boolean;
    /**
     * Maximum lockout duration in minutes (24 hours)
     * @default 1440
     */
    maxLockoutMinutes: number;
    /**
     * Whether to emit notification events on lockout
     * @default true
     */
    notifyOnLockout: boolean;
    /**
     * Number of failed attempts after which CAPTCHA is required
     * @default 3
     */
    captchaAfterAttempts: number;
    /**
     * Whether to enable IP-based rate limiting
     * @default true
     */
    ipRateLimiting: boolean;
    /**
     * Maximum attempts per IP address per hour
     * @default 100
     */
    ipMaxAttempts: number;
    /**
     * Whether to track attempts by username
     * @default true
     */
    trackByUsername: boolean;
    /**
     * Whether to track attempts by IP address
     * @default true
     */
    trackByIP: boolean;
}
/**
 * Represents a single login attempt
 */
export interface LoginAttempt {
    /** User ID if known (for authenticated attempts) */
    userId?: string;
    /** Username used in the login attempt */
    username?: string;
    /** IP address of the client */
    ipAddress: string;
    /** User agent string from the request */
    userAgent: string;
    /** Timestamp of the attempt */
    timestamp: Date;
    /** Whether the login was successful */
    success: boolean;
    /** Reason for failure if unsuccessful */
    failureReason?: string;
}
/**
 * Current lockout status for an identifier
 */
export interface LockoutStatus {
    /** Whether the account/IP is currently locked out */
    locked: boolean;
    /** Number of remaining attempts before lockout */
    remainingAttempts: number;
    /** When the lockout will end (if locked) */
    lockoutEndsAt?: Date;
    /** Total number of times this identifier has been locked out */
    lockoutCount: number;
    /** Whether CAPTCHA verification is required */
    requiresCaptcha: boolean;
}
/**
 * Lockout notification event
 */
export interface LockoutEvent {
    /** Type of event */
    type: 'lockout' | 'unlock' | 'ip_blocked';
    /** Identifier that was locked/unlocked */
    identifier: string;
    /** IP address if applicable */
    ipAddress?: string;
    /** Username if applicable */
    username?: string;
    /** When the lockout started */
    lockedAt: Date;
    /** When the lockout ends */
    lockoutEndsAt?: Date;
    /** Number of failed attempts that triggered lockout */
    failedAttempts: number;
    /** Total lockout count for this identifier */
    lockoutCount: number;
    /** Reason for unlock if manually unlocked */
    unlockReason?: string;
    /** Admin ID who performed unlock if applicable */
    adminId?: string;
}
/**
 * Callback for lockout events
 */
export type LockoutEventCallback = (event: LockoutEvent) => void | Promise<void>;
/**
 * Default brute force protection configuration
 */
export declare const DEFAULT_BRUTE_FORCE_CONFIG: BruteForceConfig;
/**
 * Brute Force Protection Service
 *
 * Provides comprehensive protection against brute force attacks
 * with Redis-backed distributed tracking.
 *
 * @example
 * ```typescript
 * const protection = new BruteForceProtection({
 *   maxAttempts: 5,
 *   windowMinutes: 15,
 *   lockoutMinutes: 30,
 * });
 *
 * // Record a failed attempt
 * await protection.recordAttempt({
 *   username: 'user@example.com',
 *   ipAddress: '192.168.1.1',
 *   userAgent: 'Mozilla/5.0...',
 *   timestamp: new Date(),
 *   success: false,
 *   failureReason: 'invalid_password',
 * });
 *
 * // Check lockout status before login
 * const status = await protection.isLockedOut('user@example.com');
 * if (status.locked) {
 *   console.log('Account locked until:', status.lockoutEndsAt);
 * }
 * ```
 */
export declare class BruteForceProtection {
    private readonly config;
    private readonly redis;
    private readonly eventCallbacks;
    /**
     * Creates a new BruteForceProtection instance
     *
     * @param config - Configuration options
     * @param redis - Optional Redis instance (uses shared instance if not provided)
     */
    constructor(config?: Partial<BruteForceConfig>, redis?: Redis);
    /**
     * Registers a callback for lockout events
     *
     * @param callback - Function to call when lockout events occur
     */
    onLockoutEvent(callback: LockoutEventCallback): void;
    /**
     * Emits a lockout event to all registered callbacks
     *
     * @param event - The lockout event to emit
     */
    private emitEvent;
    /**
     * Records a login attempt and updates protection state
     *
     * @param attempt - The login attempt to record
     */
    recordAttempt(attempt: LoginAttempt): Promise<void>;
    /**
     * Records an attempt for a specific identifier
     */
    private recordAttemptForIdentifier;
    /**
     * Records an IP rate limit attempt
     */
    private recordIPAttempt;
    /**
     * Checks if lockout should be triggered and triggers it if necessary
     */
    private checkAndTriggerLockout;
    /**
     * Triggers a lockout for an identifier
     */
    private triggerLockout;
    /**
     * Gets the count of failed attempts for an identifier
     */
    private getFailedAttemptCount;
    /**
     * Clears attempts for an identifier (e.g., after successful login)
     */
    private clearAttempts;
    /**
     * Checks the lockout status for an identifier
     *
     * @param identifier - Username or IP-prefixed string to check
     * @returns Current lockout status
     */
    isLockedOut(identifier: string): Promise<LockoutStatus>;
    /**
     * Checks if an IP address is blocked due to rate limiting
     *
     * @param ip - IP address to check
     * @returns Whether the IP is blocked
     */
    isIPBlocked(ip: string): Promise<boolean>;
    /**
     * Gets the remaining attempts before lockout for an identifier
     *
     * @param identifier - Username or IP to check
     * @returns Number of remaining attempts
     */
    getRemainingAttempts(identifier: string): Promise<number>;
    /**
     * Manually unlocks an account (admin action)
     *
     * @param identifier - Username or IP to unlock
     * @param reason - Reason for the unlock
     * @param adminId - ID of the admin performing the unlock
     */
    unlockAccount(identifier: string, reason: string, adminId: string): Promise<void>;
    /**
     * Checks if CAPTCHA is required for an identifier
     *
     * @param identifier - Username or IP to check
     * @returns Whether CAPTCHA is required
     */
    requiresCaptcha(identifier: string): Promise<boolean>;
    /**
     * Gets recent login attempts for an identifier
     *
     * @param identifier - Username or IP to get attempts for
     * @param minutes - Time window in minutes
     * @returns Array of recent login attempts
     */
    getRecentAttempts(identifier: string, minutes: number): Promise<LoginAttempt[]>;
    /**
     * Cleans up old records to prevent unbounded storage growth
     *
     * This should be called periodically (e.g., via cron job)
     */
    cleanup(): Promise<void>;
    /**
     * Gets the current configuration
     *
     * @returns Current brute force configuration
     */
    getConfig(): BruteForceConfig;
}
/**
 * Options for the brute force middleware
 */
export interface BruteForceMiddlewareOptions {
    /** Brute force protection instance */
    protection?: BruteForceProtection;
    /** Brute force configuration (if not providing protection instance) */
    config?: Partial<BruteForceConfig>;
    /** Paths to skip protection for */
    skipPaths?: string[];
    /** Function to extract username from request */
    extractUsername?: (request: FastifyRequest) => string | undefined;
    /** Function to extract user ID from request */
    extractUserId?: (request: FastifyRequest) => string | undefined;
    /** Whether to check IP blocking */
    checkIPBlocking?: boolean;
    /** Whether to check account lockout */
    checkAccountLockout?: boolean;
    /** Custom response for locked accounts */
    lockedResponse?: (status: LockoutStatus) => {
        statusCode: number;
        body: Record<string, unknown>;
    };
    /** Custom response for blocked IPs */
    ipBlockedResponse?: () => {
        statusCode: number;
        body: Record<string, unknown>;
    };
}
/**
 * Creates Fastify middleware for brute force protection
 *
 * @param options - Middleware options
 * @returns Fastify preHandler hook
 *
 * @example
 * ```typescript
 * const bruteForceMiddleware = createBruteForceMiddleware({
 *   config: {
 *     maxAttempts: 5,
 *     lockoutMinutes: 30,
 *   },
 *   skipPaths: ['/health', '/metrics'],
 *   extractUsername: (req) => req.body?.email,
 * });
 *
 * fastify.addHook('preHandler', bruteForceMiddleware);
 * ```
 */
export declare function createBruteForceMiddleware(options?: BruteForceMiddlewareOptions): preHandlerHookHandler;
/**
 * Creates a post-authentication hook to record login attempts
 *
 * @param protection - BruteForceProtection instance
 * @param options - Hook options
 * @returns Function to record attempt
 *
 * @example
 * ```typescript
 * const recordAttempt = createRecordAttemptHook(protection);
 *
 * // In your login handler:
 * try {
 *   const user = await authenticate(username, password);
 *   await recordAttempt(request, true);
 *   return { success: true, user };
 * } catch (error) {
 *   await recordAttempt(request, false, error.message);
 *   throw error;
 * }
 * ```
 */
export declare function createRecordAttemptHook(protection: BruteForceProtection, options?: {
    extractUsername?: (request: FastifyRequest) => string | undefined;
    extractUserId?: (request: FastifyRequest) => string | undefined;
}): (request: FastifyRequest, success: boolean, failureReason?: string) => Promise<void>;
declare module 'fastify' {
    interface FastifyRequest {
        bruteForceStatus?: LockoutStatus;
    }
}
/**
 * Gets or creates the singleton BruteForceProtection instance
 *
 * @param config - Optional configuration (only used on first call)
 * @returns The singleton BruteForceProtection instance
 *
 * @example
 * ```typescript
 * // Initialize with custom config
 * const protection = getBruteForceProtection({
 *   maxAttempts: 3,
 *   lockoutMinutes: 60,
 * });
 *
 * // Later, get the same instance
 * const sameProtection = getBruteForceProtection();
 * ```
 */
export declare function getBruteForceProtection(config?: Partial<BruteForceConfig>): BruteForceProtection;
/**
 * Resets the singleton instance (primarily for testing)
 */
export declare function resetBruteForceProtection(): void;
//# sourceMappingURL=brute-force.d.ts.map