From dd5d5a77c374d0ef78149c0c76b81ff23ba19d44 Mon Sep 17 00:00:00 2001 From: John Coffey Date: Fri, 4 Sep 2026 17:42:26 -0700 Subject: [PATCH] Show the account controls the deployment actually has The sidebar decided which auth mode was live from enterpriseAuthBase, so any deployment with VITE_ENTERPRISE_AUTH_BASE_URL set rendered the enterprise block -- and compose sets it unconditionally, so the tenant picker can exist. On a single-tenant stack with local login on, that meant the local block could never render: no username, no role, no Change password, no Log out, and in their place a "Sign in" link pointing at enterprise-auth's OIDC route, which is disabled unless OIDC_ISSUER_URL is configured. A dead link where the account controls should be. The build-time flag was never the right thing to ask. api registers /auth/* only when LOCAL_AUTH_ENABLED is set and ENTERPRISE_AUTH_URL is not, so the frontend cannot know the mode from its own build args -- the two can disagree, and here they did. getLocalSession already distinguishes 'disabled' (a 404 from /auth/session) from null (a 401, logged out); the sidebar collapsed both to null and threw the answer away. It now keeps that distinction and branches on it, so the mode comes from what the server actually serves. Logged out under local auth, the sidebar previously rendered no auth block at all -- no way back to the login page from the nav. It now offers Sign in, pointing at /login. Neither block renders until the probe lands, so nothing flashes the wrong mode on load. Signed-off-by: John Coffey --- web/src/lib/components/NavSidebar.svelte | 50 +++++++++++++++++------- 1 file changed, 36 insertions(+), 14 deletions(-) diff --git a/web/src/lib/components/NavSidebar.svelte b/web/src/lib/components/NavSidebar.svelte index 446fc16..f74c7f1 100644 --- a/web/src/lib/components/NavSidebar.svelte +++ b/web/src/lib/components/NavSidebar.svelte @@ -42,9 +42,27 @@ }); let localSession: LocalSession | null = $state(null); + // Whether the server actually serves local auth, which is not the + // same question as whether this bundle was built with it enabled. + // api registers /auth/* only when LOCAL_AUTH_ENABLED is set AND + // ENTERPRISE_AUTH_URL is not (see cmd/api/main.go's authorizer + // switch), so getLocalSession's 'disabled' -- a 404 from + // /auth/session -- is the only trustworthy signal of which mode is + // live. Deciding from enterpriseAuthBase alone got this wrong: + // compose sets VITE_ENTERPRISE_AUTH_BASE_URL unconditionally so the + // tenant picker can exist, so that check was true even on a + // single-tenant deployment whose actual authenticator was local + // login, and the local block below could never render. + // + // null means "not yet known" -- neither block renders until the + // probe lands, rather than flashing the wrong one. + let localAuthAvailable: boolean | null = $state(localAuthEnabled ? null : false); $effect(() => { if (!localAuthEnabled) return; - getLocalSession().then((s) => (localSession = s === 'disabled' ? null : s)); + getLocalSession().then((s) => { + localAuthAvailable = s !== 'disabled'; + localSession = s === 'disabled' ? null : s; + }); }); // The Users nav item only ever makes sense for local-auth mode's @@ -90,7 +108,23 @@ - {#if enterpriseAuthBase} + {#if localAuthAvailable} +
+ {#if localSession} +
+ + {localSession.username} + {localSession.role} +
+ Change password + + {:else} + + {/if} +
+ {:else if localAuthAvailable === false && enterpriseAuthBase}
{#if session}
@@ -103,18 +137,6 @@ {/if}
- {:else if localAuthEnabled && localSession} -
-
- - {localSession.username} - {localSession.role} -
- Change password - -
{/if}