diff --git a/.github/workflows/playwright.yml b/.github/workflows/playwright.yml index b42e60a3..20d5adc0 100644 --- a/.github/workflows/playwright.yml +++ b/.github/workflows/playwright.yml @@ -1,9 +1,10 @@ name: Playwright +# Disabled: Vercel preview deployments return 401 (password-protected), causing +# wait-for-vercel-preview to exhaust retries. Re-enable once previews are public +# or the workflow is updated to pass a bypass token. +# See: notes/public/revival-roadmap.md → Fix CI — Playwright workflow disabled on: - push: - branches: [main] - pull_request: - branches: [main] + workflow_dispatch: jobs: test_setup: name: Test setup diff --git a/docs/02-delivery/phase-01/ticket-01-get-user.md b/docs/02-delivery/phase-01/ticket-01-get-user.md index 416c5609..8b2eebb7 100644 --- a/docs/02-delivery/phase-01/ticket-01-get-user.md +++ b/docs/02-delivery/phase-01/ticket-01-get-user.md @@ -32,9 +32,10 @@ Size: 1 point ## Rationale -> Append here during implementation. +`getSession()` trusts the client-provided JWT without server-side verification, so a forged or replayed token would be accepted. `getUser()` validates the token against the Supabase auth server, closing the security gap. -Red first: -Why this path: -Alternative considered: -Deferred: +**Why this path:** Kept `getSession` as the public Locals API name (backward compat with all 3 callers) and changed internals only: call `getUser()` first; return `null` on error or missing user; then call `getSession()` to return the full `Session` object. No type changes, no caller changes. + +**Alternative considered:** Rename the local to `getUser` returning `User | null` — would require touching `+layout.server.ts`, `login/+page.server.ts`, `account/+page.server.ts`, and `app.d.ts`. Out of scope for a 1-point ticket. + +**Deferred:** Removing the internal `getSession()` call (making `getUser()` the sole auth source) — deferred because callers depend on the `Session` type having `access_token`, `refresh_token` etc. that `User` lacks. diff --git a/notes/public/revival-roadmap.md b/notes/public/revival-roadmap.md index 5e562439..46f8c67c 100644 --- a/notes/public/revival-roadmap.md +++ b/notes/public/revival-roadmap.md @@ -23,6 +23,9 @@ - `axios` → replace with native `fetch` for internal SvelteKit API route calls (one less dep, no behavior change) - MSW v1→v2 API incompatibility — migrated to `http.get` / `HttpResponse` (done 2026-05-02) +### Fix CI — Playwright workflow disabled (2026-05-02) +The Playwright workflow trigger changed from `push`/`pull_request` to `workflow_dispatch` (manual only). Root cause: Vercel preview deployments are password-protected, so `wait-for-vercel-preview` always times out with 401. Fix: either make previews public, or pass a Vercel bypass token (`VERCEL_AUTOMATION_BYPASS_SECRET`) as a workflow secret so the health-check step gets a 200. + ### Fix CI — Lint and Test jobs disabled (2026-05-02) Both jobs are disabled in `.github/workflows/ci.yaml` until root causes are resolved: diff --git a/src/hooks.server.ts b/src/hooks.server.ts index 2d77f672..88e092a4 100644 --- a/src/hooks.server.ts +++ b/src/hooks.server.ts @@ -36,11 +36,25 @@ export const handle: Handle = async ({ event, resolve }) => { }, ) + let cachedSession: Session | null | undefined event.locals.getSession = async () => { + if (cachedSession !== undefined) return cachedSession + + const { + data: { user }, + error, + } = await event.locals.supabase.auth.getUser() + + if (error || !user) { + cachedSession = null + return null + } + const { data: { session }, } = await event.locals.supabase.auth.getSession() + cachedSession = session return session }