diff --git a/app/src/api/api.ts b/app/src/api/api.ts index 53a3931..6f97c76 100644 --- a/app/src/api/api.ts +++ b/app/src/api/api.ts @@ -1,5 +1,22 @@ import { refreshToken } from './auth'; +/** + * Gets the CSRF token from cookies + * @returns {string} The CSRF token or an empty string if not found + */ +const getCsrfToken = (): string => { + const cookies = document.cookie.split(';'); + let csrfToken = ''; + for (const cookie of cookies) { + const [name, value] = cookie.trim().split('='); + if (name === 'csrf_token' && value) { + csrfToken = decodeURIComponent(value); + break; + } + } + return csrfToken; +}; + /** * Makes an API call with proper cookie handling and error handling */ @@ -9,14 +26,26 @@ export const apiCall = async ( ): Promise => { console.debug(`Making API call to: ${url}`); try { + // Set up headers with CSRF token for non-GET requests + const method = options.method || 'GET'; + const headers: Record = { + 'Content-Type': 'application/json', + ...(options.headers as Record), + }; + + // Add CSRF token for non-GET methods + if (method !== 'GET') { + const csrfToken = getCsrfToken(); + if (csrfToken) { + headers['X-CSRF-Token'] = csrfToken; + } + } + const response = await fetch(url, { ...options, // Include credentials to send/receive cookies credentials: 'include', - headers: { - 'Content-Type': 'application/json', - ...options.headers, - }, + headers, }); console.debug(`Response status: ${response.status} for URL: ${url}`);