/**
 * Bot Detection Service
 *
 * Advanced bot detection for threat protection. Analyzes HTTP requests
 * using multiple detection signals to determine if a request originates
 * from a human or automated client.
 *
 * Detection signals:
 * - Missing/suspicious headers (Accept-Language, Accept-Encoding)
 * - User-Agent analysis (known bots, headless browsers)
 * - Header order anomalies (browsers have consistent order)
 * - TLS fingerprint anomalies (JA3 hash if available)
 * - Request timing patterns (too fast = bot)
 * - Missing cookies on return visits
 * - JavaScript challenge results
 *
 * @packageDocumentation
 * @module security/threat-intel/bot-detection
 */
import type { FastifyInstance, FastifyRequest, preHandlerHookHandler } from 'fastify';
/**
 * Bot detection signal types
 */
export type BotSignalType = 'missing_accept_language' | 'missing_accept_encoding' | 'suspicious_user_agent' | 'known_bad_bot' | 'known_good_bot' | 'headless_browser' | 'header_order_anomaly' | 'tls_fingerprint_anomaly' | 'request_too_fast' | 'missing_cookies_return_visit' | 'js_challenge_failed' | 'js_challenge_passed' | 'missing_referer_on_post' | 'unusual_header_combination' | 'connection_reuse_pattern' | 'missing_sec_headers' | 'suspicious_accept_header';
/**
 * Individual bot detection signal
 */
export interface BotSignal {
    /** Signal type identifier */
    type: BotSignalType;
    /** Human-readable description */
    description: string;
    /** Score adjustment (-100 to +100) */
    scoreAdjustment: number;
    /** Confidence in this signal (0-1) */
    confidence: number;
    /** Additional metadata */
    metadata?: Record<string, unknown>;
}
/**
 * Bot score recommendation
 */
export type BotRecommendation = 'allow' | 'challenge' | 'block';
/**
 * Complete bot detection score result
 */
export interface BotScore {
    /** Final score 0-100 (0 = definitely bot, 100 = definitely human) */
    score: number;
    /** All signals that contributed to the score */
    signals: BotSignal[];
    /** Device/request fingerprint */
    fingerprint: string;
    /** Recommended action */
    recommendation: BotRecommendation;
    /** Whether this is a known good bot (e.g., Googlebot) */
    isKnownGoodBot: boolean;
    /** Whether this is a known bad bot */
    isKnownBadBot: boolean;
    /** Analysis timestamp */
    analyzedAt: Date;
    /** Analysis duration in ms */
    analysisMs: number;
}
/**
 * Bot detection configuration
 */
export interface BotDetectionConfig {
    /** Whether bot detection is enabled */
    enabled: boolean;
    /** Score threshold below which requests are blocked (default: 20) */
    blockThreshold: number;
    /** Score threshold below which requests are challenged (default: 50) */
    challengeThreshold: number;
    /** List of allowed good bots (override built-in) */
    allowedBots: string[];
    /** List of blocked bad bots (override built-in) */
    blockedBots: string[];
    /** Cache TTL in milliseconds (default: 5 minutes) */
    cacheTTLMs: number;
    /** Maximum cache size */
    maxCacheSize: number;
    /** Whether to add X-Bot-Score header to responses */
    addScoreHeader: boolean;
    /** Paths to skip bot detection */
    skipPaths: string[];
    /** Request timing threshold in ms (faster = suspicious) */
    timingThresholdMs: number;
    /** Enable strict mode (stricter signal thresholds) */
    strictMode: boolean;
}
/**
 * Default bot detection configuration
 */
export declare const DEFAULT_BOT_DETECTION_CONFIG: BotDetectionConfig;
/**
 * Bot Detection Service
 *
 * Analyzes HTTP requests to detect automated/bot traffic using multiple signals.
 *
 * @example
 * ```typescript
 * const detector = new BotDetectionService({
 *   blockThreshold: 20,
 *   challengeThreshold: 50,
 * });
 *
 * // Analyze a request
 * const score = await detector.analyze(request);
 *
 * if (score.recommendation === 'block') {
 *   reply.status(403).send({ error: 'Bot detected' });
 * }
 * ```
 */
export declare class BotDetectionService {
    private readonly config;
    private readonly scoreCache;
    private readonly requestTimings;
    private cleanupInterval;
    constructor(config?: Partial<BotDetectionConfig>);
    /**
     * Analyze a request for bot indicators
     *
     * @param request - Fastify request to analyze
     * @returns Bot detection score and signals
     */
    analyze(request: FastifyRequest): Promise<BotScore>;
    /**
     * Quick check if request is likely a bot
     *
     * @param request - Fastify request to check
     * @returns true if request is likely a bot
     */
    isBot(request: FastifyRequest): Promise<boolean>;
    /**
     * Generate a fingerprint for the request
     *
     * @param request - Fastify request to fingerprint
     * @returns Fingerprint hash
     */
    getFingerprint(request: FastifyRequest): string;
    /**
     * Get current configuration
     */
    getConfig(): Readonly<BotDetectionConfig>;
    /**
     * Update configuration
     */
    updateConfig(updates: Partial<BotDetectionConfig>): void;
    /**
     * Clear the score cache
     */
    clearCache(): void;
    /**
     * Get cache statistics
     */
    getCacheStats(): {
        size: number;
        maxSize: number;
    };
    /**
     * Shutdown the service
     */
    shutdown(): void;
    private checkKnownGoodBots;
    private checkKnownBadBots;
    private checkHeadlessBrowsers;
    private checkMissingHeaders;
    private checkSuspiciousHeaders;
    private checkHeaderOrder;
    private checkSecHeaders;
    private checkRequestTiming;
    private checkTlsFingerprint;
    private checkCookies;
    private createScore;
    private getCachedScore;
    private cacheScore;
    private startCleanupInterval;
    private getClientIP;
    private extractJA3;
}
/**
 * Bot detection middleware options
 */
export interface BotDetectionMiddlewareOptions {
    /** Bot detection service instance */
    service?: BotDetectionService;
    /** Bot detection configuration (if not providing service) */
    config?: Partial<BotDetectionConfig>;
    /** Action to take: 'log' only logs, 'challenge' returns challenge, 'block' returns 403 */
    action: 'log' | 'challenge' | 'block';
    /** Paths to skip */
    skipPaths?: string[];
    /** Custom block response */
    blockResponse?: (score: BotScore) => {
        statusCode: number;
        body: Record<string, unknown>;
    };
    /** Custom challenge response */
    challengeResponse?: (score: BotScore) => {
        statusCode: number;
        body: Record<string, unknown>;
    };
    /** Lower rate limit for suspicious requests (multiplier, e.g., 0.5 = 50% of normal) */
    suspiciousRateLimitMultiplier?: number;
}
/**
 * Create bot detection middleware
 *
 * @param options - Middleware options
 * @returns Fastify preHandler hook
 *
 * @example
 * ```typescript
 * const botMiddleware = botDetectionMiddleware({
 *   action: 'block',
 *   config: {
 *     blockThreshold: 20,
 *     challengeThreshold: 50,
 *   },
 * });
 *
 * fastify.addHook('preHandler', botMiddleware);
 * ```
 */
export declare function botDetectionMiddleware(options: BotDetectionMiddlewareOptions): preHandlerHookHandler;
/**
 * Bot detection plugin options
 */
export interface BotDetectionPluginOptions extends BotDetectionMiddlewareOptions {
    /** Decorate Fastify instance with service */
    decorateInstance?: boolean;
}
/**
 * Bot detection Fastify plugin
 *
 * @example
 * ```typescript
 * await fastify.register(botDetectionPlugin, {
 *   action: 'block',
 *   config: {
 *     blockThreshold: 20,
 *   },
 * });
 *
 * // Access score in routes
 * fastify.get('/', (request, reply) => {
 *   const score = request.botScore;
 *   // ...
 * });
 * ```
 */
export declare const botDetectionPlugin: (fastify: FastifyInstance, options: BotDetectionPluginOptions, done: (err?: Error) => void) => void;
declare module 'fastify' {
    interface FastifyRequest {
        botScore?: BotScore;
    }
    interface FastifyInstance {
        botDetectionService?: BotDetectionService;
    }
}
/**
 * Get or create singleton BotDetectionService instance
 *
 * @param config - Configuration (only used on first call)
 * @returns Singleton instance
 */
export declare function getBotDetectionService(config?: Partial<BotDetectionConfig>): BotDetectionService;
/**
 * Reset singleton instance (primarily for testing)
 */
export declare function resetBotDetectionService(): void;
export default BotDetectionService;
//# sourceMappingURL=bot-detection.d.ts.map