Commit graph

12 commits

Author SHA1 Message Date
Arthur Belleville
6779663c8a
feat(08-02): add google social sign-in flow 2026-05-15 21:03:30 +02:00
Arthur Belleville
62e5e3eb60
feat(06-01): add river dependency and ListOrphanFiles sqlc query
- go get github.com/riverqueue/river@v0.37.0 + riverpgxv5@v0.37.0
- append ListOrphanFiles :many query to files.sql (orphan tablo_files rows)
- regenerate sqlc: ListOrphanFilesRow{ID, TabloID, S3Key} exported
- go build ./... exits 0
2026-05-15 16:32:48 +02:00
Arthur Belleville
e0d72747e0
feat(05-01): add aws-sdk-go-v2 modules, 0005_files migration, sqlc queries, and files.Store
- Add four aws-sdk-go-v2 modules: core, config, credentials, service/s3
- Write 0005_files.sql migration (tablo_files table with ON DELETE CASCADE)
- Write internal/db/queries/files.sql with InsertTabloFile, ListFilesByTablo, GetTabloFileByID, DeleteTabloFile
- Implement internal/files/store.go: FileStorer interface, Store struct, NewStore (UsePathStyle for MinIO), Upload (sniff+stream+bytecount), Delete, PresignDownload
- sqlc generate produces files.sql.go + TabloFile model (gitignored, regeneratable)
2026-05-15 12:18:16 +02:00
Arthur Belleville
389e1bc8b4
feat(02-07): gorilla/csrf integration — mount middleware, wire all forms, env-driven key
- auth.Mount(env, key) wraps csrf.Protect with locked D-14/D-24 options
- auth.LoadKeyFromEnv() reads SESSION_SECRET, hex-decodes, validates 32 bytes; fails fast on error
- ui.CSRFField(token) templ component renders hidden _csrf input
- Layout, LoginPage/Fragment, SignupPage/Fragment, Index all embed @ui.CSRFField(csrfToken)
- Handlers thread csrf.Token(r) into every page/fragment render call
- NewRouter mounts auth.Mount after ResolveSession, before all route groups (D-24)
- main.go calls auth.LoadKeyFromEnv(); logs.Fatalf on missing/invalid SESSION_SECRET
- SESSION_SECRET documented in .env.example with openssl rand -hex 32 instruction
- go.mod: gorilla/csrf v1.7.3 (direct); prior tests updated with getCSRFToken helper
- All Plan 04/05/06 tests updated to acquire and submit valid _csrf tokens
2026-05-14 22:59:06 +02:00
Arthur Belleville
ae2d356f87
test(02-07): add failing CSRF tests (RED gate)
- TestLoadCSRFKey_* in internal/auth for env key loading
- TestCSRF_*MissingToken / TestCSRF_*ValidToken for all three POST routes
- TestForms_ContainCSRFField for hidden _csrf input in rendered HTML
- TestRouter_CSRFMountedAfterResolveSession for middleware order (D-24)
- TestCSRF_HeaderFallback for X-CSRF-Token header support
- Add gorilla/csrf v1.7.3 dependency
2026-05-14 22:45:36 +02:00
Arthur Belleville
b5c20c7892
feat(02-05): implement LimiterStore with injectable clock and janitor
- Token-bucket rate limiter keyed per (email+IP) using golang.org/x/time/rate
- rate.Every(12s), burst=5, idleTTL=10min (D-16)
- AllowN(t, 1) with injectable clock for deterministic tests (Pattern 8)
- Janitor goroutine evicts entries idle > 10min via cleanupNow()
- No .Allow() without args (Pitfall 8 avoided)
- Five tests pass with -race: burst, refill, isolation, janitor, concurrent
- golang.org/x/time v0.15.0 added to go.mod
2026-05-14 22:22:24 +02:00
Arthur Belleville
ee36a5c78b
feat(02): GREEN — argon2id Hash + Verify + self-test
- Add Params struct with Memory/Iterations/Parallelism/SaltLength/KeyLength
- DefaultParams: OWASP 2024 baseline (m=64KiB, t=1, p=4, salt=16B, key=32B) — D-08
- TestParams: reduced cost (m=8KiB) so go test stays under 5s — D-26/Pitfall 4
- Hash(): crypto/rand salt per call, argon2.IDKey, PHC format $argon2id$v=19$...
- Verify(): PHC split/parse, ErrInvalidHash on malformed, ErrIncompatibleVersion on v!=19
- subtle.ConstantTimeCompare for timing-attack resistance (T-2-13)
- init() self-test: hash/verify round-trip panics on regression (D-08/T-2-15)
- Add golang.org/x/crypto v0.51.0 as direct dependency
2026-05-14 22:00:55 +02:00
Arthur Belleville
2c84f4275b
feat(02-01): create internal/auth package skeleton, test DB harness, env docs
- auth/doc.go: package comment explaining consolidated layout (Open Question 3 resolved)
- auth/types.go: User + Session structs, SessionCookieName (D-12), SessionTTL (D-09),
  SessionExtendThreshold (D-09), ErrSessionNotFound, ErrInvalidHash, ErrIncompatibleVersion
- auth/testdb_test.go: setupTestDB creates isolated per-test schema (test_<uuid>),
  runs goose Up with unique version table, drops schema on cleanup (D-26)
  TestSetupTestDB_Roundtrip smoke test verifies users table visible
- go.mod: added github.com/pressly/goose/v3 v3.27.1 as direct dependency
- .env.example: added TEST_DATABASE_URL and SESSION_SECRET with comments (D-14, D-26)
2026-05-14 21:56:45 +02:00
Arthur Belleville
36e96015f5
feat(01-03): pgxpool wrapper, RequestID/slog middleware, slog handler switch
- Remove //go:build red_gate tag from internal/web/handlers_test.go and
  internal/db/pool_test.go now that consumer symbols are about to exist
- go mod tidy after real importers land (deferred from Plan 01-01 per
  Codex concern #1) — chi/v5, templ, pgx/v5, google/uuid now in require list
- internal/db/pool.go: NewPool(ctx, dsn) builds a pgxpool.Pool with
  MaxConns=10, MinConns=1; no eager Ping (RESEARCH Pitfall 2)
- internal/web/slog.go: NewSlogHandler returns JSON when env='production',
  text otherwise; pure helper, no slog.SetDefault side effect
- internal/web/middleware.go: RequestIDMiddleware (UUIDv4 → ctx +
  X-Request-ID header), LoggerFromContext helper, SlogLoggerMiddleware
  factory using chi WrapResponseWriter; field allowlist per V7/T-01-09
2026-05-14 19:24:16 +02:00
Arthur Belleville
aa90008d95
feat(01-01): initialize Go module and pin runtime dependencies
- module: backend (go 1.26.1)
- chi v5.2.5, templ v0.3.1020, pgx/v5 v5.9.2, goose v3.27.1, uuid v1.6.0
- pinned via 'go get'; 'go mod tidy' deferred to Plan 01-03 where consumers exist (Codex concern #1)
2026-05-14 17:53:36 +02:00
Arthur Belleville
50ba9b340b
Modify backend 2025-03-15 08:46:51 +01:00
Arthur Belleville
684b057b27
Initial commit 2025-01-18 22:40:32 +01:00