fix(gateway): fail fast exec approvals when no approvers are reachable

Co-authored-by: fanxian831-netizen <262880470+fanxian831-netizen@users.noreply.github.com>
This commit is contained in:
Peter Steinberger
2026-02-22 22:13:40 +01:00
parent 73fab7e445
commit d24f5c1e3a
8 changed files with 168 additions and 47 deletions

View File

@@ -63,7 +63,7 @@ describe("exec approval forwarder", () => {
resolveSessionTarget: () => ({ channel: "slack", to: "U1" }),
});
await forwarder.handleRequested(baseRequest);
await expect(forwarder.handleRequested(baseRequest)).resolves.toBe(true);
expect(deliver).toHaveBeenCalledTimes(1);
await forwarder.handleResolved({
@@ -82,7 +82,7 @@ describe("exec approval forwarder", () => {
vi.useFakeTimers();
const { deliver, forwarder } = createForwarder({ cfg: TARGETS_CFG });
await forwarder.handleRequested(baseRequest);
await expect(forwarder.handleRequested(baseRequest)).resolves.toBe(true);
expect(deliver).toHaveBeenCalledTimes(1);
await vi.runAllTimersAsync();
@@ -93,7 +93,7 @@ describe("exec approval forwarder", () => {
vi.useFakeTimers();
const { deliver, forwarder } = createForwarder({ cfg: TARGETS_CFG });
await forwarder.handleRequested(baseRequest);
await expect(forwarder.handleRequested(baseRequest)).resolves.toBe(true);
expect(getFirstDeliveryText(deliver)).toContain("Command: `echo hello`");
});
@@ -102,17 +102,50 @@ describe("exec approval forwarder", () => {
vi.useFakeTimers();
const { deliver, forwarder } = createForwarder({ cfg: TARGETS_CFG });
await forwarder.handleRequested({
...baseRequest,
request: {
...baseRequest.request,
command: "echo `uname`\necho done",
},
});
await expect(
forwarder.handleRequested({
...baseRequest,
request: {
...baseRequest.request,
command: "echo `uname`\necho done",
},
}),
).resolves.toBe(true);
expect(getFirstDeliveryText(deliver)).toContain("Command:\n```\necho `uname`\necho done\n```");
});
it("returns false when forwarding is disabled", async () => {
const { deliver, forwarder } = createForwarder({
cfg: {} as OpenClawConfig,
});
await expect(forwarder.handleRequested(baseRequest)).resolves.toBe(false);
expect(deliver).not.toHaveBeenCalled();
});
it("returns false when all targets are skipped", async () => {
vi.useFakeTimers();
const cfg = {
channels: {
discord: {
execApprovals: {
enabled: true,
approvers: ["123"],
},
},
},
approvals: { exec: { enabled: true, mode: "session" } },
} as OpenClawConfig;
const { deliver, forwarder } = createForwarder({
cfg,
resolveSessionTarget: () => ({ channel: "discord", to: "channel:123" }),
});
await expect(forwarder.handleRequested(baseRequest)).resolves.toBe(false);
expect(deliver).not.toHaveBeenCalled();
});
it("forwards to discord when discord exec approvals handler is disabled", async () => {
vi.useFakeTimers();
const cfg = {
@@ -124,7 +157,7 @@ describe("exec approval forwarder", () => {
resolveSessionTarget: () => ({ channel: "discord", to: "channel:123" }),
});
await forwarder.handleRequested(baseRequest);
await expect(forwarder.handleRequested(baseRequest)).resolves.toBe(true);
expect(deliver).toHaveBeenCalledTimes(1);
});
@@ -148,7 +181,7 @@ describe("exec approval forwarder", () => {
resolveSessionTarget: () => ({ channel: "discord", to: "channel:123" }),
});
await forwarder.handleRequested(baseRequest);
await expect(forwarder.handleRequested(baseRequest)).resolves.toBe(false);
expect(deliver).not.toHaveBeenCalled();
});
@@ -185,13 +218,15 @@ describe("exec approval forwarder", () => {
vi.useFakeTimers();
const { deliver, forwarder } = createForwarder({ cfg: TARGETS_CFG });
await forwarder.handleRequested({
...baseRequest,
request: {
...baseRequest.request,
command: "echo ```danger```",
},
});
await expect(
forwarder.handleRequested({
...baseRequest,
request: {
...baseRequest.request,
command: "echo ```danger```",
},
}),
).resolves.toBe(true);
expect(getFirstDeliveryText(deliver)).toContain("Command:\n````\necho ```danger```\n````");
});