From 4523260dda109b5113b0ebfc1a0c0b745f09b45c Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Sat, 14 Mar 2026 00:31:48 +0000 Subject: [PATCH] test: share gateway route auth helpers --- .../chat.abort-authorization.test.ts | 29 +++++------ src/gateway/server/plugins-http.test.ts | 51 ++++++++----------- 2 files changed, 34 insertions(+), 46 deletions(-) diff --git a/src/gateway/server-methods/chat.abort-authorization.test.ts b/src/gateway/server-methods/chat.abort-authorization.test.ts index ed8a92e48a0..52955904c87 100644 --- a/src/gateway/server-methods/chat.abort-authorization.test.ts +++ b/src/gateway/server-methods/chat.abort-authorization.test.ts @@ -30,16 +30,20 @@ async function invokeSingleRunAbort({ }); } +function createSingleAbortContext() { + return createChatAbortContext({ + chatAbortControllers: new Map([ + [ + "run-1", + createActiveRun("main", { owner: { connId: "conn-owner", deviceId: "dev-owner" } }), + ], + ]), + }); +} + describe("chat.abort authorization", () => { it("rejects explicit run aborts from other clients", async () => { - const context = createChatAbortContext({ - chatAbortControllers: new Map([ - [ - "run-1", - createActiveRun("main", { owner: { connId: "conn-owner", deviceId: "dev-owner" } }), - ], - ]), - }); + const context = createSingleAbortContext(); const respond = await invokeSingleRunAbort({ context, @@ -104,14 +108,7 @@ describe("chat.abort authorization", () => { }); it("allows operator.admin clients to bypass owner checks", async () => { - const context = createChatAbortContext({ - chatAbortControllers: new Map([ - [ - "run-1", - createActiveRun("main", { owner: { connId: "conn-owner", deviceId: "dev-owner" } }), - ], - ]), - }); + const context = createSingleAbortContext(); const respond = await invokeSingleRunAbort({ context, diff --git a/src/gateway/server/plugins-http.test.ts b/src/gateway/server/plugins-http.test.ts index e5062686246..1a4866d7d23 100644 --- a/src/gateway/server/plugins-http.test.ts +++ b/src/gateway/server/plugins-http.test.ts @@ -111,6 +111,23 @@ function createSecurePluginRouteHandler(params: { }); } +async function invokeSecureGatewayRoute(params: { gatewayAuthSatisfied: boolean }) { + const exactPluginHandler = vi.fn(async () => false); + const prefixGatewayHandler = vi.fn(async () => true); + const handler = createSecurePluginRouteHandler({ + exactPluginHandler, + prefixGatewayHandler, + }); + const { res } = makeMockHttpResponse(); + const handled = await handler( + { url: "/plugin/secure/report" } as IncomingMessage, + res, + undefined, + { gatewayAuthSatisfied: params.gatewayAuthSatisfied }, + ); + return { handled, exactPluginHandler, prefixGatewayHandler }; +} + describe("createGatewayPluginRequestHandler", () => { it("caps unauthenticated plugin routes to non-admin subagent scopes", async () => { loadOpenClawPlugins.mockReset(); @@ -232,44 +249,18 @@ describe("createGatewayPluginRequestHandler", () => { }); it("fails closed when a matched gateway route reaches dispatch without auth", async () => { - const exactPluginHandler = vi.fn(async () => false); - const prefixGatewayHandler = vi.fn(async () => true); - const handler = createSecurePluginRouteHandler({ - exactPluginHandler, - prefixGatewayHandler, + const { handled, exactPluginHandler, prefixGatewayHandler } = await invokeSecureGatewayRoute({ + gatewayAuthSatisfied: false, }); - - const { res } = makeMockHttpResponse(); - const handled = await handler( - { url: "/plugin/secure/report" } as IncomingMessage, - res, - undefined, - { - gatewayAuthSatisfied: false, - }, - ); expect(handled).toBe(false); expect(exactPluginHandler).not.toHaveBeenCalled(); expect(prefixGatewayHandler).not.toHaveBeenCalled(); }); it("allows gateway route fallthrough only after gateway auth succeeds", async () => { - const exactPluginHandler = vi.fn(async () => false); - const prefixGatewayHandler = vi.fn(async () => true); - const handler = createSecurePluginRouteHandler({ - exactPluginHandler, - prefixGatewayHandler, + const { handled, exactPluginHandler, prefixGatewayHandler } = await invokeSecureGatewayRoute({ + gatewayAuthSatisfied: true, }); - - const { res } = makeMockHttpResponse(); - const handled = await handler( - { url: "/plugin/secure/report" } as IncomingMessage, - res, - undefined, - { - gatewayAuthSatisfied: true, - }, - ); expect(handled).toBe(true); expect(exactPluginHandler).toHaveBeenCalledTimes(1); expect(prefixGatewayHandler).toHaveBeenCalledTimes(1);