diff --git a/surfsense_web/hooks/use-session.ts b/surfsense_web/hooks/use-session.ts index 6bb10456f..0012e8763 100644 --- a/surfsense_web/hooks/use-session.ts +++ b/surfsense_web/hooks/use-session.ts @@ -1,6 +1,7 @@ "use client"; import { useCallback, useEffect, useState } from "react"; +import { refreshSession } from "@/lib/auth-utils"; import { buildBackendUrl } from "@/lib/env-config"; type SessionState = @@ -17,6 +18,13 @@ async function getSessionHeaders(): Promise { return token ? { Authorization: `Bearer ${token}` } : {}; } +async function fetchSession(): Promise { + return fetch(buildBackendUrl("/auth/session"), { + credentials: "include", + headers: await getSessionHeaders(), + }); +} + export function useSession() { const [state, setState] = useState({ status: "loading", @@ -26,10 +34,13 @@ export function useSession() { const refresh = useCallback(async () => { try { - const response = await fetch(buildBackendUrl("/auth/session"), { - credentials: "include", - headers: await getSessionHeaders(), - }); + let response = await fetchSession(); + if (response.status === 401) { + const refreshed = await refreshSession(); + if (refreshed) { + response = await fetchSession(); + } + } if (!response.ok) { setState({ status: "unauthenticated", diff --git a/surfsense_web/lib/auth-fetch.ts b/surfsense_web/lib/auth-fetch.ts index 20b236854..4f512c2ca 100644 --- a/surfsense_web/lib/auth-fetch.ts +++ b/surfsense_web/lib/auth-fetch.ts @@ -3,6 +3,10 @@ import { handleUnauthorized, isDesktopClient, refreshSession } from "@/lib/auth- let desktopAccessToken: string | null = null; let didSubscribeToDesktopAuth = false; +type DesktopAccessTokenOptions = { + forceRefresh?: boolean; +}; + function subscribeToDesktopAuth(): void { if (didSubscribeToDesktopAuth || typeof window === "undefined" || !window.electronAPI) { return; @@ -17,10 +21,12 @@ function subscribeToDesktopAuth(): void { }); } -export async function getDesktopAccessToken(): Promise { +export async function getDesktopAccessToken( + options: DesktopAccessTokenOptions = {} +): Promise { if (!isDesktopClient()) return null; subscribeToDesktopAuth(); - if (desktopAccessToken) return desktopAccessToken; + if (desktopAccessToken && !options.forceRefresh) return desktopAccessToken; const token = (await window.electronAPI?.getAccessToken?.()) || null; desktopAccessToken = token; return token; @@ -55,7 +61,7 @@ export async function authenticatedFetch( if (!skipRefresh) { const refreshed = await refreshSession(); if (refreshed) { - const newToken = await getDesktopAccessToken(); + const newToken = await getDesktopAccessToken({ forceRefresh: true }); return fetch(url, { ...fetchOptions, headers: {