fix(status): show gateway auth when reachable
This commit is contained in:
@@ -31,6 +31,7 @@ import { getAgentLocalStatuses } from "./status-all/agents.js";
|
|||||||
import {
|
import {
|
||||||
formatAge,
|
formatAge,
|
||||||
formatDuration,
|
formatDuration,
|
||||||
|
formatGatewayAuthUsed,
|
||||||
redactSecrets,
|
redactSecrets,
|
||||||
} from "./status-all/format.js";
|
} from "./status-all/format.js";
|
||||||
import {
|
import {
|
||||||
@@ -282,6 +283,9 @@ export async function statusAllCommand(
|
|||||||
: gatewayProbe?.error
|
: gatewayProbe?.error
|
||||||
? `unreachable (${gatewayProbe.error})`
|
? `unreachable (${gatewayProbe.error})`
|
||||||
: "unreachable";
|
: "unreachable";
|
||||||
|
const gatewayAuth = gatewayReachable
|
||||||
|
? ` · auth ${formatGatewayAuthUsed(remoteUrlMissing ? localFallbackAuth : remoteAuth)}`
|
||||||
|
: "";
|
||||||
const gatewaySelfLine =
|
const gatewaySelfLine =
|
||||||
gatewaySelf?.host ||
|
gatewaySelf?.host ||
|
||||||
gatewaySelf?.ip ||
|
gatewaySelf?.ip ||
|
||||||
@@ -319,7 +323,7 @@ export async function statusAllCommand(
|
|||||||
{ Item: "Update", Value: updateLine },
|
{ Item: "Update", Value: updateLine },
|
||||||
{
|
{
|
||||||
Item: "Gateway",
|
Item: "Gateway",
|
||||||
Value: `${gatewayMode}${remoteUrlMissing ? " (remote.url missing)" : ""} · ${gatewayTarget} (${connection.urlSource}) · ${gatewayStatus}`,
|
Value: `${gatewayMode}${remoteUrlMissing ? " (remote.url missing)" : ""} · ${gatewayTarget} (${connection.urlSource}) · ${gatewayStatus}${gatewayAuth}`,
|
||||||
},
|
},
|
||||||
gatewaySelfLine
|
gatewaySelfLine
|
||||||
? { Item: "Gateway self", Value: gatewaySelfLine }
|
? { Item: "Gateway self", Value: gatewaySelfLine }
|
||||||
|
|||||||
@@ -15,6 +15,20 @@ export const formatDuration = (ms: number | null | undefined) => {
|
|||||||
return `${(ms / 1000).toFixed(1)}s`;
|
return `${(ms / 1000).toFixed(1)}s`;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export function formatGatewayAuthUsed(
|
||||||
|
auth: {
|
||||||
|
token?: string;
|
||||||
|
password?: string;
|
||||||
|
} | null,
|
||||||
|
): "token" | "password" | "token+password" | "none" {
|
||||||
|
const hasToken = Boolean(auth?.token?.trim());
|
||||||
|
const hasPassword = Boolean(auth?.password?.trim());
|
||||||
|
if (hasToken && hasPassword) return "token+password";
|
||||||
|
if (hasToken) return "token";
|
||||||
|
if (hasPassword) return "password";
|
||||||
|
return "none";
|
||||||
|
}
|
||||||
|
|
||||||
export function redactSecrets(text: string): string {
|
export function redactSecrets(text: string): string {
|
||||||
if (!text) return text;
|
if (!text) return text;
|
||||||
let out = text;
|
let out = text;
|
||||||
|
|||||||
@@ -150,4 +150,29 @@ describe("statusCommand", () => {
|
|||||||
expect(logs.some((l) => l.includes("FAQ:"))).toBe(true);
|
expect(logs.some((l) => l.includes("FAQ:"))).toBe(true);
|
||||||
expect(logs.some((l) => l.includes("Troubleshooting:"))).toBe(true);
|
expect(logs.some((l) => l.includes("Troubleshooting:"))).toBe(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("shows gateway auth when reachable", async () => {
|
||||||
|
const prevToken = process.env.CLAWDBOT_GATEWAY_TOKEN;
|
||||||
|
process.env.CLAWDBOT_GATEWAY_TOKEN = "abcd1234";
|
||||||
|
try {
|
||||||
|
mocks.probeGateway.mockResolvedValueOnce({
|
||||||
|
ok: true,
|
||||||
|
url: "ws://127.0.0.1:18789",
|
||||||
|
connectLatencyMs: 123,
|
||||||
|
error: null,
|
||||||
|
close: null,
|
||||||
|
health: {},
|
||||||
|
status: {},
|
||||||
|
presence: [],
|
||||||
|
configSnapshot: null,
|
||||||
|
});
|
||||||
|
(runtime.log as vi.Mock).mockClear();
|
||||||
|
await statusCommand({}, runtime as never);
|
||||||
|
const logs = (runtime.log as vi.Mock).mock.calls.map((c) => String(c[0]));
|
||||||
|
expect(logs.some((l) => l.includes("auth token"))).toBe(true);
|
||||||
|
} finally {
|
||||||
|
if (prevToken === undefined) delete process.env.CLAWDBOT_GATEWAY_TOKEN;
|
||||||
|
else process.env.CLAWDBOT_GATEWAY_TOKEN = prevToken;
|
||||||
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ import { resolveHeartbeatSeconds } from "../web/reconnect.js";
|
|||||||
import { getWebAuthAgeMs, webAuthExists } from "../web/session.js";
|
import { getWebAuthAgeMs, webAuthExists } from "../web/session.js";
|
||||||
import type { HealthSummary } from "./health.js";
|
import type { HealthSummary } from "./health.js";
|
||||||
import { resolveControlUiLinks } from "./onboard-helpers.js";
|
import { resolveControlUiLinks } from "./onboard-helpers.js";
|
||||||
|
import { formatGatewayAuthUsed } from "./status-all/format.js";
|
||||||
import { buildProvidersTable } from "./status-all/providers.js";
|
import { buildProvidersTable } from "./status-all/providers.js";
|
||||||
import { statusAllCommand } from "./status-all.js";
|
import { statusAllCommand } from "./status-all.js";
|
||||||
|
|
||||||
@@ -714,6 +715,10 @@ export async function statusCommand(
|
|||||||
? `unreachable (${gatewayProbe.error})`
|
? `unreachable (${gatewayProbe.error})`
|
||||||
: "unreachable",
|
: "unreachable",
|
||||||
);
|
);
|
||||||
|
const auth =
|
||||||
|
gatewayReachable && !remoteUrlMissing
|
||||||
|
? ` · auth ${formatGatewayAuthUsed(resolveGatewayProbeAuth(cfg))}`
|
||||||
|
: "";
|
||||||
const self =
|
const self =
|
||||||
gatewaySelf?.host || gatewaySelf?.version || gatewaySelf?.platform
|
gatewaySelf?.host || gatewaySelf?.version || gatewaySelf?.platform
|
||||||
? [
|
? [
|
||||||
@@ -726,7 +731,7 @@ export async function statusCommand(
|
|||||||
.join(" ")
|
.join(" ")
|
||||||
: null;
|
: null;
|
||||||
const suffix = self ? ` · ${self}` : "";
|
const suffix = self ? ` · ${self}` : "";
|
||||||
return `${gatewayMode} · ${target} · ${reach}${suffix}`;
|
return `${gatewayMode} · ${target} · ${reach}${auth}${suffix}`;
|
||||||
})();
|
})();
|
||||||
|
|
||||||
const agentsValue = (() => {
|
const agentsValue = (() => {
|
||||||
|
|||||||
Reference in New Issue
Block a user