fix(security): make csrfFetch a function to respect vi.stubGlobal mocks
All checks were successful
CI / Unit & Component Tests (pull_request) Successful in 3m34s
CI / OCR Service Tests (pull_request) Successful in 19s
CI / Backend Unit Tests (pull_request) Successful in 3m45s
CI / fail2ban Regex (pull_request) Successful in 43s
CI / Semgrep Security Scan (pull_request) Successful in 20s
CI / Compose Bucket Idempotency (pull_request) Successful in 1m5s

The previous `export const csrfFetch = makeCsrfFetch(fetch)` captured the
global fetch at module evaluation time. Tests that mock fetch via
`vi.stubGlobal('fetch', mockFetch)` set up their stub *after* module import,
so all calls through csrfFetch bypassed the mock — 21 browser tests saw 0
fetch calls.

Changing csrfFetch to a plain function means `fetch` is resolved from the
global scope at each call site, picking up whatever stub is in place at
call time. Production behaviour is identical; test isolation is restored.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Marcel
2026-05-30 11:37:53 +02:00
parent 58254b492b
commit 5d8d85057d

View File

@@ -45,8 +45,18 @@ export function makeCsrfFetch(inner: typeof fetch): typeof fetch {
* Drop-in replacement for fetch that automatically injects X-XSRF-TOKEN on
* all mutating requests (POST, PUT, PATCH, DELETE). Use this everywhere in
* client-side code instead of bare fetch + withCsrf().
*
* Implemented as a function (not a module-level const) so that test stubs
* applied via vi.stubGlobal('fetch', mock) are picked up at call time rather
* than being silently bypassed by a pre-captured reference.
*/
export const csrfFetch = makeCsrfFetch(fetch);
export function csrfFetch(input: RequestInfo | URL, init?: RequestInit): Promise<Response> {
const method = (init?.method ?? 'GET').toUpperCase();
if (['POST', 'PUT', 'PATCH', 'DELETE'].includes(method)) {
return fetch(input, withCsrf(init));
}
return fetch(input, init);
}
/**
* Extracts the fa_session cookie value from a list of Set-Cookie response headers.