fix: sanitize node invoke result params
This commit is contained in:
34
src/node-host/runner.test.ts
Normal file
34
src/node-host/runner.test.ts
Normal file
@@ -0,0 +1,34 @@
|
||||
import { describe, expect, test } from "vitest";
|
||||
|
||||
import { buildNodeInvokeResultParams } from "./runner.js";
|
||||
|
||||
describe("buildNodeInvokeResultParams", () => {
|
||||
test("omits optional fields when null/undefined", () => {
|
||||
const params = buildNodeInvokeResultParams(
|
||||
{ id: "invoke-1", nodeId: "node-1", command: "system.run" },
|
||||
{ ok: true, payloadJSON: null, error: null },
|
||||
);
|
||||
|
||||
expect(params).toEqual({ id: "invoke-1", nodeId: "node-1", ok: true });
|
||||
expect("payloadJSON" in params).toBe(false);
|
||||
expect("error" in params).toBe(false);
|
||||
});
|
||||
|
||||
test("includes payloadJSON when provided", () => {
|
||||
const params = buildNodeInvokeResultParams(
|
||||
{ id: "invoke-2", nodeId: "node-2", command: "system.run" },
|
||||
{ ok: true, payloadJSON: '{"ok":true}' },
|
||||
);
|
||||
|
||||
expect(params.payloadJSON).toBe('{"ok":true}');
|
||||
});
|
||||
|
||||
test("includes payload when provided", () => {
|
||||
const params = buildNodeInvokeResultParams(
|
||||
{ id: "invoke-3", nodeId: "node-3", command: "system.run" },
|
||||
{ ok: false, payload: { reason: "bad" } },
|
||||
);
|
||||
|
||||
expect(params.payload).toEqual({ reason: "bad" });
|
||||
});
|
||||
});
|
||||
@@ -833,19 +833,52 @@ async function sendInvokeResult(
|
||||
},
|
||||
) {
|
||||
try {
|
||||
await client.request("node.invoke.result", {
|
||||
id: frame.id,
|
||||
nodeId: frame.nodeId,
|
||||
ok: result.ok,
|
||||
payload: result.payload,
|
||||
payloadJSON: result.payloadJSON ?? null,
|
||||
error: result.error ?? null,
|
||||
});
|
||||
await client.request("node.invoke.result", buildNodeInvokeResultParams(frame, result));
|
||||
} catch {
|
||||
// ignore: node invoke responses are best-effort
|
||||
}
|
||||
}
|
||||
|
||||
export function buildNodeInvokeResultParams(
|
||||
frame: NodeInvokeRequestPayload,
|
||||
result: {
|
||||
ok: boolean;
|
||||
payload?: unknown;
|
||||
payloadJSON?: string | null;
|
||||
error?: { code?: string; message?: string } | null;
|
||||
},
|
||||
): {
|
||||
id: string;
|
||||
nodeId: string;
|
||||
ok: boolean;
|
||||
payload?: unknown;
|
||||
payloadJSON?: string;
|
||||
error?: { code?: string; message?: string };
|
||||
} {
|
||||
const params: {
|
||||
id: string;
|
||||
nodeId: string;
|
||||
ok: boolean;
|
||||
payload?: unknown;
|
||||
payloadJSON?: string;
|
||||
error?: { code?: string; message?: string };
|
||||
} = {
|
||||
id: frame.id,
|
||||
nodeId: frame.nodeId,
|
||||
ok: result.ok,
|
||||
};
|
||||
if (result.payload !== undefined) {
|
||||
params.payload = result.payload;
|
||||
}
|
||||
if (typeof result.payloadJSON === "string") {
|
||||
params.payloadJSON = result.payloadJSON;
|
||||
}
|
||||
if (result.error) {
|
||||
params.error = result.error;
|
||||
}
|
||||
return params;
|
||||
}
|
||||
|
||||
async function sendNodeEvent(client: GatewayClient, event: string, payload: unknown) {
|
||||
try {
|
||||
await client.request("node.event", {
|
||||
|
||||
Reference in New Issue
Block a user