diff --git a/frontend/src/components/settings/DaydreamAccountSection.tsx b/frontend/src/components/settings/DaydreamAccountSection.tsx index 01df7ffb1..5bd8c130d 100644 --- a/frontend/src/components/settings/DaydreamAccountSection.tsx +++ b/frontend/src/components/settings/DaydreamAccountSection.tsx @@ -56,8 +56,11 @@ export function DaydreamAccountSection({ setShowCloudMode(shouldShowCloudMode()); // If signed in but no display name cached, refresh the profile + // Only attempt if we have valid stored auth (not just env var fallback) if (authed && !cachedName) { - refreshUserProfile(); + refreshUserProfile().catch(() => { + // If refresh fails (e.g. 401), auth state will be cleared automatically + }); } const handleAuthChange = () => { diff --git a/frontend/src/lib/auth.ts b/frontend/src/lib/auth.ts index e7e837353..66e11a089 100644 --- a/frontend/src/lib/auth.ts +++ b/frontend/src/lib/auth.ts @@ -104,6 +104,12 @@ async function fetchUserProfile(apiKey: string): Promise { const response = await fetch(`${DAYDREAM_API_BASE}/users/profile`, { headers: { Authorization: `Bearer ${apiKey}` }, }); + if (response.status === 401) { + // Clear invalid auth data to prevent repeated 401 polling + localStorage.removeItem(AUTH_STORAGE_KEY); + window.dispatchEvent(new CustomEvent("daydream-auth-change")); + throw new Error("Authentication expired or invalid"); + } if (!response.ok) { throw new Error(`Failed to fetch profile: ${response.status}`); } @@ -182,10 +188,11 @@ export async function saveDaydreamAuth( /** * Refresh user profile in localStorage (for existing auth) + * Only makes API call if user has valid stored auth credentials. */ export async function refreshUserProfile(): Promise { const authData = getAuthData(); - if (!authData) return; + if (!authData?.apiKey) return; try { const profile = await fetchUserProfile(authData.apiKey);