openclaw/src/gateway/node-invoke-system-run-approval.test.ts

86 lines
2.5 KiB
TypeScript

import { describe, expect, test } from "vitest";
import type { ExecApprovalRecord } from "./exec-approval-manager.js";
import { sanitizeSystemRunParamsForForwarding } from "./node-invoke-system-run-approval.js";
describe("sanitizeSystemRunParamsForForwarding", () => {
const now = Date.now();
const client = {
connId: "conn-1",
connect: {
scopes: ["operator.write", "operator.approvals"],
device: { id: "dev-1" },
client: { id: "cli-1" },
},
};
function makeRecord(command: string): ExecApprovalRecord {
return {
id: "approval-1",
request: {
host: "node",
command,
cwd: null,
agentId: null,
sessionKey: null,
},
createdAtMs: now - 1_000,
expiresAtMs: now + 60_000,
requestedByConnId: "conn-1",
requestedByDeviceId: "dev-1",
requestedByClientId: "cli-1",
resolvedAtMs: now - 500,
decision: "allow-once",
resolvedBy: "operator",
};
}
function manager(record: ReturnType<typeof makeRecord>) {
return {
getSnapshot: () => record,
};
}
test("rejects cmd.exe /c trailing-arg mismatch against rawCommand", () => {
const result = sanitizeSystemRunParamsForForwarding({
rawParams: {
command: ["cmd.exe", "/d", "/s", "/c", "echo", "SAFE&&whoami"],
rawCommand: "echo",
runId: "approval-1",
approved: true,
approvalDecision: "allow-once",
},
client,
execApprovalManager: manager(makeRecord("echo")),
nowMs: now,
});
expect(result.ok).toBe(false);
if (result.ok) {
throw new Error("unreachable");
}
expect(result.message).toContain("rawCommand does not match command");
expect(result.details?.code).toBe("RAW_COMMAND_MISMATCH");
});
test("accepts matching cmd.exe /c command text for approval binding", () => {
const result = sanitizeSystemRunParamsForForwarding({
rawParams: {
command: ["cmd.exe", "/d", "/s", "/c", "echo", "SAFE&&whoami"],
rawCommand: "echo SAFE&&whoami",
runId: "approval-1",
approved: true,
approvalDecision: "allow-once",
},
client,
execApprovalManager: manager(makeRecord("echo SAFE&&whoami")),
nowMs: now,
});
expect(result.ok).toBe(true);
if (!result.ok) {
throw new Error("unreachable");
}
const params = result.params as Record<string, unknown>;
expect(params.approved).toBe(true);
expect(params.approvalDecision).toBe("allow-once");
});
});