/**
 * Security utilities for the mailpouch Settings Server
 *
 * Covers:
 *   • Per-IP rate limiting (sliding window, in-memory)
 *   • Safe request body reading (size cap + timeout)
 *   • Origin / Referer validation (defence-in-depth)
 *   • LAN access token (256-bit, single-use per server instance)
 *   • Self-signed TLS certificate generation via system openssl
 *   • Constant-time token comparison to prevent timing attacks
 *   • Input sanitisation helpers shared with the escalation module
 *
 * None of this requires third-party packages — only Node.js built-ins.
 */
import http from "http";
/** Max POST body size: 64 KiB.  Rejects bodies that could exhaust heap. */
export declare const MAX_BODY_BYTES = 65536;
/** Abort reading body after this many ms (Slow Loris / slow POST). */
export declare const BODY_TIMEOUT_MS = 15000;
/** Per-IP request rate: general endpoints (req / window). */
export declare const GENERAL_RATE_LIMIT = 120;
/** Per-IP request rate: mutating escalation endpoints. */
export declare const ESCALATION_RATE_LIMIT = 20;
/** Per-IP request rate: any request when serving over LAN. */
export declare const LAN_RATE_LIMIT = 200;
/**
 * Sliding-window in-memory rate limiter.
 *
 * Keyed by any string (typically the client IP address + optional route tag).
 * Stale buckets are evicted every `windowMs` to prevent unbounded memory growth.
 * A hard cap of MAX_RATE_LIMIT_BUCKETS distinct keys is enforced per instance.
 */
export declare class RateLimiter {
    private readonly maxRequests;
    private readonly windowMs;
    private readonly buckets;
    private readonly cleanup;
    constructor(maxRequests: number, windowMs: number);
    /**
     * Consume one slot for `key`.
     * Returns true if the request is allowed; false if the limit is exceeded.
     */
    check(key: string): boolean;
    /** Current slot count for a key (does not consume a slot). */
    count(key: string): number;
    dispose(): void;
    private evict;
}
/**
 * Reads an HTTP request body with strict guards:
 *   • Aborts and destroys the socket if the body exceeds `maxBytes`.
 *   • Aborts after `timeoutMs` with no data (Slow Loris / slow-POST).
 *
 * Callers should still validate/sanitise the returned string.
 */
export declare function readBodySafe(req: http.IncomingMessage, maxBytes?: number, timeoutMs?: number): Promise<string>;
/**
 * Returns true if the request's `Origin` or `Referer` header is consistent
 * with the settings server itself.
 *
 * This is defence-in-depth alongside CSRF tokens — neither alone is
 * sufficient, together they raise the bar significantly.
 *
 * Requests with no Origin/Referer are allowed (some legitimate browser
 * environments omit them); the CSRF check is the authoritative gate.
 *
 * @param scheme  "http" or "https" — the actual scheme the server is using.
 *                This is required to accept the correct origin in TLS mode,
 *                where browsers send `https://` rather than `http://` origins.
 */
export declare function isValidOrigin(req: http.IncomingMessage, port: number, lan: boolean, scheme?: "http" | "https"): boolean;
export interface AccessToken {
    /** Raw token (64 hex chars = 256-bit random). */
    value: string;
    /** Truncated SHA-256 of value — safe to display publicly. */
    fingerprint: string;
}
/** Generate a fresh 256-bit access token for LAN mode. */
export declare function generateAccessToken(): AccessToken;
/**
 * Check whether an incoming request carries the valid access token.
 * Uses `timingSafeEqual` to prevent timing-based enumeration.
 *
 * Only the `X-Access-Token` header is accepted. Query-string tokens leak
 * into browser history, referer headers to outbound links, proxy access
 * logs, and devtools network tab; not worth the marginal UX benefit.
 */
export declare function hasValidAccessToken(req: http.IncomingMessage, _url: URL, token: AccessToken): boolean;
/**
 * UI-014: bootstrap-only token check for the shell HTML served on "/".
 *
 * The shell page is loaded by a top-level browser *navigation*, which cannot
 * carry a custom `X-Access-Token` header — so the documented LAN bootstrap URL
 * passes the token as `?token=…`. The API endpoints stay header-only (query
 * tokens leak into history / referer / proxy logs), but "/" must still be gated
 * in LAN mode or any device on the network could fetch the page and read the
 * embedded per-process CSRF token. This accepts the token from EITHER the
 * header (SPA re-fetch) or the `?token=` query (initial navigation), compared
 * constant-time.
 */
export declare function hasValidBootstrapToken(req: http.IncomingMessage, url: URL, token: AccessToken): boolean;
export interface TlsCredentials {
    key: Buffer;
    cert: Buffer;
    /** Human-readable SHA-256 fingerprint for display in the terminal. */
    fingerprint: string;
}
/**
 * Attempt to generate a self-signed TLS certificate via the system `openssl`
 * binary.  Returns `null` if openssl is unavailable or fails.
 *
 * The cert is written to a temporary directory and loaded into memory;
 * the files are left on disk in `/tmp` and will be cleaned by the OS.
 *
 * The resulting credentials are suitable for `https.createServer()`.
 */
export declare function tryGenerateSelfSignedCert(): TlsCredentials | null;
export declare function isValidChallengeId(id: unknown): id is string;
export declare function sanitizeText(text: unknown, maxLen?: number): string;
export declare function isValidEscalationTarget(preset: unknown): preset is string;
/** Get the machine's primary non-loopback IPv4 address. */
export declare function getPrimaryLanIP(): string;
/**
 * Extract the remote IP from a Node.js HTTP request, preferring
 * socket.remoteAddress over any forwarded headers (we do not sit behind
 * a proxy so forwarded headers should never be trusted here).
 */
export declare function clientIP(req: http.IncomingMessage): string;
//# sourceMappingURL=security.d.ts.map