From fd8a8ecba2a31235a00668c5e7a9731bed2db53c Mon Sep 17 00:00:00 2001 From: kolaente Date: Fri, 3 Apr 2026 20:18:03 +0200 Subject: [PATCH] fix(auth): normalize API base URL to prevent refresh cookie path mismatch When window.API_URL lacks a trailing slash, axios resolves relative URLs by stripping path segments, causing the refresh request to hit a different path than the cookie's Path attribute. The browser then omits the HttpOnly refresh cookie, silently breaking token renewal and logging users out after the short JWT TTL expires. Extract a getApiBaseUrl() helper that ensures baseURL always ends with '/' so relative URL resolution preserves the full path, matching the cookie scope. Ref: #2391 --- frontend/src/helpers/fetcher.ts | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/frontend/src/helpers/fetcher.ts b/frontend/src/helpers/fetcher.ts index f0fa4f9c2..66c89a64a 100644 --- a/frontend/src/helpers/fetcher.ts +++ b/frontend/src/helpers/fetcher.ts @@ -3,9 +3,17 @@ import type {AxiosRequestConfig} from 'axios' import {getToken, refreshToken} from '@/helpers/auth' import {AUTH_TYPES} from '@/modelTypes/IUser' +/** + * Returns the API base URL with a guaranteed trailing slash. + */ +export function getApiBaseUrl(): string { + const url = window.API_URL + return url?.endsWith('/') ? url : url + '/' +} + export function HTTPFactory() { const instance = axios.create({ - baseURL: window.API_URL, + baseURL: getApiBaseUrl(), // Ensure the browser sends and accepts cookies (e.g. the HttpOnly // refresh token) even when the API is on a different origin. withCredentials: true, @@ -14,7 +22,7 @@ export function HTTPFactory() { instance.interceptors.request.use((config) => { // by setting the baseURL fresh for every request // we make sure that it is never outdated in case it is updated - config.baseURL = window.API_URL + config.baseURL = getApiBaseUrl() return config })