mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-08 09:31:25 +00:00
fix(gateway): bind system.run approvals to exec approvals
This commit is contained in:
@@ -15,7 +15,7 @@ export function createExecApprovalHandlers(
|
||||
opts?: { forwarder?: ExecApprovalForwarder },
|
||||
): GatewayRequestHandlers {
|
||||
return {
|
||||
"exec.approval.request": async ({ params, respond, context }) => {
|
||||
"exec.approval.request": async ({ params, respond, context, client }) => {
|
||||
if (!validateExecApprovalRequestParams(params)) {
|
||||
respond(
|
||||
false,
|
||||
@@ -64,6 +64,9 @@ export function createExecApprovalHandlers(
|
||||
sessionKey: p.sessionKey ?? null,
|
||||
};
|
||||
const record = manager.create(request, timeoutMs, explicitId);
|
||||
record.requestedByConnId = client?.connId ?? null;
|
||||
record.requestedByDeviceId = client?.connect?.device?.id ?? null;
|
||||
record.requestedByClientId = client?.connect?.client?.id ?? null;
|
||||
// Use register() to synchronously add to pending map before sending any response.
|
||||
// This ensures the approval ID is valid immediately after the "accepted" response.
|
||||
let decisionPromise: Promise<
|
||||
|
||||
@@ -10,6 +10,7 @@ import {
|
||||
verifyNodeToken,
|
||||
} from "../../infra/node-pairing.js";
|
||||
import { isNodeCommandAllowed, resolveNodeCommandAllowlist } from "../node-command-policy.js";
|
||||
import { sanitizeSystemRunParamsForForwarding } from "../node-invoke-system-run-approval.js";
|
||||
import {
|
||||
ErrorCodes,
|
||||
errorShape,
|
||||
@@ -361,7 +362,7 @@ export const nodeHandlers: GatewayRequestHandlers = {
|
||||
);
|
||||
});
|
||||
},
|
||||
"node.invoke": async ({ params, respond, context }) => {
|
||||
"node.invoke": async ({ params, respond, context, client }) => {
|
||||
if (!validateNodeInvokeParams(params)) {
|
||||
respondInvalidParams({
|
||||
respond,
|
||||
@@ -417,10 +418,28 @@ export const nodeHandlers: GatewayRequestHandlers = {
|
||||
);
|
||||
return;
|
||||
}
|
||||
const forwardedParams =
|
||||
command === "system.run"
|
||||
? sanitizeSystemRunParamsForForwarding({
|
||||
rawParams: p.params,
|
||||
client,
|
||||
execApprovalManager: context.execApprovalManager,
|
||||
})
|
||||
: ({ ok: true, params: p.params } as const);
|
||||
if (!forwardedParams.ok) {
|
||||
respond(
|
||||
false,
|
||||
undefined,
|
||||
errorShape(ErrorCodes.INVALID_REQUEST, forwardedParams.message, {
|
||||
details: forwardedParams.details ?? null,
|
||||
}),
|
||||
);
|
||||
return;
|
||||
}
|
||||
const res = await context.nodeRegistry.invoke({
|
||||
nodeId,
|
||||
command,
|
||||
params: p.params,
|
||||
params: forwardedParams.params,
|
||||
timeoutMs: p.timeoutMs,
|
||||
idempotencyKey: p.idempotencyKey,
|
||||
});
|
||||
|
||||
@@ -5,6 +5,7 @@ import type { CronService } from "../../cron/service.js";
|
||||
import type { createSubsystemLogger } from "../../logging/subsystem.js";
|
||||
import type { WizardSession } from "../../wizard/session.js";
|
||||
import type { ChatAbortControllerEntry } from "../chat-abort.js";
|
||||
import type { ExecApprovalManager } from "../exec-approval-manager.js";
|
||||
import type { NodeRegistry } from "../node-registry.js";
|
||||
import type { ConnectParams, ErrorShape, RequestFrame } from "../protocol/index.js";
|
||||
import type { ChannelRuntimeSnapshot } from "../server-channels.js";
|
||||
@@ -28,6 +29,7 @@ export type GatewayRequestContext = {
|
||||
deps: ReturnType<typeof createDefaultDeps>;
|
||||
cron: CronService;
|
||||
cronStorePath: string;
|
||||
execApprovalManager?: ExecApprovalManager;
|
||||
loadGatewayModelCatalog: () => Promise<ModelCatalogEntry[]>;
|
||||
getHealthCache: () => HealthSummary | null;
|
||||
refreshHealthSnapshot: (opts?: { probe?: boolean }) => Promise<HealthSummary>;
|
||||
|
||||
Reference in New Issue
Block a user