mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-08 18:48:27 +00:00
fix(gateway): use LAN IP for WebSocket/probe URLs when bind=lan (#11448)
* fix(gateway): use LAN IP for WebSocket/probe URLs when bind=lan (#11329) When gateway.bind=lan, the HTTP server correctly binds to 0.0.0.0 (all interfaces), but WebSocket connection URLs, probe targets, and Control UI links were hardcoded to 127.0.0.1. This caused CLI commands and status probes to show localhost-only URLs even in LAN mode, and made onboarding display misleading connection info. - Add pickPrimaryLanIPv4() to gateway/net.ts to detect the machine's primary LAN IPv4 address (prefers en0/eth0, falls back to any external interface) - Update pickProbeHostForBind() to use LAN IP when bind=lan - Update buildGatewayConnectionDetails() to use LAN IP and report "local lan <ip>" as the URL source - Update resolveControlUiLinks() to return LAN-accessible URLs - Update probe note in status.gather.ts to reflect new behavior - Add tests for pickPrimaryLanIPv4 and bind=lan URL resolution Closes #11329 Co-authored-by: Cursor <cursoragent@cursor.com> * test: move vi.restoreAllMocks to afterEach in pickPrimaryLanIPv4 Per review feedback: avoid calling vi.restoreAllMocks() inside individual tests as it restores all spies globally and can cause ordering issues. Use afterEach in the describe block instead. Co-authored-by: Cursor <cursoragent@cursor.com> * Changelog: note LAN bind URLs fix (#11448) (thanks @AnonO6) --------- Co-authored-by: Cursor <cursoragent@cursor.com> Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
This commit is contained in:
@@ -1,6 +1,30 @@
|
||||
import net from "node:net";
|
||||
import os from "node:os";
|
||||
import { pickPrimaryTailnetIPv4, pickPrimaryTailnetIPv6 } from "../infra/tailnet.js";
|
||||
|
||||
/**
|
||||
* Pick the primary non-internal IPv4 address (LAN IP).
|
||||
* Prefers common interface names (en0, eth0) then falls back to any external IPv4.
|
||||
*/
|
||||
export function pickPrimaryLanIPv4(): string | undefined {
|
||||
const nets = os.networkInterfaces();
|
||||
const preferredNames = ["en0", "eth0"];
|
||||
for (const name of preferredNames) {
|
||||
const list = nets[name];
|
||||
const entry = list?.find((n) => n.family === "IPv4" && !n.internal);
|
||||
if (entry?.address) {
|
||||
return entry.address;
|
||||
}
|
||||
}
|
||||
for (const list of Object.values(nets)) {
|
||||
const entry = list?.find((n) => n.family === "IPv4" && !n.internal);
|
||||
if (entry?.address) {
|
||||
return entry.address;
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
export function isLoopbackAddress(ip: string | undefined): boolean {
|
||||
if (!ip) {
|
||||
return false;
|
||||
|
||||
Reference in New Issue
Block a user