From bf590c81d0bc800e2e0ef1fa4e4f168a45d1d5bf Mon Sep 17 00:00:00 2001 From: Ben Date: Wed, 3 Jun 2026 13:59:25 +1000 Subject: [PATCH] fix(desktop): hide gateway auth control until probe resolves the scheme The remote-gateway settings rendered the session-token box for every gateway during the idle/probing window before the first /api/status probe lands, because authMode defaults to 'token'. Gate both the OAuth sign-in button and the token box behind an authResolved flag so neither renders until the probe resolves the scheme (or a previously-saved remote config is being re-shown, so re-opening settings doesn't flicker). The gateway-side WS Origin fix that lets the packaged desktop (file:// origin) connect to an OAuth-gated remote gateway landed separately in #37870; this branch is now purely the desktop client + this UI fix. --- .../src/app/settings/gateway-settings.tsx | 24 +++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/apps/desktop/src/app/settings/gateway-settings.tsx b/apps/desktop/src/app/settings/gateway-settings.tsx index 46447a338..3fed72458 100644 --- a/apps/desktop/src/app/settings/gateway-settings.tsx +++ b/apps/desktop/src/app/settings/gateway-settings.tsx @@ -175,6 +175,26 @@ export function GatewaySettings() { return state.remoteAuthMode }, [probe, probeStatus, state.remoteAuthMode]) + // Whether we actually KNOW how this gateway authenticates yet. Until we do, + // neither the OAuth button nor the session-token box should render — + // `authMode` defaults to 'token', so without this gate the token box flashes + // for every gateway (including OAuth ones) during the idle/probing window + // before the first probe lands. The scheme is known when either: + // * the live probe finished (probeStatus 'done'), or + // * we're idle but showing a previously-saved remote config (re-opening + // settings for a gateway already signed-in or with a saved token), so + // its control appears immediately with no flicker. + // While probing (or after a probe error), the scheme is unknown and we show + // the probe status row instead of a control. + const hasSavedRemote = state.remoteTokenSet || state.remoteOauthConnected + const authResolved = useMemo(() => { + if (probeStatus === 'done') { + return true + } + + return probeStatus === 'idle' && hasSavedRemote + }, [probeStatus, hasSavedRemote]) + const providerLabel = useMemo(() => { const providers: DesktopAuthProvider[] = probe?.providers ?? [] @@ -427,7 +447,7 @@ export function GatewaySettings() { ) : null} {/* OAuth gateways: present a sign-in button + connection status. */} - {state.mode === 'remote' && authMode === 'oauth' ? ( + {state.mode === 'remote' && authResolved && authMode === 'oauth' ? (