From a5e33ac72b8700c641175f998395f074d45f0dc3 Mon Sep 17 00:00:00 2001 From: Jared Wolff Date: Wed, 4 Mar 2026 18:51:39 -0500 Subject: [PATCH] fix(auth): await logout fetch to prevent token refresh race condition The logout function fired a non-awaited POST /logout then immediately redirected to /login. The login page's session probe would find the cookies still valid and refresh the token, redirecting back to the app. Fix by awaiting the fetch and clearing local state before redirect. --- static/js/app/userMenu.js | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/static/js/app/userMenu.js b/static/js/app/userMenu.js index c3522b96..5d2fa7b2 100644 --- a/static/js/app/userMenu.js +++ b/static/js/app/userMenu.js @@ -223,17 +223,24 @@ function showUserProfileModal() { }); } -function logout() { +async function logout() { const USER_DATA_KEY = 'oxicloud_user'; - // Tell the server to clear HttpOnly cookies - fetch('/api/auth/logout', { method: 'POST', credentials: 'same-origin', headers: getCsrfHeaders() }) - .catch(() => {}) // Best-effort - .finally(() => { - localStorage.removeItem(USER_DATA_KEY); - sessionStorage.removeItem('redirect_count'); - window.location.href = '/login'; - }); + // Clear local state first to prevent login page from auto-refreshing + localStorage.removeItem(USER_DATA_KEY); + localStorage.removeItem('refresh_attempts'); + sessionStorage.removeItem('redirect_count'); + + // Tell the server to clear HttpOnly cookies (await to ensure cookies are + // cleared before redirecting, otherwise the login page's session probe + // will refresh the token and redirect back to the app). + try { + await fetch('/api/auth/logout', { method: 'POST', credentials: 'same-origin', headers: getCsrfHeaders() }); + } catch (_) { + // Best-effort + } + + window.location.href = '/login'; } window.setupUserMenu = setupUserMenu;