mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-08 12:32:43 +00:00
A step-up elevation minted from the account password satisfied the fresh-factor routes. That is a second-factor bypass: a stolen token plus a known password could rotate the recovery codes — which take no factor in the body — and then spend one of them to disable the second factor outright. The web has never allowed that chain, because a password login does not stamp mfaVerifiedAt. The method is now an authorisation input. Only totp, webauthn, and passkey satisfy a fresh-factor gate, which is exactly the set of ceremonies the web stamps a session for; password reaches what a plain cookie session reaches and stops. The mint gains TOTP and security-key arms so a TOTP-only account can still manage its factor natively, and the response says which reach it bought. The gate also returns a discriminated context. session.id meant a session row on one arm and a token row on the other, and the disable route passed the token id to a session-scoped query — excluding nothing, so it deleted every browser session and revoked the caller's own device login. The transport is now in the type and the compiler refuses the confusion. Redemption splits into validate-then-commit so a 429, a 422, or a wrong code no longer burns a proof against a five-per-fifteen-minute mint ceiling. The claim is UPDATE ... RETURNING, so the statement that decides is the one that reports. The mint is transactional behind a partial unique index. Sign-out-everywhere and both password-reset paths clear elevations. The status read drops to plain requireAuth — it carries no credential material — and every mutation stays gated.
src/lib/
The server and runtime toolkit. Everything that is not a page, component, or route handler lives here: the API kit, auth, crypto, the rollup tier, AI providers, notifications, background jobs, and the integration clients. Route handlers and RSC pages compose these modules; the modules never reach back into app/.
Core request kit
api-handler.ts— theapiHandlerwrapper every route uses. Auth resolver (cookie OR Bearer),requireAuth/requireAdmin(admin is cookie-only by construction), idempotency plumbing, Wide-Event builder, GlitchTip forwarder.api-response.ts— the{ data, error, meta? }envelope:apiSuccess/apiError,safeJson, trusted-proxy IP resolver,returnAllZodIssues+sanitiseZodIssues.rate-limit.ts— Postgres-backed sliding-window limiter (single atomic upsert); multi-instance correct.idempotency.ts— user-scoped idempotency keys that refuse to cache secret-shaped responses.query-keys/— the only legal source of TanStack QueryqueryKey/mutationKeyarrays (enforced by an ESLint rule); per-feature files behind theindex.tsbarrel.safe-fetch.ts— the one documented outbound-egress entry (redirect: "manual"+ timeout; optional connect-time DNS-rebinding pin). Rawfetch(underlib/+app/is banned by ESLint.db.ts— the Prisma client singleton.crypto.ts— AES-256-GCM at rest with versioned key ids, fail-closed loader, rotation primitives.
Subsystems
auth/— Postgres sessions, secure-cookie flag policy, passkey (WebAuthn) + Argon2id password, per-device refresh-token rotation, HMAC Bearer tokens.ai/— multi-provider insight + Coach engine:provider-chain.ts, hand-rolled{openai,anthropic,local,codex,mock}-client.ts,coach/,prompts/, citation + confidence helpers.rollups/— DAY/WEEK/MONTH/YEAR pre-aggregations for measurements, mood, and medication compliance. Read-swap pattern: probe the rollup, fall back to live SQL on a coverage miss.notifications/— the dispatcher cascade (APNs → Telegram → ntfy → Web Push), per-channelsenders/, retry policy, VAPID config.jobs/— pg-boss workers: reminders, insight pre-generation, backups, retention sweeps, integration backfills. Recurring work belongs here, not inscripts/.integrations/,withings/,whoop/,fitbit/— OAuth clients and sync services for the device providers;sync/holds the shared delta-feed plumbing.analytics/— trend calculations, cadence-aware medicationcompliance.ts, correlations.insights/,fhir/,doctor-report-*.ts— insight pipeline, FHIR R4 export, client-side doctor-report PDF.openapi/— Zod registry that is the source of truth fordocs/api/openapi.yaml.logging/,observability/,monitoring/— Wide-Event transports and the central redaction denylists (redact at the egress boundary, not the call site).validations/— shared Zod schemas, including the SSRFisPublicUrlfloor.i18n/,tz/+timezone.ts,format*.ts— translations, timezone helpers (Berlin for display, UTC in DB), locale formatting.
Conventions
Kebab-case filenames. See ../../CLAUDE.md "Code conventions" and "Security-relevant patterns"; the critical-files map there cites the exact entry points. Most modules carry tests in a sibling __tests__/.