Przeglądaj źródła

[Docs] Note signout routes + Supabase cookie-name pinning rule

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
User 2 miesięcy temu
rodzic
commit
add8745dc0
1 zmienionych plików z 4 dodań i 3 usunięć
  1. 4 3
      CLAUDE.md

+ 4 - 3
CLAUDE.md

@@ -16,10 +16,10 @@ Docker: `docker compose up --build`. Supabase Studio at `localhost:3000` (dev on
 
 
 ```
 ```
 TMDB Proxy:  /api/tmdb/search, /api/tmdb/* (server-side only — TMDB_API_KEY never NEXT_PUBLIC_)
 TMDB Proxy:  /api/tmdb/search, /api/tmdb/* (server-side only — TMDB_API_KEY never NEXT_PUBLIC_)
-Auth:        Supabase GoTrue (signInAnonymously) — no custom auth routes
+Auth:        Supabase GoTrue (signInAnonymously). /api/auth/recovery/{generate,claim}, /api/auth/signout (POST), /logout (GET/POST → redirect /)
 Groups:      /api/groups, /api/groups/join (rate-limited, server-side via service role key)
 Groups:      /api/groups, /api/groups/join (rate-limited, server-side via service role key)
 Health:      /api/health
 Health:      /api/health
-Admin:       /admin (TOTP login, iron-session v8)
+Admin:       /admin (TOTP login, iron-session v8) — /api/admin/logout is SEPARATE from user signout
 ```
 ```
 
 
 All TMDB calls set `include_adult=false` and server-side filter by `adult` field.
 All TMDB calls set `include_adult=false` and server-side filter by `adult` field.
@@ -40,7 +40,7 @@ Tables: `users`, `groups`, `group_members`, `movies`, `landing_reel_posters`
 
 
 ## Frontend (Next.js App Router)
 ## Frontend (Next.js App Router)
 
 
-- `@supabase/ssr` — `createBrowserClient` (browser) / `createServerClient` with `SUPABASE_INTERNAL_URL` (server)
+- `@supabase/ssr` — `createBrowserClient` (browser) / `createServerClient` with `SUPABASE_INTERNAL_URL` (server). All server-side `createServerClient` MUST set `cookieOptions: { name: getSupabaseCookieName() }` (`src/lib/supabase/cookie-name.ts`) so the cookie name is derived from `NEXT_PUBLIC_SUPABASE_URL`, not the internal URL — otherwise hostname-based project-ref derivation diverges from the browser and `getUser`/`signOut` silently no-op.
 - TanStack Query with explicit `staleTime`. Offline: `persistQueryClient` + IndexedDB (3 packages: `react-query-persist-client`, `query-async-storage-persister`, `idb-keyval`).
 - TanStack Query with explicit `staleTime`. Offline: `persistQueryClient` + IndexedDB (3 packages: `react-query-persist-client`, `query-async-storage-persister`, `idb-keyval`).
 - TMDB posters: native sized URLs from TMDB CDN (w342 grid, w185 reel, w500 panel). No `next/image` for posters. `loading="lazy"` + meaningful `alt` text on all images. Reel posters `aria-hidden`.
 - TMDB posters: native sized URLs from TMDB CDN (w342 grid, w185 reel, w500 panel). No `next/image` for posters. `loading="lazy"` + meaningful `alt` text on all images. Reel posters `aria-hidden`.
 - Real-time: subscribe on mount, unsubscribe on unmount (one list at a time). Home page counts via polling.
 - Real-time: subscribe on mount, unsubscribe on unmount (one list at a time). Home page counts via polling.
@@ -54,6 +54,7 @@ Tables: `users`, `groups`, `group_members`, `movies`, `landing_reel_posters`
 ## Auth
 ## Auth
 
 
 - Users: Supabase Anonymous Sign-In → JWT via GoTrue → cookie-based sessions via `@supabase/ssr`
 - Users: Supabase Anonymous Sign-In → JWT via GoTrue → cookie-based sessions via `@supabase/ssr`
+- Signout: `<SignOutButton />` in `(app)` header → `POST /api/auth/signout` → `queryClient.clear()` → hard nav to `/`. Linkable variant: `GET /logout` (redirects). No confirm dialog, even for users without a saved recovery code.
 - Recovery: 24-char alphanumeric (128-bit entropy), Argon2id hashed, single-use, claim rate-limited (5/15min per IP)
 - Recovery: 24-char alphanumeric (128-bit entropy), Argon2id hashed, single-use, claim rate-limited (5/15min per IP)
 - Admin: username + TOTP (otplib), iron-session v8 (HttpOnly, Secure, SameSite=Strict, 8h expiry)
 - Admin: username + TOTP (otplib), iron-session v8 (HttpOnly, Secure, SameSite=Strict, 8h expiry)
 - GoTrue config: `GOTRUE_EXTERNAL_ANONYMOUS_USERS_ENABLED=true`, all other auth methods disabled
 - GoTrue config: `GOTRUE_EXTERNAL_ANONYMOUS_USERS_ENABLED=true`, all other auth methods disabled