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,69 @@
# `errors/hibp-error.ts`
## Purpose
`HibpError` is the structured error class every failure path inside
`@suaveplan/hibp` throws. It carries one of the seven registered
`HibpErrorCode` values plus optional cause / context / trace-id metadata,
and ships a `toJSON()` form that strips sensitive payloads (API keys,
emails, passwords, full SHA-1 hashes) before any logger touches it.
## Features
- `code` field narrows on the seven-member registry, so callers can fan
out on stable enumerated values rather than parse messages.
- Inherits trace-id propagation and timestamp from
`SuaveplanError`, keeping every error in the project wire-compatible.
- `leakClass` field annotates errors thrown by `assert-no-leak.ts` with
whether the offending value was a SHA-1, a password, or an email —
without ever echoing the leaked bytes.
- `toJSON()` scrubs any 40-char hex sequence and any address-shaped
substring as a defence-in-depth filter, so even an unexpected interpolation
cannot leak a hash or email.
## Usage: Basic Example
```ts
import { HIBP_CODES, HibpError } from "@suaveplan/hibp";
try {
/* ... */
} catch (err) {
if (err instanceof HibpError && err.code === HIBP_CODES.RATE_LIMITED) {
// back off
}
}
```
## Usage: Advanced Example
```ts
import { HibpError } from "@suaveplan/hibp";
function logSafely(err: unknown, logger: { error(s: string): void }): void {
if (err instanceof HibpError) {
logger.error(JSON.stringify(err.toJSON()));
} else if (err instanceof Error) {
logger.error(err.message);
}
}
```
## API Reference
- `new HibpError(code, message, options?)` — `options` accepts `cause`,
`context`, `traceId`, `clock`, and `leakClass`.
- `error.code: HibpErrorCode` — the namespaced code string.
- `error.leakClass: "sha1" | "password" | "email" | undefined`.
- `error.toJSON()` — returns a stable, redacted serialization safe to
hand to any logger.
## Implementation Notes
The `toJSON` redaction is intentionally regex-based — strings that happen
to resemble a SHA-1 or an email get replaced with `[redacted]` even if
they were never deliberate. False positives here cost almost nothing;
false negatives would cost the privacy contract. The constructor uses a
helper to build the super-options object so that
`exactOptionalPropertyTypes: true` doesn't reject `undefined` values
that the parent class doesn't accept.