Files
PersonalBlog/packages/config/src/index.ts
T
implementer 345ceccfad feat: HOST validated at the adapter boundary and controls the actual bind interface (E00-S04-T04)
The environment adapter now resolves HOST through resolveHost, validating it
at the adapter boundary as a hostname (RFC 1123) or IP address (IPv4/IPv6,
node:net isIP); an invalid HOST throws a field-specific ConfigStartupError
naming host, so arbitrary env content is never used for binding or echoed
verbatim into the startup log (issue acceptance criterion, resolving security
review finding SEC-3).

The server passes config.host to server.listen(config.port, config.host, ...),
so a configured HOST binds exactly that interface and the startup log never
claims a bind the process does not enforce (resolving SEC-2).
2026-08-30 04:41:53 +00:00

40 lines
2.1 KiB
TypeScript

/**
* @personal-blog/config — EPPP configuration service.
*
* [E00-S04-T01] TypeBox/Ajv schema: the package boundary exposes the
* configuration schema (`configSchema`, defined with TypeBox) and the Ajv
* schema-validation entry point (`validateConfig`).
*
* [E00-S04-T02] Field-specific startup error: the boundary also exposes the
* startup validation entry point (`assertValidConfig`) and its field-specific
* errors (`MissingRequiredSettingError` — names the missing required setting —
* and `ConfigStartupError` — names each violating field), so the application
* fails fast at startup when a required setting is missing.
*
* [E00-S04-T03] Secret redaction: the boundary also exposes the redaction
* layer (`redactConfig` — a config value with every secret replaced by
* `[REDACTED]`, for logging the resolved configuration — and `redactText` —
* scrubbing free-form log text of the config's secret values), which the
* server's redacting logger applies to every log line, so secrets
* automatically redact from logs.
*
* [E00-S04-T04] Environment adapter: the boundary also exposes
* `loadConfigFromEnv` — the workspace's single owner of `process.env` reads.
* It maps the environment (`HOST`/`PORT`/`DATABASE_URL`/`EPPP_SESSION_SECRET`)
* onto the validated config shape and validates it with `assertValidConfig`
* at startup, so every setting flows through the adapter and no other module
* reads `process.env` directly. `HOST` is validated at the adapter boundary
* as a hostname or IP address before it is used for binding or logged, so
* arbitrary env content is never echoed verbatim into the startup log. The
* `.env.example` template (E00-S04-T05) builds on this boundary in a later
* task.
*/
export { configSchema } from './schema.js';
export type { Config } from './schema.js';
export { validateConfig } from './validate.js';
export type { ConfigValidationResult } from './validate.js';
export { assertValidConfig, ConfigStartupError, MissingRequiredSettingError } from './startup.js';
export { REDACTED, SECRET_FIELD_NAMES, redactConfig, redactText } from './redact.js';
export { loadConfigFromEnv } from './env.js';