mirror of
https://github.com/openclaw/openclaw.git
synced 2026-04-12 09:41:11 +00:00
fix: harden local TLS gateway probes (#61935) (thanks @ThanhNguyxn07)
This commit is contained in:
@@ -35,6 +35,7 @@ Docs: https://docs.openclaw.ai
|
||||
- TUI/terminal: restore Kitty keyboard protocol and `modifyOtherKeys` state on TUI exit and fatal CLI crashes so parent shells stop inheriting broken keyboard input after `openclaw tui` exits. (#49130) Thanks @biefan.
|
||||
- Docs/i18n: relocalize final localized-page links after translation so generated locale pages stop keeping stale English-root links when targets appear later in the same run. (#61796) thanks @hxy91819.
|
||||
- iOS/Watch exec approvals: keep Apple Watch review and approval recovery working while the iPhone is locked or backgrounded, including background-safe reconnects, persisted pending approvals, notification cleanup, and APNs-backed watch refresh recovery. (#61757) Thanks @ngutman.
|
||||
- Gateway/status: probe local TLS gateways over `wss://`, forward the local cert fingerprint for self-signed loopback probes, and warn when the local TLS runtime cannot load the configured cert. (#61935) Thanks @ThanhNguyxn07.
|
||||
|
||||
## 2026.4.5
|
||||
|
||||
|
||||
@@ -664,6 +664,45 @@ describe("gateway-status command", () => {
|
||||
);
|
||||
});
|
||||
|
||||
it("warns when local TLS is enabled but the certificate fingerprint cannot be loaded", async () => {
|
||||
const { runtime, runtimeLogs } = createRuntimeCapture();
|
||||
probeGateway.mockClear();
|
||||
loadGatewayTlsRuntime.mockResolvedValueOnce({
|
||||
enabled: false,
|
||||
required: true,
|
||||
error: "gateway tls: cert/key missing",
|
||||
});
|
||||
readBestEffortConfig.mockResolvedValueOnce({
|
||||
gateway: {
|
||||
mode: "local",
|
||||
tls: { enabled: true },
|
||||
auth: { mode: "token", token: "ltok" },
|
||||
},
|
||||
} as never);
|
||||
|
||||
await runGatewayStatus(runtime, { timeout: "15000", json: true });
|
||||
|
||||
expect(probeGateway).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
url: "wss://127.0.0.1:18789",
|
||||
tlsFingerprint: undefined,
|
||||
}),
|
||||
);
|
||||
|
||||
const parsed = JSON.parse(runtimeLogs.join("\n")) as {
|
||||
warnings?: Array<{ code?: string; message?: string; targetIds?: string[] }>;
|
||||
};
|
||||
expect(parsed.warnings).toContainEqual(
|
||||
expect.objectContaining({
|
||||
code: "local_tls_runtime_unavailable",
|
||||
targetIds: ["localLoopback"],
|
||||
}),
|
||||
);
|
||||
expect(
|
||||
parsed.warnings?.find((warning) => warning.code === "local_tls_runtime_unavailable")?.message,
|
||||
).toContain("gateway tls: cert/key missing");
|
||||
});
|
||||
|
||||
it("passes the full caller timeout through to local loopback probes", async () => {
|
||||
const { runtime } = createRuntimeCapture();
|
||||
probeGateway.mockClear();
|
||||
|
||||
@@ -122,6 +122,10 @@ export async function gatewayStatusCommand(
|
||||
sshTarget: probePass.sshTarget,
|
||||
sshTunnelStarted: probePass.sshTunnelStarted,
|
||||
sshTunnelError: probePass.sshTunnelError,
|
||||
localTlsLoadError:
|
||||
localTlsRuntime && !localTlsRuntime.enabled && localTlsRuntime.required
|
||||
? (localTlsRuntime.error ?? "gateway tls is enabled but local TLS runtime could not load")
|
||||
: null,
|
||||
});
|
||||
const primary = pickPrimaryProbedTarget(probePass.probed);
|
||||
|
||||
|
||||
@@ -32,6 +32,7 @@ export function buildGatewayStatusWarnings(params: {
|
||||
sshTarget: string | null;
|
||||
sshTunnelStarted: boolean;
|
||||
sshTunnelError: string | null;
|
||||
localTlsLoadError?: string | null;
|
||||
}): GatewayStatusWarning[] {
|
||||
const reachable = params.probed.filter((entry) => isProbeReachable(entry.probe));
|
||||
const degradedScopeLimited = params.probed.filter((entry) =>
|
||||
@@ -46,6 +47,13 @@ export function buildGatewayStatusWarnings(params: {
|
||||
: "SSH tunnel failed to start; falling back to direct probes.",
|
||||
});
|
||||
}
|
||||
if (params.localTlsLoadError) {
|
||||
warnings.push({
|
||||
code: "local_tls_runtime_unavailable",
|
||||
message: `Local gateway TLS is enabled but OpenClaw could not load the local certificate fingerprint: ${params.localTlsLoadError}`,
|
||||
targetIds: ["localLoopback"],
|
||||
});
|
||||
}
|
||||
if (reachable.length > 1) {
|
||||
warnings.push({
|
||||
code: "multiple_gateways",
|
||||
|
||||
Reference in New Issue
Block a user