trails/apps/journal
Ullrich Schäfer 6afd996e19
fix(journal): rate-limit auth endpoints
Adds per-process in-memory fixed-window rate limiting (lib/rate-limit.server.ts)
and applies it across /api/auth/login and /api/auth/register:

- All login steps: 30 attempts per IP per minute (defense against
  step-fanout flooding).
- finish-passkey: 10 per IP per minute (assertions don't usefully retry
  faster).
- magic-link generation: 3 per email per 5 min + 10 per IP per 5 min
  (defeats inbox-spam-the-victim + cross-email IP fanout).
- verify-code: 10 per email per 15 min — makes 6-digit code brute force
  (10^6 search) infeasible before code expiry.
- /api/auth/register: 10 per IP per hour (legitimate signup completes
  in 2-3 requests; sustained churn from one IP is account spam).

Single-instance is fine for the flagship's current topology (one journal
container). When we horizontally scale we revisit with a Postgres- or
Redis-backed store. Buckets self-clean on next read and a 5-minute
background sweep drops stale entries.

Client IP: honors X-Forwarded-For first entry (Caddy in front of the
journal sets it), falls back to a stable "unknown" bucket so the
limiter still bites when the header is missing.

Tests: rate-limit.server.test.ts (8 cases — exhaustion, independent
scopes/keys, remaining countdown, reset window, XFF parsing, fallback,
trimming). Existing auth tests still pass; limits sized to not trip
during the ~7 test cases that all share the "unknown" IP bucket.

Full repo: pnpm typecheck, pnpm lint, pnpm test all green.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-24 11:51:43 +02:00
..
app fix(journal): rate-limit auth endpoints 2026-05-24 11:51:43 +02:00
public Add favicons, apple-touch-icons, and Chrome DevTools JSON 2026-03-29 10:35:03 +02:00
.env.example Document why HTTPS=1 dev exists, and the one case that still needs it 2026-04-26 12:26:58 +02:00
Dockerfile Add packages/fit to journal and planner Dockerfiles 2026-05-01 08:10:15 +02:00
package.json Bump the production group with 14 updates 2026-05-24 08:31:11 +00:00
react-router.config.ts Complete monorepo toolchain setup (tasks 1.1-1.7) 2026-03-22 12:12:57 +01:00
server.ts fix(journal): fail loud in production when secrets are unset 2026-05-24 11:37:20 +02:00
tsconfig.json Fix planner production server + use .ts extensions everywhere 2026-03-25 01:41:33 +01:00
vite.config.ts Pre-warm Vite dep discovery for the journal dev server 2026-04-26 19:51:39 +02:00
vitest.config.ts Add mocked unit tests for REST API route handlers 2026-04-13 00:59:45 +02:00