From 8a0de78e781a746b9833217f25e5f92bf12c7b29 Mon Sep 17 00:00:00 2001 From: neckfire Date: Tue, 21 Jul 2026 13:57:10 +0200 Subject: [PATCH] =?UTF-8?q?StreakFit=20web:=20fix=20419=20sur=20les=20s?= =?UTF-8?q?=C3=A9ances=20=E2=80=94=20pose=20le=20cookie=20CSRF=20avant=20t?= =?UTF-8?q?oute=20requ=C3=AAte=20mutante?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cause: après login OIDC/pocket-id (ou XSRF cookie absent), le SPA n'avait jamais appelé /sanctum/csrf-cookie -> POST /api/sessions (démarrer une séance) = 419. Fix: useApi.api récupère automatiquement le cookie XSRF si absent avant tout POST/PUT/PATCH/DELETE. Corrige démarrage de séance, log de séries, complete, etc. Co-Authored-By: Claude Opus 4.8 (1M context) --- app/composables/useApi.ts | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/app/composables/useApi.ts b/app/composables/useApi.ts index 5d76f3d..d45db41 100644 --- a/app/composables/useApi.ts +++ b/app/composables/useApi.ts @@ -12,12 +12,21 @@ function readCookie(name: string): string | null { export function useApi() { const base = useRuntimeConfig().public.apiBase as string + const SAFE_METHODS = new Set(['GET', 'HEAD', 'OPTIONS']) + const api = $fetch.create({ baseURL: base, credentials: 'include', headers: { Accept: 'application/json' }, - onRequest({ options }) { - const xsrf = readCookie('XSRF-TOKEN') + async onRequest({ options }) { + const method = String(options.method || 'GET').toUpperCase() + let xsrf = readCookie('XSRF-TOKEN') + // Requête mutante sans cookie XSRF (ex : session ouverte via OIDC/pocket-id qui n'est jamais + // passée par /sanctum/csrf-cookie) → on pose le cookie avant, sinon Sanctum renvoie 419. + if (!xsrf && !SAFE_METHODS.has(method)) { + await ensureCsrf() + xsrf = readCookie('XSRF-TOKEN') + } const headers = new Headers(options.headers as HeadersInit) if (xsrf) headers.set('X-XSRF-TOKEN', xsrf) options.headers = headers