UNPKG

openclaw

Version:

Multi-channel AI gateway with extensible messaging integrations

161 lines (160 loc) • 7.71 kB
import { l as normalizeOptionalString, o as normalizeLowercaseStringOrEmpty, p as normalizeStringifiedOptionalString, s as normalizeNullableString } from "./string-coerce-1VuiLaaR.mjs"; import { c as isRecord } from "./record-coerce-TIsquoVR.mjs"; import "./session-key-DY3MOX4N.mjs"; import "./account-id-ifCOO7_9.mjs"; import { r as createSqliteWorkerOperationAdmission } from "./sqlite-worker-operation-admission-C5lBzzTk.mjs"; import { r as openOpenClawStateDatabase } from "./openclaw-state-db-DJZ7EKoI.mjs"; import { r as captureOpenClawStateWorkerContext } from "./openclaw-state-worker-context-BvvgY6-t.mjs"; import { o as runOpenClawStateWorkerOperation } from "./openclaw-state-worker-store-BxZXTKna.mjs"; import { t as getPairingAdapter } from "./pairing-Bx3sWrDJ.mjs"; import { a as safeChannelKey, n as resolveAllowFromAccountId } from "./pairing-store-keys-cRW5JPmq.mjs"; import { n as readChannelAllowEntries } from "./pairing-store-sqlite-D_sqw3gG.mjs"; import "./pairing-store-model-B2kD2hdd.mjs"; import "./pairing-store.read-B4WF5dGA.mjs"; import { MessagePort } from "node:worker_threads"; //#region src/pairing/pairing-store.ts function resolvePairingAdapter(channel, pairingAdapter) { return pairingAdapter ?? getPairingAdapter(channel) ?? void 0; } function normalizeAllowFromInput(entry, pairingAdapter) { const trimmed = normalizeStringifiedOptionalString(entry) ?? ""; if (!trimmed || trimmed === "*") return ""; const adapter = pairingAdapter; const normalized = adapter?.normalizeAllowEntry ? adapter.normalizeAllowEntry(trimmed) : trimmed; const normalizedEntry = normalizeOptionalString(normalized) ?? ""; return normalizedEntry === "*" ? "" : normalizedEntry; } function mutatePairing(params, mutation) { const channel = safeChannelKey(params.channel); const assertCurrent = params.assertCurrent; const adapter = mutation.action === "resolve" && mutation.approval !== "dismiss" ? resolvePairingAdapter(params.channel, params.pairingAdapter) : void 0; if (mutation.action === "resolve" && (adapter?.normalizeAllowEntry || adapter?.resolveApprovalStoreEntry)) mutation.approval = "host"; const context = captureOpenClawStateWorkerContext({ env: params.env ?? process.env }); return runOpenClawStateWorkerOperation(context, (scope) => scope.execute({ type: "channelPairing.mutate", input: { channel, mutation } }), { assertCurrent, createAdmission: () => ({ nativeLocations: [context.admission.databasePath], admission: createSqliteWorkerOperationAdmission((request, grant) => { context.admission.assertCurrent(); assertCurrent?.(); const facts = request.facts; if (!isRecord(facts) || facts.channel !== channel) throw new Error("Channel pairing requires its captured mutation authority"); if (request.stage === "prepare" && facts.kind === "channel-pairing-approval" && mutation.action === "resolve" && mutation.approval === "host" && isRecord(facts.entry) && typeof facts.entry.id === "string" && facts.replyPort instanceof MessagePort) { const meta = {}; if (facts.entry.meta !== void 0) { if (!isRecord(facts.entry.meta)) throw new Error("Invalid channel pairing approval metadata"); for (const [key, value] of Object.entries(facts.entry.meta)) { if (typeof value !== "string") throw new Error("Invalid channel pairing approval metadata"); meta[key] = value; } } const entry = { id: facts.entry.id, ...facts.entry.meta ? { meta } : {} }; const approval = adapter?.resolveApprovalStoreEntry ? adapter.resolveApprovalStoreEntry({ id: entry.id, ...entry.meta ? { meta: entry.meta } : {} }) : entry.id; const normalized = approval == null ? "" : normalizeAllowFromInput(approval, adapter); context.admission.assertCurrent(); assertCurrent?.(); facts.replyPort.postMessage(normalized, []); } else if (facts.kind !== "channel-pairing" || request.stage !== "transaction" && request.stage !== "commit") throw new Error("Unexpected channel pairing admission request"); grant(); }) }) }); } /** @deprecated Use readChannelAllowFromStore; retained for the v2026.9.8 SDK until the next Plugin SDK major. */ function readChannelAllowFromStoreSync(channel, env = process.env, accountId) { const resolvedAccountId = resolveAllowFromAccountId(accountId); return (readChannelAllowEntries(openOpenClawStateDatabase({ env }).db, channel)[resolvedAccountId] ?? []).slice(); } async function updateAllowFromStoreEntry(params, remove) { const result = await mutatePairing(params, { action: "allow", accountId: resolveAllowFromAccountId(params.accountId), entry: normalizeAllowFromInput(params.entry, resolvePairingAdapter(params.channel, params.pairingAdapter)), remove }); if (result.action !== "allow") throw new Error("Unexpected channel pairing allowlist result"); return { changed: result.changed, allowFrom: result.allowFrom }; } async function addChannelAllowFromStoreEntry(params) { return updateAllowFromStoreEntry(params, false); } async function removeChannelAllowFromStoreEntry(params) { return updateAllowFromStoreEntry(params, true); } async function listChannelPairingRequests(channel, env = process.env, accountId, assertCurrent) { const result = await mutatePairing({ channel, env, assertCurrent }, { action: "list", accountId: normalizeLowercaseStringOrEmpty(accountId) }); if (result.action !== "list") throw new Error("Unexpected channel pairing list result"); return result.requests; } async function upsertChannelPairingRequest(params) { const accountId = normalizeLowercaseStringOrEmpty(params.accountId) || "default"; const meta = { ...Object.fromEntries(Object.entries(params.meta ?? {}).map(([key, value]) => [key, normalizeOptionalString(value) ?? ""]).filter(([, value]) => Boolean(value))), accountId }; const result = await mutatePairing(params, { action: "upsert", id: normalizeStringifiedOptionalString(params.id) ?? "", accountId, meta }); if (result.action !== "upsert") throw new Error("Unexpected channel pairing request result"); return { code: result.code, created: result.created }; } async function resolveChannelPairingRequest(params, selector, approve) { const result = await mutatePairing(params, { action: "resolve", accountId: normalizeLowercaseStringOrEmpty(params.accountId), selector, approval: approve ? "sender" : "dismiss" }); if (result.action !== "resolve") throw new Error("Unexpected channel pairing resolution result"); return result.result; } async function approveChannelPairingCode(params) { const code = (normalizeNullableString(params.code) ?? "").toUpperCase(); return code ? resolveChannelPairingRequest(params, { code }, true) : null; } /** Approves a pending request by opaque id without exposing its pairing code. */ async function approveChannelPairingRequest(params) { const requestId = normalizeOptionalString(params.requestId); return requestId ? resolveChannelPairingRequest(params, { requestId, channel: params.channel }, true) : null; } /** Dismisses a pending request without blocking the sender from requesting again. */ async function dismissChannelPairingRequest(params) { const requestId = normalizeOptionalString(params.requestId); return requestId ? resolveChannelPairingRequest(params, { requestId, channel: params.channel }, false) : null; } //#endregion export { listChannelPairingRequests as a, upsertChannelPairingRequest as c, dismissChannelPairingRequest as i, approveChannelPairingCode as n, readChannelAllowFromStoreSync as o, approveChannelPairingRequest as r, removeChannelAllowFromStoreEntry as s, addChannelAllowFromStoreEntry as t };