mirror of
http://192.168.0.88:13333/lywsvip/openclaw-zero-token.git
synced 2026-06-03 23:50:09 +08:00
Major upgrade from e26988a38 to upstream v2026.3.28 (f9b107928).
Key changes:
- Upstream src/, ui/, extensions/ (89 bundled extensions)
- Zero-token web providers preserved in src/zero-token/
- AskOnce plugin restored and registered as CLI command
- Added missing packages: @anthropic-ai/vertex-sdk, @modelcontextprotocol/sdk
- Fixed tsconfig rootDir, skipLibCheck for plugin-sdk DTS build
- Added askonce to bundled plugin metadata and package.json exports
- Fixed AskOnce CLI command registration (missing commands metadata)
- Restored AskOnce adapter imports (correct 5-level relative paths)
- Removed stale migration artifacts from root directory
113 lines
4.0 KiB
TypeScript
113 lines
4.0 KiB
TypeScript
import { resolveConfigPath, resolveGatewayPort } from "../config/paths.js";
|
|
import type { OpenClawConfig } from "../config/types.js";
|
|
import { isSecureWebSocketUrl } from "./net.js";
|
|
|
|
export type GatewayConnectionDetails = {
|
|
url: string;
|
|
urlSource: string;
|
|
bindDetail?: string;
|
|
remoteFallbackNote?: string;
|
|
message: string;
|
|
};
|
|
|
|
type GatewayConnectionDetailResolvers = {
|
|
loadConfig?: () => OpenClawConfig;
|
|
resolveConfigPath?: (env: NodeJS.ProcessEnv) => string;
|
|
resolveGatewayPort?: (cfg?: OpenClawConfig, env?: NodeJS.ProcessEnv) => number;
|
|
};
|
|
|
|
function trimToUndefined(value: string | undefined): string | undefined {
|
|
const trimmed = value?.trim();
|
|
return trimmed ? trimmed : undefined;
|
|
}
|
|
|
|
export function buildGatewayConnectionDetailsWithResolvers(
|
|
options: {
|
|
config?: OpenClawConfig;
|
|
url?: string;
|
|
configPath?: string;
|
|
urlSource?: "cli" | "env";
|
|
} = {},
|
|
resolvers: GatewayConnectionDetailResolvers = {},
|
|
): GatewayConnectionDetails {
|
|
const config = options.config ?? resolvers.loadConfig?.() ?? {};
|
|
const configPath =
|
|
options.configPath ??
|
|
resolvers.resolveConfigPath?.(process.env) ??
|
|
resolveConfigPath(process.env);
|
|
const isRemoteMode = config.gateway?.mode === "remote";
|
|
const remote = isRemoteMode ? config.gateway?.remote : undefined;
|
|
const tlsEnabled = config.gateway?.tls?.enabled === true;
|
|
const localPort =
|
|
resolvers.resolveGatewayPort?.(config, process.env) ?? resolveGatewayPort(config);
|
|
const bindMode = config.gateway?.bind ?? "loopback";
|
|
const scheme = tlsEnabled ? "wss" : "ws";
|
|
const localUrl = `${scheme}://127.0.0.1:${localPort}`;
|
|
const cliUrlOverride =
|
|
typeof options.url === "string" && options.url.trim().length > 0
|
|
? options.url.trim()
|
|
: undefined;
|
|
const envUrlOverride = cliUrlOverride
|
|
? undefined
|
|
: trimToUndefined(process.env.OPENCLAW_GATEWAY_URL);
|
|
const urlOverride = cliUrlOverride ?? envUrlOverride;
|
|
const remoteUrl =
|
|
typeof remote?.url === "string" && remote.url.trim().length > 0 ? remote.url.trim() : undefined;
|
|
const remoteMisconfigured = isRemoteMode && !urlOverride && !remoteUrl;
|
|
const urlSourceHint =
|
|
options.urlSource ?? (cliUrlOverride ? "cli" : envUrlOverride ? "env" : undefined);
|
|
const url = urlOverride || remoteUrl || localUrl;
|
|
const urlSource = urlOverride
|
|
? urlSourceHint === "env"
|
|
? "env OPENCLAW_GATEWAY_URL"
|
|
: "cli --url"
|
|
: remoteUrl
|
|
? "config gateway.remote.url"
|
|
: remoteMisconfigured
|
|
? "missing gateway.remote.url (fallback local)"
|
|
: "local loopback";
|
|
const bindDetail = !urlOverride && !remoteUrl ? `Bind: ${bindMode}` : undefined;
|
|
const remoteFallbackNote = remoteMisconfigured
|
|
? "Warn: gateway.mode=remote but gateway.remote.url is missing; set gateway.remote.url or switch gateway.mode=local."
|
|
: undefined;
|
|
|
|
const allowPrivateWs = process.env.OPENCLAW_ALLOW_INSECURE_PRIVATE_WS === "1";
|
|
if (!isSecureWebSocketUrl(url, { allowPrivateWs })) {
|
|
throw new Error(
|
|
[
|
|
`SECURITY ERROR: Gateway URL "${url}" uses plaintext ws:// to a non-loopback address.`,
|
|
"Both credentials and chat data would be exposed to network interception.",
|
|
`Source: ${urlSource}`,
|
|
`Config: ${configPath}`,
|
|
"Fix: Use wss:// for remote gateway URLs.",
|
|
"Safe remote access defaults:",
|
|
"- keep gateway.bind=loopback and use an SSH tunnel (ssh -N -L 18789:127.0.0.1:18789 user@gateway-host)",
|
|
"- or use Tailscale Serve/Funnel for HTTPS remote access",
|
|
allowPrivateWs
|
|
? undefined
|
|
: "Break-glass (trusted private networks only): set OPENCLAW_ALLOW_INSECURE_PRIVATE_WS=1",
|
|
"Doctor: openclaw doctor --fix",
|
|
"Docs: https://docs.openclaw.ai/gateway/remote",
|
|
].join("\n"),
|
|
);
|
|
}
|
|
|
|
const message = [
|
|
`Gateway target: ${url}`,
|
|
`Source: ${urlSource}`,
|
|
`Config: ${configPath}`,
|
|
bindDetail,
|
|
remoteFallbackNote,
|
|
]
|
|
.filter(Boolean)
|
|
.join("\n");
|
|
|
|
return {
|
|
url,
|
|
urlSource,
|
|
bindDetail,
|
|
remoteFallbackNote,
|
|
message,
|
|
};
|
|
}
|