first commit

This commit is contained in:
2026-05-29 08:20:56 +01:00
commit 949299f58d
6368 changed files with 527176 additions and 0 deletions

View File

@@ -0,0 +1,60 @@
# `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/<prefix>[?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.