Replace username-based admin bootstrap with a one-time setup secret, rate-limit login/register, equalize login bcrypt timing, cap passwords at 72 bytes, destroy sessions on logout, and require Secure cookies when PORT is set.
1.7 KiB
1.7 KiB
Plumber — follow-ups
From the project review. Priority order within each section.
Done recently
- Persist sessions — Custom sqlc-backed
SessionStore(scs API kept; nopostgresstore). - Drop Dockerfile — DigitalOcean App Platform buildpack from
go.mod. - Rune-safe truncation — Form fields truncate by runes.
- Admin bootstrap — One-time
ADMIN_SETUP_SECRETon register (not username alone);/admin/usersfor promote/demote. - Graceful shutdown — Signal-aware
http.Server.Shutdownwith timeouts. - Handler tests — Vote HTMX, answer/hide, CSRF, session rotation via in-memory
Store(no Postgres for web suite). - App Platform listen port — Prefers
PORT, thenLISTEN, then:8080. - Prod DB = PlanetScale Postgres — Required
DATABASE_URL; DSN cleanup for PlanetScale/libpq-only params. - Auth hardening — Rate limits, timing-safe login, password ≤72 bytes, logout destroys session, Secure cookies required when
PORTis set.
Docs & ops
- README — How to run locally, env vars (from
.env.example), admin bootstrap, PlanetScaleDATABASE_URL, App Platform notes (PORT,SECURE_COOKIE=1). - Migrations story — Schema is applied on boot from
schema.sql. OK for v1; plan real migrations before schema drifts.
Smaller / later
- Cursor pagination UI when hunt/profile lists hit their row limits.
- Optional Postgres integration tests (
TEST_DATABASE_URL) for sqlc SessionStore / advisory locks.
Suggested order of attack
- Short README (run, env, admin setup secret, App Platform + PlanetScale).
- Migrations plan before the next schema change.