From 4d5b9e88dd1d045582d890b07e39a52e2efa193d Mon Sep 17 00:00:00 2001 From: busya Date: Wed, 25 Feb 2026 20:58:14 +0300 Subject: [PATCH] fix(auth): defer environment context fetch until token is available --- frontend/src/lib/stores/environmentContext.js | 29 +++++++++++++++++-- frontend/src/routes/+layout.svelte | 8 ----- 2 files changed, 27 insertions(+), 10 deletions(-) diff --git a/frontend/src/lib/stores/environmentContext.js b/frontend/src/lib/stores/environmentContext.js index 4a8f2f1..5cdfe78 100644 --- a/frontend/src/lib/stores/environmentContext.js +++ b/frontend/src/lib/stores/environmentContext.js @@ -4,6 +4,7 @@ // @LAYER: UI-State import { derived, get, writable } from "svelte/store"; +import { browser } from "$app/environment"; import { api } from "$lib/api.js"; const INITIAL_STATE = { @@ -18,12 +19,12 @@ const SELECTED_ENV_KEY = "selected_env_id"; const contextStore = writable(INITIAL_STATE); function getStoredSelectedEnvId() { - if (typeof window === "undefined") return ""; + if (!browser) return ""; return localStorage.getItem(SELECTED_ENV_KEY) || ""; } function persistSelectedEnvId(envId) { - if (typeof window === "undefined") return; + if (!browser) return; if (!envId) { localStorage.removeItem(SELECTED_ENV_KEY); return; @@ -31,6 +32,11 @@ function persistSelectedEnvId(envId) { localStorage.setItem(SELECTED_ENV_KEY, envId); } +function hasAuthToken() { + if (!browser) return false; + return Boolean(localStorage.getItem("auth_token")); +} + function resolveSelectedEnvId(environments, preferredEnvId) { if (!Array.isArray(environments) || environments.length === 0) return ""; if (preferredEnvId && environments.some((env) => env.id === preferredEnvId)) { @@ -53,6 +59,16 @@ function applySelectedEnvId(selectedEnvId) { } async function refreshEnvironmentContext(preferredEnvId = "") { + if (!hasAuthToken()) { + contextStore.update((state) => ({ + ...state, + isLoading: false, + isLoaded: false, + error: null, + })); + return; + } + contextStore.update((state) => ({ ...state, isLoading: true, error: null })); try { const environments = await api.getEnvironmentsList(); @@ -71,6 +87,15 @@ async function refreshEnvironmentContext(preferredEnvId = "") { error: null, })); } catch (error) { + if (error?.status === 401) { + contextStore.update((state) => ({ + ...state, + isLoading: false, + isLoaded: false, + error: null, + })); + return; + } console.error( "[environmentContext][Coherence:Failed] Failed to refresh environments", error, diff --git a/frontend/src/routes/+layout.svelte b/frontend/src/routes/+layout.svelte index 8c254c0..6a79f5f 100644 --- a/frontend/src/routes/+layout.svelte +++ b/frontend/src/routes/+layout.svelte @@ -23,7 +23,6 @@ @INVARIANT: Login route bypasses shell; all other routes are wrapped by ProtectedRoute. -->