openclaw
Version:
Multi-channel AI gateway with extensible messaging integrations
166 lines (165 loc) • 7.13 kB
JavaScript
import { n as GATEWAY_CLIENT_IDS, r as GATEWAY_CLIENT_MODES } from "./client-info-B1bPgeKr.js";
import { t as ErrorCodes } from "./gateway-error-details-w0nAGBBp.js";
import { Gt as validateExecApprovalsSetParams, Ht as validateExecApprovalsNodeGetParams, Ut as validateExecApprovalsNodeSetParams, Vt as validateExecApprovalsGetParams, Wt as validateExecApprovalsNodeSnapshot } from "./src-BiL5aQto.js";
import { d as errorShape } from "./error-codes-Bo8q2D1o.js";
import { a as mergeExecApprovalsSocketDefaults } from "./exec-approvals-config-D1lCGl0_.js";
import { i as resolveExecApprovalsFromFile, n as redactExecApprovals, t as normalizeExecApprovals } from "./exec-approvals-BSZ-fPIY.js";
import { d as updateExecApprovals, n as ensureExecApprovalsSnapshot, o as readExecApprovalsSnapshot } from "./exec-approvals-store-DBR0neS0.js";
import { l as resolveNodeCommandAllowlist, o as isNodeCommandAllowed } from "./node-command-policy-H4FpS0aA.js";
import { t as parseGatewayPayload } from "./server-json-CUC0gj3q.js";
import { n as respondUnavailableOnNodeInvokeErrorWithProvenance, r as respondUnavailableOnThrow } from "./nodes.helpers-7uACMTmw.js";
import { t as assertValidParams } from "./validation-pzrlzFvo.js";
import { t as resolveBaseHashParam } from "./base-hash-BJkn_bB6.js";
//#region src/gateway/server-methods/exec-approvals.ts
function requireApprovalsBaseHash(params, snapshot, respond) {
const baseHash = resolveBaseHashParam(params);
if (!snapshot.exists) {
if (baseHash && baseHash !== snapshot.hash) {
respondApprovalsChanged(respond);
return false;
}
return true;
}
if (!snapshot.hash) {
respond(false, void 0, errorShape(ErrorCodes.INVALID_REQUEST, "exec approvals base hash unavailable; re-run exec.approvals.get and retry"));
return false;
}
if (!baseHash) {
respond(false, void 0, errorShape(ErrorCodes.INVALID_REQUEST, "exec approvals base hash required; re-run exec.approvals.get and retry"));
return false;
}
if (baseHash !== snapshot.hash) {
respondApprovalsChanged(respond);
return false;
}
return true;
}
function respondApprovalsChanged(respond) {
respond(false, void 0, errorShape(ErrorCodes.INVALID_REQUEST, "exec approvals changed since last load; re-run exec.approvals.get and retry"));
}
function toExecApprovalsPayload(snapshot) {
return {
...redactExecApprovals(snapshot),
resolvedDefaults: resolveExecApprovalsFromFile({ file: snapshot.file }).defaults
};
}
function isMacAppNode(session) {
const platform = session?.platform?.trim().toLowerCase();
return session?.clientId === GATEWAY_CLIENT_IDS.MACOS_APP && session.clientMode === GATEWAY_CLIENT_MODES.NODE && (platform === "macos" || platform?.startsWith("macos ") === true);
}
async function respondWithExecApprovalsNodePayload(params) {
const rawParams = params.rawParams;
if (!assertValidParams(rawParams, params.validate, params.method, params.respond)) return;
const parsedParams = rawParams;
const nodeId = parsedParams.nodeId.trim();
if (!nodeId) {
params.respond(false, void 0, errorShape(ErrorCodes.INVALID_REQUEST, "nodeId required"));
return;
}
const nodeSession = params.context.nodeRegistry.get(nodeId);
if (nodeSession) {
const allowed = isNodeCommandAllowed({
command: params.command,
declaredCommands: nodeSession.commands,
allowlist: resolveNodeCommandAllowlist(params.context.getRuntimeConfig(), {
...nodeSession,
approvedCommands: nodeSession.commands
})
});
if (!allowed.ok) {
params.respond(false, void 0, errorShape(ErrorCodes.INVALID_REQUEST, `node command not allowed: ${params.command} (${allowed.reason})`, { details: {
command: params.command,
reason: allowed.reason
} }));
return;
}
}
await respondUnavailableOnThrow(params.respond, async () => {
let nodeCommandDispatched = false;
const res = await params.context.nodeRegistry.invoke({
nodeId,
...nodeSession ? {
expectedConnId: nodeSession.connId,
...nodeSession.pairingGeneration ? { expectedPairingGeneration: nodeSession.pairingGeneration } : {}
} : {},
command: params.command,
params: params.commandParams(parsedParams, nodeSession),
onDispatchReady: () => {
nodeCommandDispatched = true;
}
});
if (!respondUnavailableOnNodeInvokeErrorWithProvenance(params.respond, res, { nodeCommandDispatched })) return;
const payload = params.readPayload(res);
if (params.validatePayload && !params.validatePayload(payload)) {
params.respond(false, void 0, errorShape(ErrorCodes.INVALID_REQUEST, "node returned invalid exec approvals payload"));
return;
}
params.respond(true, payload, void 0);
});
}
const execApprovalsHandlers = {
"exec.approvals.get": async ({ params, respond }) => {
if (!assertValidParams(params, validateExecApprovalsGetParams, "exec.approvals.get", respond)) return;
await respondUnavailableOnThrow(respond, async () => {
respond(true, toExecApprovalsPayload(await ensureExecApprovalsSnapshot()), void 0);
});
},
"exec.approvals.set": async ({ params, respond }) => {
if (!assertValidParams(params, validateExecApprovalsSetParams, "exec.approvals.set", respond)) return;
await respondUnavailableOnThrow(respond, async () => {
const snapshot = readExecApprovalsSnapshot();
if (!requireApprovalsBaseHash(params, snapshot, respond)) return;
const incoming = params.file;
if (!incoming || typeof incoming !== "object") {
respond(false, void 0, errorShape(ErrorCodes.INVALID_REQUEST, "exec approvals file is required"));
return;
}
const normalized = normalizeExecApprovals(incoming);
const nextSnapshot = await updateExecApprovals({
baseHash: snapshot.hash,
update: (current) => mergeExecApprovalsSocketDefaults({
normalized,
current
})
});
if (!nextSnapshot) {
respondApprovalsChanged(respond);
return;
}
respond(true, toExecApprovalsPayload(nextSnapshot), void 0);
});
},
"exec.approvals.node.get": async ({ params, respond, context }) => {
await respondWithExecApprovalsNodePayload({
method: "exec.approvals.node.get",
rawParams: params,
validate: validateExecApprovalsNodeGetParams,
context,
respond,
command: "system.execApprovals.get",
commandParams: (_parsedParams, nodeSession) => isMacAppNode(nodeSession) ? { includeResolvedDefaults: true } : {},
readPayload: (res) => res.payloadJSON ? parseGatewayPayload(res.payloadJSON) : res.payload,
validatePayload: validateExecApprovalsNodeSnapshot
});
},
"exec.approvals.node.set": async ({ params, respond, context }) => {
await respondWithExecApprovalsNodePayload({
method: "exec.approvals.node.set",
rawParams: params,
validate: validateExecApprovalsNodeSetParams,
context,
respond,
command: "system.execApprovals.set",
commandParams: (parsedParams) => "native" in parsedParams ? {
...parsedParams.native,
baseHash: parsedParams.baseHash
} : {
file: parsedParams.file,
baseHash: parsedParams.baseHash
},
readPayload: (res) => res.payloadJSON ? parseGatewayPayload(res.payloadJSON) : res.payload
});
}
};
//#endregion
export { execApprovalsHandlers };