# `range/range-mode.ts` ## Purpose Houses the hash-mode dispatch utilities used by `checkPassword`: `hashSha1Prefix` (SHA-1 via `@noble/hashes/sha1`), `hashNtlmPrefix` (MD4-over-UTF-16-LE, supplied by an injectable adapter because not every runtime ships an MD4 implementation), and `buildRangeUrl` (assembles the final `/range/[?mode=ntlm]` URL). The split between hashing and URL building keeps each function small, testable, and reusable from both the public `checkPassword` path and the privacy-leak verification helpers. ## Features - `hashSha1Prefix(password)` returns `{ prefix, suffix, full }` with the uppercase 40-char digest and its k-anonymity decomposition. - `hashNtlmPrefix(password, adapter)` accepts a caller-supplied adapter, validating that the returned digest is exactly 40 uppercase hex chars. - `buildRangeUrl(prefix, mode)` appends `?mode=ntlm` only when the mode is `"ntlm"` — SHA-1 mode never sends a query string. - `RangeMode` type alias narrows callers to the two valid values. ## Usage: Basic Example ```ts import { buildRangeUrl, hashSha1Prefix } from "@suaveplan/hibp"; const { prefix } = hashSha1Prefix("hunter2"); const url = buildRangeUrl(prefix, "sha1"); ``` ## Usage: Advanced Example ```ts import { buildRangeUrl, hashNtlmPrefix } from "@suaveplan/hibp"; import { md4 } from "my-ntlm-adapter"; const { prefix } = hashNtlmPrefix("hunter2", (pw) => md4(pw).toUpperCase()); const url = buildRangeUrl(prefix, "ntlm"); ``` ## API Reference - `RangeMode = "sha1" | "ntlm"`. - `NtlmHashAdapter = (password: string) => string`. - `hashSha1Prefix(password): { prefix, suffix, full }`. - `hashNtlmPrefix(password, adapter): { prefix, suffix, full }`. - `buildRangeUrl(prefix, mode): string`. ## Implementation Notes SHA-1 is sourced from `@noble/hashes/sha1` rather than from `@suaveplan/crypto-hash` because the crypto-hash package deliberately omits SHA-1 (collision-broken for security purposes). The HIBP API requires SHA-1 strictly for k-anonymity bucket selection — never for security — so the direct noble dependency is the right call. `hashNtlmPrefix` validates the adapter output rather than trusting it because a buggy adapter could produce shorter strings and accidentally leak unrelated bytes.