diff --git a/web/src/auth-state.ts b/web/src/auth-state.ts index 058b96900..8729febab 100644 --- a/web/src/auth-state.ts +++ b/web/src/auth-state.ts @@ -62,6 +62,19 @@ export const isTokenExpired = (bufferMs: number = 30000): boolean => { return new Date() >= new Date(tokenExpiresAt.getTime() - bufferMs); }; +// Returns true if a token exists in sessionStorage, even if it is expired. +// Used to decide whether to attempt GetCurrentUser on app init — if no token +// was ever stored, the user is definitively not logged in and there is nothing +// to refresh, so we can skip the network round-trip entirely. +export const hasStoredToken = (): boolean => { + if (accessToken) return true; + try { + return !!sessionStorage.getItem(SESSION_TOKEN_KEY); + } catch { + return false; + } +}; + export const clearAccessToken = (): void => { accessToken = null; tokenExpiresAt = null; diff --git a/web/src/contexts/AuthContext.tsx b/web/src/contexts/AuthContext.tsx index 4615d2215..0ce0741dd 100644 --- a/web/src/contexts/AuthContext.tsx +++ b/web/src/contexts/AuthContext.tsx @@ -1,6 +1,6 @@ import { useQueryClient } from "@tanstack/react-query"; import { createContext, type ReactNode, useCallback, useContext, useMemo, useState } from "react"; -import { clearAccessToken } from "@/auth-state"; +import { clearAccessToken, hasStoredToken } from "@/auth-state"; import { authServiceClient, shortcutServiceClient, userServiceClient } from "@/connect"; import { userKeys } from "@/hooks/useUserQueries"; import type { Shortcut } from "@/types/proto/api/v1/shortcut_service_pb"; @@ -52,6 +52,21 @@ export function AuthProvider({ children }: { children: ReactNode }) { const initialize = useCallback(async () => { setState((prev) => ({ ...prev, isLoading: true })); + + // If there is no stored token at all, the user is not authenticated. + // Skip the network call — there is nothing to refresh and no session to restore. + if (!hasStoredToken()) { + setState({ + currentUser: undefined, + userGeneralSetting: undefined, + userWebhooksSetting: undefined, + shortcuts: [], + isInitialized: true, + isLoading: false, + }); + return; + } + try { const { user: currentUser } = await authServiceClient.getCurrentUser({});