Commit graph

3 commits

Author SHA1 Message Date
Arthur Belleville
7d8c498980
feat(02-05): login vertical slice with rate limiting
- auth_login.templ: LoginPage + LoginFormFragment (mirrors signup shape)
- LoginForm + LoginErrors types added to templates/auth_forms.go
- LoginPageHandler + LoginPostHandler in handlers_auth.go
  - Rate-limit check before user lookup (D-16, T-2-14)
  - Single errInvalidCreds constant for D-20 enumeration defense
  - Session rotation via Store.Rotate on success (D-10, T-2-04)
  - HTMX-aware redirect and fragment responses (D-19, D-21)
- AuthDeps extended with Limiter *auth.LimiterStore field
- router.go: GET /login in RedirectIfAuthed group (D-23)
- main.go: LimiterStore created with janitor goroutine (D-16)
- Export NewLimiterStoreWithClock + SetLimiterClock for cross-package tests
- 12 TestLogin_* integration tests all pass with real DB
2026-05-14 22:27:54 +02:00
Arthur Belleville
efdc16babe
feat(02-04): signup handler, router wiring, and integration tests
- Add handlers_auth.go: SignupPageHandler + SignupPostHandler (validate -> hash -> insert -> session -> redirect)
- Add AuthDeps struct; wire argon2id hash, InsertUser, Store.Create, SetSessionCookie
- Update router.go: NewRouter accepts AuthDeps; mount ResolveSession (D-24); wire /signup routes behind RedirectIfAuthed
- Update cmd/web/main.go: build AuthDeps (sqlc.Queries + auth.Store + secure flag) and pass to NewRouter
- Add nil-Store guard to auth.ResolveSession for Phase 1 unit-test compatibility
- Update handlers_test.go: pass AuthDeps{} zero value to NewRouter (Phase 1 routes unaffected)
- Add testdb_test.go: isolated-schema test helper for web package integration tests
- Add handlers_auth_test.go: 8 TestSignup_* integration tests (all pass against real Postgres)
2026-05-14 22:17:50 +02:00
Arthur Belleville
08a2c3cd96
feat(01-03): cmd/web entrypoint with graceful shutdown
- Reads DATABASE_URL (required), PORT (default 8080), ENV (default
  development) from os.Getenv only — no third-party env loader (D-15:
  .env exported by just dev, prod injects real env)
- slog.SetDefault wired before fatal-on-missing-DSN so even startup errors
  emit structured output; sanitization per T-01-12 (never log DSN)
- pgxpool opened via db.NewPool; chi router mounted with ./static as the
  asset root
- http.Server: ReadTimeout=15s, WriteTimeout=15s, IdleTimeout=60s
  (T-01-10 slow-client mitigation)
- signal.NotifyContext (Go 1.21+) traps SIGINT/SIGTERM, propagates through
  ctx; on signal: srv.Shutdown with 10s timeout, then explicit pool.Close
  (Pitfall 4 — never via defer)
- No /readyz route (Phase 7 scope)
2026-05-14 19:26:22 +02:00