# `privacy/assert-no-leak.ts` _(no submodules)_ ## Purpose `assertNoLeak` is the runtime sentinel that scans an outgoing `Request` URL and body byte-by-byte for three classes of forbidden content: the full SHA-1 digest of the password being checked, the password itself, and the configured email. A hit on any of the three throws `HibpError(HIBP.MALFORMED_RESPONSE)` carrying a `leakClass` tag that identifies what was leaked — without ever echoing the leaked bytes into the error message. ## Features - Three independent leak classes — `sha1`, `password`, `email` — each optional so callers pay only for the checks they configure. - Whitelists the legitimate 5-hex prefix in the range URL so the k-anonymity protocol does not trip the check. - Treats both the literal email and its URL-encoded form as body leaks, but allows the documented `/api/v3/breachedaccount/{encoded}` and `/api/v3/pasteaccount/{encoded}` URL shapes. - Tolerates requests whose body cannot be cloned (some `Request` subclasses) — failure to read the body is silent rather than fatal. - No allocations beyond what `Request.clone().text()` requires. ## Usage: Basic Example ```ts import { assertNoLeak } from "@suaveplan/hibp"; await assertNoLeak(req, { password: "hunter2" }); ``` ## Usage: Advanced Example ```ts import { assertNoLeak, hashSha1Prefix } from "@suaveplan/hibp"; const { full } = hashSha1Prefix(password); await assertNoLeak(req, { fullSha1: full, password, email }); ``` ## API Reference - `LeakCandidate` — `{ fullSha1?, password?, email? }`. - `LeakClass` — `"sha1" | "password" | "email"`. - `assertNoLeak(request, candidates): Promise` — throws on hit. ## Implementation Notes The helper is intentionally async even though the URL check is synchronous: reading the body requires `Request.clone().text()`, which returns a `Promise`. The check uses `Array.prototype.includes` on the strings rather than per-byte iteration because JS strings already expose `indexOf` in O(n), and the simpler API has fewer ways to go wrong. The 5-hex prefix is stripped before the SHA-1 search to avoid flagging the legitimate k-anonymity payload. Production deployments opt in via `HibpClient` `assertOutgoingRequestSafe: true`; tests use it unconditionally as a regression sentinel.