fix(auth): defer environment context fetch until token is available
This commit is contained in:
@@ -4,6 +4,7 @@
|
|||||||
// @LAYER: UI-State
|
// @LAYER: UI-State
|
||||||
|
|
||||||
import { derived, get, writable } from "svelte/store";
|
import { derived, get, writable } from "svelte/store";
|
||||||
|
import { browser } from "$app/environment";
|
||||||
import { api } from "$lib/api.js";
|
import { api } from "$lib/api.js";
|
||||||
|
|
||||||
const INITIAL_STATE = {
|
const INITIAL_STATE = {
|
||||||
@@ -18,12 +19,12 @@ const SELECTED_ENV_KEY = "selected_env_id";
|
|||||||
const contextStore = writable(INITIAL_STATE);
|
const contextStore = writable(INITIAL_STATE);
|
||||||
|
|
||||||
function getStoredSelectedEnvId() {
|
function getStoredSelectedEnvId() {
|
||||||
if (typeof window === "undefined") return "";
|
if (!browser) return "";
|
||||||
return localStorage.getItem(SELECTED_ENV_KEY) || "";
|
return localStorage.getItem(SELECTED_ENV_KEY) || "";
|
||||||
}
|
}
|
||||||
|
|
||||||
function persistSelectedEnvId(envId) {
|
function persistSelectedEnvId(envId) {
|
||||||
if (typeof window === "undefined") return;
|
if (!browser) return;
|
||||||
if (!envId) {
|
if (!envId) {
|
||||||
localStorage.removeItem(SELECTED_ENV_KEY);
|
localStorage.removeItem(SELECTED_ENV_KEY);
|
||||||
return;
|
return;
|
||||||
@@ -31,6 +32,11 @@ function persistSelectedEnvId(envId) {
|
|||||||
localStorage.setItem(SELECTED_ENV_KEY, envId);
|
localStorage.setItem(SELECTED_ENV_KEY, envId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function hasAuthToken() {
|
||||||
|
if (!browser) return false;
|
||||||
|
return Boolean(localStorage.getItem("auth_token"));
|
||||||
|
}
|
||||||
|
|
||||||
function resolveSelectedEnvId(environments, preferredEnvId) {
|
function resolveSelectedEnvId(environments, preferredEnvId) {
|
||||||
if (!Array.isArray(environments) || environments.length === 0) return "";
|
if (!Array.isArray(environments) || environments.length === 0) return "";
|
||||||
if (preferredEnvId && environments.some((env) => env.id === preferredEnvId)) {
|
if (preferredEnvId && environments.some((env) => env.id === preferredEnvId)) {
|
||||||
@@ -53,6 +59,16 @@ function applySelectedEnvId(selectedEnvId) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function refreshEnvironmentContext(preferredEnvId = "") {
|
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 }));
|
contextStore.update((state) => ({ ...state, isLoading: true, error: null }));
|
||||||
try {
|
try {
|
||||||
const environments = await api.getEnvironmentsList();
|
const environments = await api.getEnvironmentsList();
|
||||||
@@ -71,6 +87,15 @@ async function refreshEnvironmentContext(preferredEnvId = "") {
|
|||||||
error: null,
|
error: null,
|
||||||
}));
|
}));
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
if (error?.status === 401) {
|
||||||
|
contextStore.update((state) => ({
|
||||||
|
...state,
|
||||||
|
isLoading: false,
|
||||||
|
isLoaded: false,
|
||||||
|
error: null,
|
||||||
|
}));
|
||||||
|
return;
|
||||||
|
}
|
||||||
console.error(
|
console.error(
|
||||||
"[environmentContext][Coherence:Failed] Failed to refresh environments",
|
"[environmentContext][Coherence:Failed] Failed to refresh environments",
|
||||||
error,
|
error,
|
||||||
|
|||||||
@@ -23,7 +23,6 @@
|
|||||||
@INVARIANT: Login route bypasses shell; all other routes are wrapped by ProtectedRoute.
|
@INVARIANT: Login route bypasses shell; all other routes are wrapped by ProtectedRoute.
|
||||||
-->
|
-->
|
||||||
<script>
|
<script>
|
||||||
import { onMount } from 'svelte';
|
|
||||||
import '../app.css';
|
import '../app.css';
|
||||||
import Navbar from '../components/Navbar.svelte';
|
import Navbar from '../components/Navbar.svelte';
|
||||||
import Footer from '../components/Footer.svelte';
|
import Footer from '../components/Footer.svelte';
|
||||||
@@ -36,7 +35,6 @@
|
|||||||
import AssistantChatPanel from '$lib/components/assistant/AssistantChatPanel.svelte';
|
import AssistantChatPanel from '$lib/components/assistant/AssistantChatPanel.svelte';
|
||||||
import { t } from '$lib/i18n';
|
import { t } from '$lib/i18n';
|
||||||
import {
|
import {
|
||||||
initializeEnvironmentContext,
|
|
||||||
isProductionContextStore,
|
isProductionContextStore,
|
||||||
selectedEnvironmentStore
|
selectedEnvironmentStore
|
||||||
} from '$lib/stores/environmentContext.js';
|
} from '$lib/stores/environmentContext.js';
|
||||||
@@ -47,12 +45,6 @@
|
|||||||
$: isExpanded = $sidebarStore?.isExpanded || true;
|
$: isExpanded = $sidebarStore?.isExpanded || true;
|
||||||
$: isProductionContext = $isProductionContextStore;
|
$: isProductionContext = $isProductionContextStore;
|
||||||
$: selectedEnvironment = $selectedEnvironmentStore;
|
$: selectedEnvironment = $selectedEnvironmentStore;
|
||||||
|
|
||||||
onMount(async () => {
|
|
||||||
if (!isLoginPage) {
|
|
||||||
await initializeEnvironmentContext();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<Toast />
|
<Toast />
|
||||||
|
|||||||
Reference in New Issue
Block a user