openclaw
Version:
Multi-channel AI gateway with extensible messaging integrations
176 lines (175 loc) • 8.05 kB
JavaScript
import { r as captureOpenClawStateWorkerContext } from "./openclaw-state-worker-context-BvvgY6-t.mjs";
import { n as GATEWAY_CLIENT_IDS, r as GATEWAY_CLIENT_MODES } from "./client-info-BgcoFakQ.mjs";
import { en as validateExecApprovalsGetParams, in as validateExecApprovalsSetParams, nn as validateExecApprovalsNodeSetParams, rn as validateExecApprovalsNodeSnapshot, tn as validateExecApprovalsNodeGetParams } from "./src-D6kL8tMP.mjs";
import { t as ErrorCodes } from "./gateway-error-details-gTekQWj2.mjs";
import { d as errorShape } from "./error-codes-D0WRV4Bq.mjs";
import { u as normalizeExecApprovalsInternal } from "./exec-approvals-migration-gate-BHpUkl4x.mjs";
import { t as resolveExecApprovalsFromFileInternal } from "./exec-approvals-resolver-C1cTECqF.mjs";
import { d as updateExecApprovals, l as readExecApprovalsSnapshotAsync, n as ensureExecApprovalsSnapshot } from "./exec-approvals-store-B-TRUVtg.mjs";
import { t as redactExecApprovals } from "./exec-approvals-BkzkbwrB.mjs";
import { a as readGatewayRequestMutationAuthority } from "./session-mutation-guards-CQnYdW-6.mjs";
import { l as resolveNodeCommandAllowlist, o as isNodeCommandAllowed } from "./node-command-policy-I3ly1VaT.mjs";
import { n as respondUnavailableOnNodeInvokeErrorWithProvenance, r as parseGatewayPayload } from "./nodes.helpers-UXSISi6G.mjs";
import { n as defineValidatedGatewayHandler, t as assertValidParams } from "./validation-UW_NLjlV.mjs";
import { n as respondUnavailableOnThrow } from "./response-DOs02N6Y.mjs";
import { n as localStateOwnerChangedError, t as captureLocalStateMutationGuard } from "./local-state-owner-BC6QxYKq.mjs";
import { t as resolveBaseHashParam } from "./base-hash-DxpcXxxb.mjs";
//#region src/gateway/server-methods/exec-approvals.ts
function requireApprovalsBaseHash(params, snapshot, respond) {
const baseHash = resolveBaseHashParam(params);
if (snapshot.exists && (!snapshot.hash || !baseHash)) {
respond(false, void 0, errorShape(ErrorCodes.INVALID_REQUEST, `exec approvals base hash ${snapshot.hash ? "required" : "unavailable"}; re-run exec.approvals.get and retry`));
return false;
}
if (baseHash && 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: resolveExecApprovalsFromFileInternal({ file: snapshot.file }).defaults
};
}
function captureExecApprovalsOwnerGuard(expectedOwnerId, options) {
const authority = readGatewayRequestMutationAuthority(options);
try {
const assertOwner = expectedOwnerId ? captureLocalStateMutationGuard(expectedOwnerId, options) : void 0;
return {
assertPreparationCurrent: authority.assertPreparationCurrent,
assertCurrent: () => {
if (authority.family === "worker") {
authority.assertWorkerCurrent();
authority.expectedProfileBinding?.assertCurrent();
} else authority.assertCurrent();
assertOwner?.();
}
};
} catch (error) {
options.respond(false, void 0, localStateOwnerChangedError(error));
return null;
}
}
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);
}
function execApprovalsNodeHandler(definition) {
return defineValidatedGatewayHandler(definition.method, definition.validate, async ({ params, context, respond }) => {
const nodeId = params.nodeId.trim();
if (!nodeId) {
respond(false, void 0, errorShape(ErrorCodes.INVALID_REQUEST, "nodeId required"));
return;
}
const nodeSession = context.nodeRegistry.get(nodeId);
if (nodeSession) {
const allowed = isNodeCommandAllowed({
command: definition.command,
declaredCommands: nodeSession.commands,
allowlist: resolveNodeCommandAllowlist(context.getRuntimeConfig(), {
...nodeSession,
approvedCommands: nodeSession.commands
})
});
if (!allowed.ok) {
respond(false, void 0, errorShape(ErrorCodes.INVALID_REQUEST, `node command not allowed: ${definition.command} (${allowed.reason})`, { details: {
command: definition.command,
reason: allowed.reason
} }));
return;
}
}
await respondUnavailableOnThrow(respond, async () => {
let nodeCommandDispatched = false;
const res = await context.nodeRegistry.invoke({
nodeId,
...nodeSession ? {
expectedConnId: nodeSession.connId,
...nodeSession.pairingGeneration ? { expectedPairingGeneration: nodeSession.pairingGeneration } : {}
} : {},
command: definition.command,
params: definition.commandParams(params, nodeSession),
onDispatchReady: () => {
nodeCommandDispatched = true;
}
});
if (!respondUnavailableOnNodeInvokeErrorWithProvenance(respond, res, { nodeCommandDispatched })) return;
const payload = res.payloadJSON ? parseGatewayPayload(res.payloadJSON) : res.payload;
if (definition.validatePayload && !definition.validatePayload(payload)) {
respond(false, void 0, errorShape(ErrorCodes.INVALID_REQUEST, "node returned invalid exec approvals payload"));
return;
}
respond(true, payload, void 0);
});
});
}
const execApprovalsHandlers = {
"exec.approvals.get": async (options) => {
const { params, respond } = options;
if (!assertValidParams(params, validateExecApprovalsGetParams, "exec.approvals.get", respond)) return;
const guard = captureExecApprovalsOwnerGuard(params.expectedOwnerId, options);
if (guard === null) return;
await respondUnavailableOnThrow(respond, async () => {
guard.assertPreparationCurrent();
const snapshot = params.expectedOwnerId ? await readExecApprovalsSnapshotAsync() : await ensureExecApprovalsSnapshot(guard.assertCurrent, guard.assertPreparationCurrent);
guard.assertCurrent();
respond(true, toExecApprovalsPayload(snapshot), void 0);
});
},
"exec.approvals.set": async (options) => {
const { params, respond } = options;
if (!assertValidParams(params, validateExecApprovalsSetParams, "exec.approvals.set", respond)) return;
const guard = captureExecApprovalsOwnerGuard(params.expectedOwnerId, options);
if (guard === null) return;
await respondUnavailableOnThrow(respond, async () => {
guard.assertPreparationCurrent();
const context = captureOpenClawStateWorkerContext();
const snapshot = await readExecApprovalsSnapshotAsync(context);
guard.assertPreparationCurrent();
if (!requireApprovalsBaseHash(params, snapshot, respond)) return;
const normalized = normalizeExecApprovalsInternal(params.file);
const nextSnapshot = await updateExecApprovals({
baseHash: snapshot.hash,
...guard,
update: {
kind: "replace",
file: normalized,
preserveSocket: true
}
}, context);
if (!nextSnapshot) {
respondApprovalsChanged(respond);
return;
}
context.admission.assertCurrent();
guard.assertCurrent();
respond(true, toExecApprovalsPayload(nextSnapshot), void 0);
});
},
"exec.approvals.node.get": execApprovalsNodeHandler({
method: "exec.approvals.node.get",
validate: validateExecApprovalsNodeGetParams,
command: "system.execApprovals.get",
commandParams: (_parsedParams, nodeSession) => isMacAppNode(nodeSession) ? { includeResolvedDefaults: true } : {},
validatePayload: validateExecApprovalsNodeSnapshot
}),
"exec.approvals.node.set": execApprovalsNodeHandler({
method: "exec.approvals.node.set",
validate: validateExecApprovalsNodeSetParams,
command: "system.execApprovals.set",
commandParams: (parsedParams) => "native" in parsedParams ? {
...parsedParams.native,
baseHash: parsedParams.baseHash
} : {
file: parsedParams.file,
baseHash: parsedParams.baseHash
}
})
};
//#endregion
export { execApprovalsHandlers };