fix(gateway): improve auth error for native apps

Fixes #2268

When macOS/iOS/Android apps fail to connect due to missing auth token,
the error message now clearly explains that gateway.remote.token needs
to be set in ~/.clawdbot/clawdbot.json to match gateway.auth.token on
the server.

Before: 'unauthorized: gateway token missing (provide gateway auth token)'
After: 'unauthorized: gateway token missing (set gateway.remote.token in ~/.clawdbot/clawdbot.json to match gateway.auth.token on the server)'

This eliminates confusion when switching to remote mode over SSH.
This commit is contained in:
Episkey 2026-01-27 11:00:26 +08:00
parent dce7925e2a
commit d91765df74
2 changed files with 15 additions and 6 deletions

View File

@ -79,6 +79,7 @@ Status: unreleased.
- Gateway: default auth now fail-closed (token/password required; Tailscale Serve identity remains allowed). - Gateway: default auth now fail-closed (token/password required; Tailscale Serve identity remains allowed).
- Gateway: treat loopback + non-local Host connections as remote unless trusted proxy headers are present. - Gateway: treat loopback + non-local Host connections as remote unless trusted proxy headers are present.
- Onboarding: remove unsupported gateway auth "off" choice from onboarding/configure flows and CLI flags. - Onboarding: remove unsupported gateway auth "off" choice from onboarding/configure flows and CLI flags.
- Gateway: improve auth error message for native apps (macOS/iOS/Android) to clarify gateway.remote.token setup. (#2268)
## 2026.1.24-3 ## 2026.1.24-3

View File

@ -83,17 +83,25 @@ function formatGatewayAuthFailureMessage(params: {
const isCli = isGatewayCliClient(client); const isCli = isGatewayCliClient(client);
const isControlUi = client?.id === GATEWAY_CLIENT_IDS.CONTROL_UI; const isControlUi = client?.id === GATEWAY_CLIENT_IDS.CONTROL_UI;
const isWebchat = isWebchatClient(client); const isWebchat = isWebchatClient(client);
const isMacOsApp = client?.id === GATEWAY_CLIENT_IDS.MACOS_APP;
const isIosApp = client?.id === GATEWAY_CLIENT_IDS.IOS_APP;
const isAndroidApp = client?.id === GATEWAY_CLIENT_IDS.ANDROID_APP;
const isNativeApp = isMacOsApp || isIosApp || isAndroidApp;
const uiHint = "open a tokenized dashboard URL or paste token in Control UI settings"; const uiHint = "open a tokenized dashboard URL or paste token in Control UI settings";
const tokenHint = isCli const tokenHint = isCli
? "set gateway.remote.token to match gateway.auth.token" ? "set gateway.remote.token to match gateway.auth.token"
: isControlUi || isWebchat : isNativeApp
? uiHint ? "set gateway.remote.token in ~/.clawdbot/clawdbot.json to match gateway.auth.token on the server"
: "provide gateway auth token"; : isControlUi || isWebchat
? uiHint
: "provide gateway auth token";
const passwordHint = isCli const passwordHint = isCli
? "set gateway.remote.password to match gateway.auth.password" ? "set gateway.remote.password to match gateway.auth.password"
: isControlUi || isWebchat : isNativeApp
? "enter the password in Control UI settings" ? "set gateway.remote.password in ~/.clawdbot/clawdbot.json to match gateway.auth.password on the server"
: "provide gateway auth password"; : isControlUi || isWebchat
? "enter the password in Control UI settings"
: "provide gateway auth password";
switch (reason) { switch (reason) {
case "token_missing": case "token_missing":
return `unauthorized: gateway token missing (${tokenHint})`; return `unauthorized: gateway token missing (${tokenHint})`;