UNPKG

openclaw

Version:

Multi-channel AI gateway with extensible messaging integrations

135 lines (134 loc) • 5.99 kB
import { l as normalizeOptionalString } from "./string-coerce-1VuiLaaR.mjs"; import { g as resolveSecretInputRef, o as hasConfiguredSecretInput } from "./types.secrets-DsPRn9Dz.mjs"; import { t as formatCliCommand } from "./command-format-DwEdrDKL.mjs"; import { i as assertGatewayServiceUpdateCurrent, o as isUpdateOwnedGatewayServiceCommand } from "./service-update-authority-CoX8GMUL.mjs"; import { S as isUnsafeGatewayTailscaleNoAuth, x as formatUnsafeGatewayTailscaleNoAuthMessage } from "./validation-core-C5DCruFP.mjs"; import { r as replaceConfigFile } from "./mutate-DJq1JylX.mjs"; import { O as collectDurableServiceEnvVars } from "./systemd-service-files-Cc5QKjzs.mjs"; import { r as resolveGatewayAuth } from "./auth-resolve-BmUDP1m_.mjs"; import { t as randomToken } from "./random-token-Sl4a6KEQ.mjs"; import { n as hasAmbiguousGatewayAuthModeConfig } from "./auth-mode-policy-DzNSJi11.mjs"; import "./auth-BfNXsaOg.mjs"; import { t as resolveGatewayAuthToken } from "./auth-token-resolution-B9VLhqWq.mjs"; //#region src/gateway/auth-install-policy.ts /** Decide whether install should require token auth when no durable password source exists. */ function shouldRequireGatewayTokenForInstall(cfg, env) { switch (cfg.gateway?.auth?.mode) { case "token": return true; case "password": case "none": case "trusted-proxy": return false; case void 0: } if (hasConfiguredSecretInput(cfg.gateway?.auth?.password, cfg.secrets?.defaults)) return false; const durableServiceEnv = collectDurableServiceEnvVars({ env, config: cfg }); return !(normalizeOptionalString(durableServiceEnv.OPENCLAW_GATEWAY_PASSWORD) || normalizeOptionalString(durableServiceEnv.CLAWDBOT_GATEWAY_PASSWORD)); } //#endregion //#region src/commands/gateway-install-token.ts async function maybePersistAutoGeneratedGatewayInstallToken(params) { try { const { snapshot, writeOptions } = params.generation; if (snapshot.exists && !snapshot.valid) { params.warnings.push("Warning: config file exists but is invalid; skipping token persistence."); return; } const baseConfig = snapshot.exists ? snapshot.sourceConfig ?? snapshot.config : {}; const existingTokenRef = resolveSecretInputRef({ value: baseConfig.gateway?.auth?.token, defaults: baseConfig.secrets?.defaults }).ref; const baseConfigToken = existingTokenRef || typeof baseConfig.gateway?.auth?.token !== "string" ? void 0 : normalizeOptionalString(baseConfig.gateway.auth.token); if (!existingTokenRef && !baseConfigToken) { await replaceConfigFile({ sourceConfig: { ...baseConfig, gateway: { ...baseConfig.gateway, auth: { ...baseConfig.gateway?.auth, mode: baseConfig.gateway?.auth?.mode ?? "token", token: params.token } } }, snapshot, writeOptions: { baseSnapshot: snapshot, ...writeOptions, ...isUpdateOwnedGatewayServiceCommand() ? { assertCurrent: () => { writeOptions.assertCurrent?.(); assertGatewayServiceUpdateCurrent(); } } : {}, skipRuntimeSnapshotRefresh: true }, afterWrite: { mode: "auto" } }); return; } if (baseConfigToken) return; params.warnings.push("Warning: gateway.auth.token is SecretRef-managed; skipping plaintext token persistence."); } catch (err) { params.warnings.push(`Warning: could not persist token to config: ${String(err)}`); } } function formatAmbiguousGatewayAuthModeReason() { return ["gateway.auth.token and gateway.auth.password are both configured while gateway.auth.mode is unset.", `Set ${formatCliCommand("openclaw config set gateway.auth.mode token")} or ${formatCliCommand("openclaw config set gateway.auth.mode password")}.`].join(" "); } /** Validate install auth, using the caller's captured write preparation for token generation. */ async function resolveGatewayInstallToken(options) { const cfg = options.config; const warnings = []; if (hasAmbiguousGatewayAuthModeConfig(cfg)) return { unavailableReason: formatAmbiguousGatewayAuthModeReason(), warnings }; const resolvedAuth = resolveGatewayAuth({ authConfig: cfg.gateway?.auth, env: options.env, tailscaleMode: cfg.gateway?.tailscale?.mode ?? "off" }); const tailscaleMode = cfg.gateway?.tailscale?.mode ?? "off"; if (isUnsafeGatewayTailscaleNoAuth({ authMode: resolvedAuth.mode, tailscaleMode })) return { unavailableReason: formatUnsafeGatewayTailscaleNoAuthMessage(tailscaleMode), warnings }; if (!(shouldRequireGatewayTokenForInstall(cfg, options.env) && !resolvedAuth.allowTailscale)) return { unavailableReason: void 0, warnings }; const resolvedToken = await resolveGatewayAuthToken({ cfg, env: options.env, explicitToken: options.explicitToken, envFallback: "no-secret-ref", unresolvedReasonStyle: "detailed" }); const tokenRefConfigured = resolvedToken.secretRefConfigured; const token = resolvedToken.source === "secretRef" ? void 0 : resolvedToken.token; let unavailableReason; if (tokenRefConfigured && resolvedToken.source === "secretRef") warnings.push("gateway.auth.token is SecretRef-managed; install will not persist a resolved token in service environment. Ensure the SecretRef is resolvable in the daemon runtime context."); else if (tokenRefConfigured && !token) unavailableReason = `gateway.auth.token SecretRef is configured but unresolved (${resolvedToken.unresolvedRefReason ?? "unknown reason"}).`; if (!token && !tokenRefConfigured && options.requireExisting) unavailableReason = "Deferred service load requires an existing Gateway token."; else if (!token && !tokenRefConfigured && options.generateIfMissing) { const generatedToken = randomToken(); warnings.push("No gateway token found. Auto-generated one and saving to config."); await maybePersistAutoGeneratedGatewayInstallToken({ token: generatedToken, generation: options.generateIfMissing, warnings }); } return { unavailableReason, warnings }; } //#endregion export { resolveGatewayInstallToken as t };