UNPKG

openclaw

Version:

Multi-channel AI gateway with extensible messaging integrations

154 lines (153 loc) 5.84 kB
import { m as clampTimerTimeoutMs } from "./number-coercion-CLj0HTDM.js"; import { l as toErrorObject } from "./error-coercion-D_-xJ90S.js"; import { l as normalizeOptionalString, o as normalizeLowercaseStringOrEmpty } from "./string-coerce-CIXf7egm.js"; import { n as getRuntimeConfig } from "./io.runtime-B9iJRs3w.js"; import { n as resolveGatewayAuth } from "./auth-resolve-O5AKX-sb.js"; import "./error-runtime-Bz9Tw57Z.js"; import "./number-runtime-Cy4drVnh.js"; import "./string-coerce-runtime-GQa0ehRA.js"; import "./plugin-runtime-Cl_BX05Z.js"; import { t as ensureGatewayStartupAuth } from "./startup-auth-D92BVWdq.js"; import "./gateway-runtime-BkyVf3uU.js"; import "./config-C0cjs7WS.js"; import { r as persistBrowserControlCredential } from "./config-mutations-C1jaO0us.js"; import crypto from "node:crypto"; //#region extensions/browser/src/sdk-node-runtime.ts /** * Browser-local SDK bridge for gateway, plugin runtime, and timeout helpers. */ function normalizeTimeoutMs(timeoutMs) { return clampTimerTimeoutMs(timeoutMs); } function createTimeoutAbortSignal(timeoutMs, label) { const controller = new AbortController(); const error = /* @__PURE__ */ new Error(`${label ?? "request"} timed out`); const timer = setTimeout(() => controller.abort(error), timeoutMs); timer.unref?.(); return { controller, error, timer }; } function waitForAbort(signal, fallback) { if (signal.aborted) return { promise: Promise.reject(toErrorObject(signal.reason ?? fallback, "Non-Error rejection")), cleanup: () => void 0 }; let listener; return { cleanup: () => { if (listener) signal.removeEventListener("abort", listener); }, promise: new Promise((_, reject) => { listener = () => reject(toErrorObject(signal.reason ?? fallback, "Non-Error rejection")); signal.addEventListener("abort", listener, { once: true }); }) }; } /** Runs async work with an optional aborting timeout signal. */ async function withTimeout(work, timeoutMs, label) { const resolved = normalizeTimeoutMs(timeoutMs); if (!resolved) return await work(void 0); const timeout = createTimeoutAbortSignal(resolved, label); const abort = waitForAbort(timeout.controller.signal, timeout.error); try { return await Promise.race([work(timeout.controller.signal), abort.promise]); } finally { clearTimeout(timeout.timer); abort.cleanup(); } } //#endregion //#region extensions/browser/src/browser/control-auth.ts /** * Browser control authentication helpers. * * Resolves browser-control auth from Gateway auth config and auto-generates a * token/password for local control when safe to persist one. */ /** Resolve browser-control auth material from config and environment. */ function resolveBrowserControlAuth(cfg, env = process.env) { const auth = resolveGatewayAuth({ authConfig: cfg?.gateway?.auth, env, tailscaleMode: cfg?.gateway?.tailscale?.mode }); const token = normalizeOptionalString(auth.token) ?? ""; const password = normalizeOptionalString(auth.password) ?? ""; switch (auth.mode) { case "password": case "trusted-proxy": return { password: password || void 0 }; case "token": case "none": return { token: token || void 0 }; default: return {}; } } /** Return true when startup may auto-generate browser-control auth. */ function shouldAutoGenerateBrowserAuth(env) { if (normalizeLowercaseStringOrEmpty(env.NODE_ENV) === "test") return false; const vitest = normalizeLowercaseStringOrEmpty(env.VITEST); if (vitest && vitest !== "0" && vitest !== "false" && vitest !== "off") return false; return true; } function hasExplicitNonStringGatewayCredentialForMode(params) { const { cfg, mode } = params; const auth = cfg?.gateway?.auth; if (!auth) return false; if (mode === "none") return auth.token != null && typeof auth.token !== "string"; return auth.password != null && typeof auth.password !== "string"; } async function generateAndPersistBrowserControlCredential(params) { const credential = crypto.randomBytes(24).toString("hex"); await persistBrowserControlCredential({ kind: params.kind, value: credential }); const persistedAuth = resolveBrowserControlAuth(getRuntimeConfig(), params.env); if (persistedAuth.token || persistedAuth.password) return { auth: persistedAuth, generatedToken: persistedAuth[params.kind] === credential ? credential : void 0 }; return { auth: { [params.kind]: credential }, generatedToken: credential }; } /** Ensure browser-control auth exists, generating and persisting it when allowed. */ async function ensureBrowserControlAuth(params) { const env = params.env ?? process.env; const auth = resolveBrowserControlAuth(params.cfg, env); if (auth.token || auth.password) return { auth }; if (!shouldAutoGenerateBrowserAuth(env)) return { auth }; if (params.cfg.gateway?.auth?.mode === "password") return { auth }; const latestCfg = getRuntimeConfig(); const latestAuth = resolveBrowserControlAuth(latestCfg, env); if (latestAuth.token || latestAuth.password) return { auth: latestAuth }; if (latestCfg.gateway?.auth?.mode === "password") return { auth: latestAuth }; const latestMode = latestCfg.gateway?.auth?.mode; if (latestMode === "none" || latestMode === "trusted-proxy") { if (hasExplicitNonStringGatewayCredentialForMode({ cfg: latestCfg, mode: latestMode })) return { auth: latestAuth }; return await generateAndPersistBrowserControlCredential({ kind: latestMode === "trusted-proxy" ? "password" : "token", env }); } const ensured = await ensureGatewayStartupAuth({ cfg: latestCfg, env, persist: true }); return { auth: { token: ensured.auth.token, password: ensured.auth.password }, generatedToken: ensured.generatedToken }; } //#endregion export { withTimeout as i, resolveBrowserControlAuth as n, shouldAutoGenerateBrowserAuth as r, ensureBrowserControlAuth as t };