UNPKG

openclaw

Version:

Multi-channel AI gateway with extensible messaging integrations

169 lines (168 loc) 7.45 kB
import { l as normalizeOptionalString } from "./string-coerce-CIXf7egm.js"; import { l as readConfigFileSnapshotForWrite } from "./io.runtime-B9iJRs3w.js"; import { t as formatCliCommand } from "./command-format-C7YfyMTd.js"; import { l as hasConfiguredSecretInput, v as resolveSecretInputRef } from "./types.secrets-kC0nOetj.js"; import { b as isUnsafeGatewayTailscaleNoAuth, y as formatUnsafeGatewayTailscaleNoAuthMessage } from "./io.types-BUCjdS5v.js"; import "./io-bdCzpGWJ.js"; import { r as replaceConfigFile } from "./mutate-ZNN4iFCn.js"; import { d as collectDurableServiceEnvVars } from "./systemd-service-files-BCcumv4T.js"; import { n as hasAmbiguousGatewayAuthModeConfig } from "./auth-mode-policy-CgmWtSyI.js"; import { t as resolveGatewayAuthToken } from "./auth-token-resolution-B9de62Be.js"; import { n as resolveGatewayAuth } from "./auth-resolve-O5AKX-sb.js"; import "./auth-CyN_wFeb.js"; import { t as randomToken } from "./random-token-B1woZa_H.js"; //#region src/gateway/auth-install-policy.ts function hasExplicitGatewayInstallAuthMode(mode) { if (mode === "token") return true; if (mode === "password" || mode === "none" || mode === "trusted-proxy") return false; } function hasConfiguredGatewayPasswordForInstall(cfg) { return hasConfiguredSecretInput(cfg.gateway?.auth?.password, cfg.secrets?.defaults); } function hasDurableGatewayPasswordEnvForInstall(cfg, env) { const durableServiceEnv = collectDurableServiceEnvVars({ env, config: cfg }); return Boolean(normalizeOptionalString(durableServiceEnv.OPENCLAW_GATEWAY_PASSWORD) || normalizeOptionalString(durableServiceEnv.CLAWDBOT_GATEWAY_PASSWORD)); } /** Decide whether install should require token auth when no durable password source exists. */ function shouldRequireGatewayTokenForInstall(cfg, env) { const explicitModeDecision = hasExplicitGatewayInstallAuthMode(cfg.gateway?.auth?.mode); if (explicitModeDecision !== void 0) return explicitModeDecision; if (hasConfiguredGatewayPasswordForInstall(cfg)) return false; if (hasDurableGatewayPasswordEnvForInstall(cfg, env)) return false; return true; } //#endregion //#region src/commands/gateway-install-token.ts /** Resolves the gateway token used when installing or updating the managed service. */ const defaultGatewayInstallTokenPersistence = { readConfigFileSnapshotForWrite, replaceConfigFile }; async function maybePersistAutoGeneratedGatewayInstallToken(params) { try { const prepared = params.configSnapshot && params.configWriteOptions ? { snapshot: params.configSnapshot, writeOptions: params.configWriteOptions } : await params.persistence.readConfigFileSnapshotForWrite(); const snapshot = params.configSnapshot ?? prepared.snapshot; if (snapshot.exists && !snapshot.valid) { params.warnings.push("Warning: config file exists but is invalid; skipping token persistence."); return params.token; } 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 params.persistence.replaceConfigFile({ nextConfig: { ...baseConfig, gateway: { ...baseConfig.gateway, auth: { ...baseConfig.gateway?.auth, mode: baseConfig.gateway?.auth?.mode ?? "token", token: params.token } } }, snapshot, writeOptions: { baseSnapshot: snapshot, ...prepared.writeOptions, ...params.configWriteOptions, skipRuntimeSnapshotRefresh: true }, afterWrite: { mode: "auto" } }); return params.token; } if (baseConfigToken) return baseConfigToken; params.warnings.push("Warning: gateway.auth.token is SecretRef-managed; skipping plaintext token persistence."); return; } catch (err) { params.warnings.push(`Warning: could not persist token to config: ${String(err)}`); return params.token; } } 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(" "); } /** Resolves, validates, optionally generates, and optionally persists a gateway install token. */ async function resolveGatewayInstallToken(options) { const cfg = options.config; const warnings = []; if (hasAmbiguousGatewayAuthModeConfig(cfg)) return { token: void 0, tokenRefConfigured: Boolean(resolveSecretInputRef({ value: cfg.gateway?.auth?.token, defaults: cfg.secrets?.defaults }).ref), 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 { token: void 0, tokenRefConfigured: false, unavailableReason: formatUnsafeGatewayTailscaleNoAuthMessage(tailscaleMode), warnings }; const needsToken = shouldRequireGatewayTokenForInstall(cfg, options.env) && !resolvedAuth.allowTailscale; if (!needsToken) return { token: void 0, tokenRefConfigured: Boolean(resolveSecretInputRef({ value: cfg.gateway?.auth?.token, defaults: cfg.secrets?.defaults }).ref), 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; let token = resolvedToken.source === "secretRef" ? void 0 : resolvedToken.token; let unavailableReason; if (tokenRefConfigured && resolvedToken.source === "secretRef" && needsToken) 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 && needsToken) unavailableReason = `gateway.auth.token SecretRef is configured but unresolved (${resolvedToken.unresolvedRefReason ?? "unknown reason"}).`; const allowAutoGenerate = options.autoGenerateWhenMissing ?? false; const persistGeneratedToken = options.persistGeneratedToken ?? false; if (!token && !tokenRefConfigured && allowAutoGenerate) { token = randomToken(); warnings.push(persistGeneratedToken ? "No gateway token found. Auto-generated one and saving to config." : "No gateway token found. Auto-generated one for this run without saving to config."); if (persistGeneratedToken) token = await maybePersistAutoGeneratedGatewayInstallToken({ token, config: cfg, configSnapshot: options.configSnapshot, configWriteOptions: options.configWriteOptions, warnings, persistence: options.persistence ?? defaultGatewayInstallTokenPersistence }); } return { token, tokenRefConfigured, unavailableReason, warnings }; } //#endregion export { resolveGatewayInstallToken as t };