/** * Shared Express route guards (alongside createRouteLimiter in validation.ts). */ import type { Request, Response } from 'express'; /** * Canonicalize a bound-host string into the form a browser `Origin` hostname * takes after WHATWG URL parsing, so the same-host comparison in * {@link createLocalhostOriginGuard} can use a plain `===`. * * Returns `undefined` when the host carries no single comparable identity: * - empty / not provided * - a wildcard bind (`0.0.0.0`, `::`, expanded `0:0:0:0:0:0:0:0`) — the server * listens on every interface and has no one address a browser Origin maps to, * so writes stay loopback-only (we deliberately do NOT trust the whole subnet) * - an unparseable value * * Otherwise returns `new URL(...).hostname` (lowercased, IPv6 bracketed and * compressed) — provably identical to how the request Origin is parsed below. * Hand-rolling lowercase + bracketing is insufficient: it fails to compress * non-canonical IPv6 forms (e.g. `fe80:0:0:0:0:0:0:1`, `::ffff:127.0.0.1`). */ export declare function normalizeBoundHost(boundHost?: string): string | undefined; /** * Restrict a route to same-host browser origins. Allows: * - loopback (`localhost`, `127.0.0.1`, `[::1]`) * - the server's own bound host (when non-loopback, e.g. a LAN IP) * * Non-browser requests (no Origin header, e.g. curl / the CLI) pass through. * This closes cross-origin reach to write routes without affecting read routes. * * @param boundHost - The hostname/IP the server is listening on (from * `createServer`'s `host` parameter). When `undefined`, `'localhost'`, or a * wildcard (`0.0.0.0`/`::`), only loopback origins are admitted. */ export declare function createLocalhostOriginGuard(boundHost?: string): (req: Request, res: Response, next: () => void) => void; /** * Default guard that only allows loopback origins. For use in tests or when * the bound host is not available. */ export declare const requireLocalhostOrigin: (req: Request, res: Response, next: () => void) => void;