UNPKG

openclaw

Version:

Multi-channel AI gateway with extensible messaging integrations

86 lines (85 loc) 3.19 kB
import { a as normalizeLowercaseStringOrEmpty } from "./string-coerce-mnp54Vah.js"; import { o as getTailnetHostname } from "./tailscale-BOFw04AY.js"; import { g as parseCanonicalIpAddress, i as isCanonicalDottedDecimalIPv4, l as isIpv6Address } from "./ip-0oQXo6_w.js"; //#region packages/net-policy/src/ipv4.ts /** Validates the custom-bind IPv4 input and returns the user-facing error text. */ function validateDottedDecimalIPv4Input(value) { if (!value) return "IP address is required for custom bind mode"; if (isCanonicalDottedDecimalIPv4(value)) return; return "Invalid IPv4 address (e.g., 192.168.1.100)"; } /** @deprecated Use validateDottedDecimalIPv4Input. */ function validateIPv4AddressInput(value) { return validateDottedDecimalIPv4Input(value); } //#endregion //#region src/gateway/gateway-config-prompts.shared.ts const TAILSCALE_EXPOSURE_OPTIONS = [ { value: "off", label: "Off", hint: "No Tailscale exposure" }, { value: "serve", label: "Serve", hint: "Private HTTPS for your tailnet (devices on Tailscale)" }, { value: "funnel", label: "Funnel", hint: "Public HTTPS via Tailscale Funnel (internet)" } ]; const TAILSCALE_MISSING_BIN_NOTE_LINES = [ "Tailscale binary not found in PATH or /Applications.", "Ensure Tailscale is installed from:", " https://tailscale.com/download/mac", "", "You can continue setup, but serve/funnel will fail at runtime." ]; const TAILSCALE_DOCS_LINES = [ "Docs:", "https://docs.openclaw.ai/gateway/tailscale", "https://docs.openclaw.ai/web" ]; function normalizeTailnetHostForUrl(rawHost) { const trimmed = rawHost.trim().replace(/\.$/, ""); if (!trimmed) return null; const parsed = parseCanonicalIpAddress(trimmed); if (parsed && isIpv6Address(parsed)) return `[${normalizeLowercaseStringOrEmpty(parsed.toString())}]`; return trimmed; } function buildTailnetHttpsOrigin(rawHost) { const normalizedHost = normalizeTailnetHostForUrl(rawHost); if (!normalizedHost) return null; try { return new URL(`https://${normalizedHost}`).origin; } catch { return null; } } function appendAllowedOrigin(existing, origin) { const current = existing ?? []; const normalized = normalizeLowercaseStringOrEmpty(origin); if (current.some((entry) => normalizeLowercaseStringOrEmpty(entry) === normalized)) return current; return [...current, origin]; } async function maybeAddTailnetOriginToControlUiAllowedOrigins(params) { if (params.tailscaleMode !== "serve" && params.tailscaleMode !== "funnel") return params.config; const tsOrigin = await getTailnetHostname(void 0, params.tailscaleBin ?? void 0).then((host) => buildTailnetHttpsOrigin(host)).catch(() => null); if (!tsOrigin) return params.config; const updatedOrigins = appendAllowedOrigin(params.config.gateway?.controlUi?.allowedOrigins ?? [], tsOrigin); return { ...params.config, gateway: { ...params.config.gateway, controlUi: { ...params.config.gateway?.controlUi, allowedOrigins: updatedOrigins } } }; } //#endregion export { validateIPv4AddressInput as a, maybeAddTailnetOriginToControlUiAllowedOrigins as i, TAILSCALE_EXPOSURE_OPTIONS as n, TAILSCALE_MISSING_BIN_NOTE_LINES as r, TAILSCALE_DOCS_LINES as t };