Skip to content

centralize admin auth in hooks + rate limit uploads

jedmund requested to merge jedmund/arch-audit-auth-hooks into main

Created by: jedmund

Summary

Architecture audit phase 3 — structural auth enforcement and defense-in-depth rate limits.

  • A-4 · Move admin auth from per-route checkAdminAuth() calls to a single /api/admin/* prefix check in hooks.server.ts. New admin endpoints can't accidentally ship unauthenticated — forgetting the guard is no longer possible. Dropped 21 redundant guards across admin routes; checkAdminAuth() stays available for routes that mix public reads with admin writes (/api/projects, /api/posts, /api/albums, /api/media, /api/tags) until A-10 relocates those.
  • A-9 (scaled) · Refactored the rate limiter to support per-prefix configs. Added a 30/min bucket for /api/media/upload and /api/media/bulk-upload as defense in depth — these are session-gated, so rate-limiting is self-DoS protection rather than a brute-force defense. Existing login (5/min) and project unlock (5/min) limits unchanged.
  • Also removed two unused Apple Music test fixtures (debug/test-find-album, debug/test-simple-search) that were noise.

Net: −233 lines across 24 files.

Test plan

  • pnpm check — baseline 116 errors / 9 warnings, no new ones introduced
  • Unauthenticated GET /api/admin/media-stats → 401 {error:"Unauthorized"}
  • Authenticated GET /api/admin/media-stats → 200 with stats
  • curl -X POST /api/media/upload 31 times → 429 on request 31 (verify the 30/min bucket)
  • curl -X POST /admin/login 6 times → 429 on request 6 (verify login bucket still works, independent of upload bucket)
  • Admin UI still loads and can perform uploads/edits without "Unauthorized" flashes

Merge request reports

Loading