feat(auth): Google OAuth, sealed session and default-deny gating (T9)

Gate the app behind Google sign-in restricted to verified @theodo.com
identities, and record the real reporter on filed defects (F9).

- nuxt-auth-utils for sealed cookie sessions + the Google OAuth handler,
  mounted at /auth/google/callback to match the registered redirect URI.
- isAllowedGoogleUser re-derives the domain from Google's verified email;
  the spoofable `hd` claim is deliberately ignored (DESIGN T9).
- Default-deny: server middleware 401s unauthenticated /api calls (health
  and the session endpoint excepted); a global route middleware redirects
  unauthenticated page navigations to /login.
- getReporter() now reads the session email instead of the dev stub.
- Env contract moves to nuxt-auth-utils names (NUXT_SESSION_PASSWORD,
  NUXT_OAUTH_GOOGLE_*); .env.example, compose and README updated.

Unit-tested: domain check (incl. hd-spoof + look-alike) and public-path
matching. Live OAuth round-trip pending manual verification.
This commit is contained in:
Julien Calixte
2026-05-28 01:09:48 +02:00
parent 73e4c56a9e
commit 82ac540909
18 changed files with 368 additions and 21 deletions

View File

@@ -1,5 +1,5 @@
# App
NUXT_SESSION_SECRET=change-me
# App — session sealing key for nuxt-auth-utils (must be ≥32 chars)
NUXT_SESSION_PASSWORD=change-me-to-a-long-random-string-min-32-chars
# Database (Postgres) — Coolify-managed in prod, docker-compose in dev
DATABASE_URL=postgres://andon:andon@localhost:5432/andon
@@ -9,10 +9,13 @@ POSTGRES_USER=andon
POSTGRES_PASSWORD=andon
POSTGRES_DB=andon
# Google OAuth (Task 9) — restricted to the theodo.com hosted domain
GOOGLE_CLIENT_ID=
GOOGLE_CLIENT_SECRET=
GOOGLE_REDIRECT_URI=
# Google OAuth (Task 9) — nuxt-auth-utils reads these exact names. Access is
# restricted server-side to verified @theodo.com emails (the `hd` claim is not
# trusted on its own). REDIRECT_URL must match an Authorized redirect URI in the
# Google Cloud console (defaults to <origin>/auth/google/callback if unset).
NUXT_OAUTH_GOOGLE_CLIENT_ID=
NUXT_OAUTH_GOOGLE_CLIENT_SECRET=
NUXT_OAUTH_GOOGLE_REDIRECT_URL=
# Web Push / VAPID (Task 10)
VAPID_PUBLIC_KEY=