# `range/range.ts` _(no submodules)_ ## Purpose `RangeClient` is the heart of the package — the k-anonymity Pwned Passwords client. `checkPassword(password, opts?)` hashes the input, slices the 5-hex prefix, dispatches `GET https://api.pwnedpasswords.com/range/` with the mandatory `Add-Padding: true` header, scans the streamed response for a matching 35-char suffix, and returns `{ pwned, count }`. It owns the strict / off framing, the NTLM mode opt-in, the differential-privacy decoy fan-out, the AbortSignal threading, and the OTel emission. ## Features - Mandatory `Add-Padding: true` on every fetch — including every differential-privacy decoy. - SHA-1 (default) and NTLM (caller-injected adapter) hash modes. - Constant-time suffix compare on every parsed line. - Streaming line parser (no `Response.text()` call ever). - Differential-privacy decoy fan-out when `extraPrefixes > 0` — real prefix's response is the only one consulted. - AbortSignal threaded into fetch and the streaming parser. - OTel histograms for duration; counters for outcome, errors, throttling. - Optional `assertOutgoingRequestSafe: true` runtime privacy gate. ## Usage: Basic Example ```ts import { RangeClient } from "@suaveplan/hibp"; const client = new RangeClient(); const { pwned, count } = await client.checkPassword("hunter2"); ``` ## Usage: Advanced Example ```ts import { RangeClient } from "@suaveplan/hibp"; const client = new RangeClient({ extraPrefixes: 3, rng: myRng, assertOutgoingRequestSafe: true, strict: true, }); const ac = new AbortController(); setTimeout(() => ac.abort(), 5_000); const result = await client.checkPassword("hunter2", { signal: ac.signal }); ``` ## API Reference - `CheckPasswordOptions` — `mode?`, `signal?`, `extraPrefixes?`. - `RangeClientOptions` — `fetchFn`, `clock`, `rng`, `strict`, `ntlmHash`, `extraPrefixes`, `assertOutgoingRequestSafe`. - `new RangeClient(options?)`. - `client.checkPassword(password, opts?): Promise`. ## Implementation Notes The class is stateless beyond its constructor options — every public method takes the password and a per-call options bag, so a single `RangeClient` instance is safe to share across a process. Error paths funnel through the metrics emission so dashboards see counters even for failures the caller catches and retries. The `assertOutgoingRequestSafe` gate constructs a `Request` to feed into `assertNoLeak`, then re-issues the actual fetch with the same `RequestInit` so the privacy check exercises the real outgoing bytes. The NTLM adapter is required at runtime if `mode: "ntlm"` is ever passed; a missing adapter surfaces as `HIBP.MALFORMED_RESPONSE` because the caller has misconfigured the client rather than the server having misbehaved.