UNPKG

openclaw

Version:

Multi-channel AI gateway with extensible messaging integrations

204 lines (203 loc) 9.26 kB
import { a as isWssUrl } from "./url-protocol-OU3K-ySz.js"; import { r as trimToUndefined } from "./credential-planner-DAMjVc9j.js"; import { r as resolveExplicitGatewayAuth } from "./credentials-CXbS4PS0.js"; import { t as gatewayOriginScope } from "./gateway-origin-scope-D4zHFrov.js"; import { t as resolveGatewayPublicOrigin } from "./gateway-public-origin-BcHLka2A.js"; import { n as resolveGatewayProbeSurfaceAuth, t as resolveGatewayInteractiveSurfaceAuth } from "./auth-surface-resolution-BmpOVonk.js"; import { t as buildGatewayConnectionDetailsWithResolvers } from "./connection-details-dzrfNKN8.js"; import { t as normalizeControlUiBasePath } from "./control-ui-shared-BiO6QP54.js"; import { n as resolveGatewayCredentialsWithSecretInputs } from "./credentials-secret-inputs-BlthacCl.js"; import { o as requireTlsFingerprint } from "./client-address-utils-DUCasR_v.js"; import { t as inspectGatewayTlsCertificate } from "./gateway-BtIixcdW.js"; //#region src/gateway/tls-fingerprint.ts /** Resolve the certificate pin for one already-selected Gateway target. */ async function resolveGatewayConnectionTlsFingerprint(params) { const explicitTlsFingerprint = params.explicitTlsFingerprint ? requireTlsFingerprint(params.explicitTlsFingerprint) : void 0; if (explicitTlsFingerprint) return explicitTlsFingerprint; const remoteTlsFingerprint = params.config.gateway?.mode === "remote" && (params.urlSource === "config gateway.remote.url" || params.urlSource === "env OPENCLAW_GATEWAY_URL") ? params.config.gateway.remote?.tlsFingerprint ? requireTlsFingerprint(params.config.gateway.remote.tlsFingerprint) : void 0 : void 0; if (remoteTlsFingerprint) return remoteTlsFingerprint; if (!isWssUrl(params.url)) return; if (!(params.urlSource === "local loopback" || params.urlSource === "missing gateway.remote.url (fallback local)") || params.config.gateway?.tls?.enabled !== true) return; const certificate = await inspectGatewayTlsCertificate(params.config.gateway.tls); return certificate.ok ? certificate.value.fingerprintSha256 : void 0; } //#endregion //#region src/gateway/client-bootstrap.ts /** * Maps connection-detail source labels to the override kinds that affect auth fallback. */ function resolveGatewayUrlOverrideSource(urlSource) { if (urlSource === "cli --url") return "cli"; if (urlSource === "env OPENCLAW_GATEWAY_URL") return "env"; } var GatewayExplicitAuthRequiredError = class extends Error { constructor(message) { super(message); this.name = "GatewayExplicitAuthRequiredError"; } }; function ensureExplicitGatewayAuth(params) { if (!params.urlOverride || !params.urlOverrideSource) return; if (params.explicitAuth?.token || params.explicitAuth?.password) return; if (params.urlOverrideSource === "env" && (params.resolvedAuth?.token || params.resolvedAuth?.password)) return; if (params.deviceAuthScope && params.allowStoredOriginAuth?.(params.deviceAuthScope) === true) return; const sourceHint = params.urlOverrideSource === "env" ? "Set OPENCLAW_GATEWAY_TOKEN or OPENCLAW_GATEWAY_PASSWORD alongside OPENCLAW_GATEWAY_URL; config credentials are intentionally not reused." : "For the default local or SSH-tunneled Gateway, remove --url to use the configured target."; throw new GatewayExplicitAuthRequiredError([ "gateway url override requires explicit credentials", params.errorHint, sourceHint, params.configPath ? `Config: ${params.configPath}` : void 0 ].filter(Boolean).join("\n")); } function appendControlUiBasePath(url, basePath) { return `${url}${normalizeControlUiBasePath(basePath)}`; } function resolveExactConfiguredGatewayTarget(params) { const candidates = []; if (params.config.gateway?.mode === "remote") { const remoteUrl = trimToUndefined(params.config.gateway.remote?.url); if (remoteUrl) candidates.push({ target: remoteUrl, identity: { authSurface: "remote", tlsSource: "config gateway.remote.url" } }); } else { const localGateway = { ...params.config.gateway, mode: "local" }; delete localGateway.remote; const localUrl = params.buildConnectionDetails({ config: { ...params.config, gateway: localGateway }, ignoreEnvUrlOverride: true, ...params.localPortOverride !== void 0 ? { localPortOverride: params.localPortOverride } : {} }).url; const basePath = params.config.gateway?.controlUi?.basePath ?? ""; candidates.push({ target: appendControlUiBasePath(localUrl, basePath), identity: { authSurface: "local", tlsSource: "local loopback" } }); const publicOrigin = resolveGatewayPublicOrigin(params.config); if (publicOrigin) candidates.push({ target: appendControlUiBasePath(publicOrigin.replace(/^https:/u, "wss:").replace(/^http:/u, "ws:"), basePath), identity: { authSurface: "local" } }); } return candidates.find(({ target }) => target === params.explicitUrl)?.identity; } /** Resolve the only URL overrides allowed to displace configured Gateway targets. */ function resolveGatewayUrlOverride(params) { const cliUrl = trimToUndefined(params.gatewayUrl); if (cliUrl) return { url: cliUrl, source: "cli" }; if (params.ignoreEnvUrlOverride || params.localPortOverride !== void 0) return {}; const envUrl = trimToUndefined((params.env ?? process.env).OPENCLAW_GATEWAY_URL); return envUrl ? { url: envUrl, source: "env" } : {}; } /** * Resolves the URL, auth material, and handshake tuning needed to start a GatewayClient. */ async function resolveGatewayClientBootstrap(params) { const env = params.env ?? process.env; const explicitAuth = resolveExplicitGatewayAuth(params.explicitAuth); const urlOverride = resolveGatewayUrlOverride({ gatewayUrl: params.gatewayUrl, env, ignoreEnvUrlOverride: params.ignoreEnvUrlOverride, localPortOverride: params.localPortOverride }); const buildConnectionDetails = params.buildConnectionDetails ?? buildGatewayConnectionDetailsWithResolvers; const connection = buildConnectionDetails({ config: params.config, url: urlOverride.url, ...params.configPath ? { configPath: params.configPath } : {}, ...urlOverride.source ? { urlSource: urlOverride.source } : {}, ignoreEnvUrlOverride: true, ...params.localPortOverride !== void 0 ? { localPortOverride: params.localPortOverride } : {} }); const detectedUrlOverrideSource = resolveGatewayUrlOverrideSource(connection.urlSource); const urlOverrideSource = urlOverride.source ?? detectedUrlOverrideSource; const configuredTarget = params.allowConfiguredAuthForExactTarget && urlOverrideSource === "cli" ? resolveExactConfiguredGatewayTarget({ buildConnectionDetails, config: params.config, explicitUrl: connection.url, ...params.localPortOverride !== void 0 ? { localPortOverride: params.localPortOverride } : {} }) : void 0; const tlsUrlSource = configuredTarget?.tlsSource ?? connection.urlSource; const tlsFingerprint = await resolveGatewayConnectionTlsFingerprint({ config: params.config, url: connection.url, urlSource: tlsUrlSource, explicitTlsFingerprint: params.explicitTlsFingerprint }); const surface = configuredTarget?.authSurface ?? params.modeOverride ?? (params.localPortOverride !== void 0 ? "local" : params.config.gateway?.mode === "remote" ? "remote" : "local"); let auth; if (params.skipImplicitAuth) auth = explicitAuth; else if (urlOverrideSource && !configuredTarget) auth = params.suppressEnvAuthFallback ? explicitAuth : await resolveGatewayCredentialsWithSecretInputs({ config: params.config, explicitAuth, env, urlOverride: connection.url, urlOverrideSource, modeOverride: params.modeOverride }); else if (params.authPolicy === "probe") auth = await resolveGatewayProbeSurfaceAuth({ config: params.config, env, surface }); else if (params.authPolicy === "interactive") auth = await resolveGatewayInteractiveSurfaceAuth({ config: params.config, env, explicitAuth, suppressEnvAuthFallback: params.suppressEnvAuthFallback, surface }); else auth = await resolveGatewayCredentialsWithSecretInputs({ config: params.config, explicitAuth, env, urlOverride: urlOverrideSource ? connection.url : void 0, urlOverrideSource, modeOverride: params.modeOverride }); const deviceAuthScope = urlOverrideSource || params.config.gateway?.mode === "remote" ? gatewayOriginScope(connection.url) : void 0; if (params.overrideAuthErrorHint && !configuredTarget) ensureExplicitGatewayAuth({ urlOverride: urlOverrideSource ? connection.url : void 0, urlOverrideSource, explicitAuth, resolvedAuth: auth, deviceAuthScope, allowStoredOriginAuth: params.allowStoredOriginAuth, errorHint: params.overrideAuthErrorHint ?? "Fix: pass --token or --password with --url.", configPath: params.configPath }); return { url: connection.url, urlSource: connection.urlSource, connectionDetails: connection, ...urlOverrideSource ? { urlOverrideSource } : {}, ...deviceAuthScope ? { deviceAuthScope } : {}, ...auth.failureReason ? { authFailureReason: auth.failureReason } : {}, ...tlsFingerprint ? { tlsFingerprint } : {}, auth: { token: auth.token, password: auth.password } }; } //#endregion export { resolveGatewayUrlOverride as i, ensureExplicitGatewayAuth as n, resolveGatewayClientBootstrap as r, GatewayExplicitAuthRequiredError as t };