From 3de5bf0dec7dac42f261a4a9cf45252b5d2bdcf4 Mon Sep 17 00:00:00 2001 From: Mark Nesbitt Date: Fri, 9 Oct 2026 11:49:50 -0400 Subject: [PATCH] Fix missing return in expressProxyHandler and nextProxyHandler --- packages/sdk-server/package.json | 1 + .../src/__tests__/proxy-handler-test.ts | 78 +++++++++++++++++++ packages/sdk-server/src/sdk-client.ts | 2 + 3 files changed, 81 insertions(+) create mode 100644 packages/sdk-server/src/__tests__/proxy-handler-test.ts diff --git a/packages/sdk-server/package.json b/packages/sdk-server/package.json index 97ad6e46e6..548e58d50e 100644 --- a/packages/sdk-server/package.json +++ b/packages/sdk-server/package.json @@ -42,6 +42,7 @@ "version": "node -p \"'export const VERSION = ' + JSON.stringify(require('./package.json').name + '@' + require('./package.json').version) + ';'\" > src/__generated__/version.ts", "build": "rollup -c", "clean": "rimraf ./dist ./.cache", + "test": "jest src/__tests__/proxy-handler-test.ts", "typecheck": "tsc --noEmit", "prepublishOnly": "pnpm run clean && pnpm run build", "codegen": "node scripts/codegen.js" diff --git a/packages/sdk-server/src/__tests__/proxy-handler-test.ts b/packages/sdk-server/src/__tests__/proxy-handler-test.ts new file mode 100644 index 0000000000..ec1eca3937 --- /dev/null +++ b/packages/sdk-server/src/__tests__/proxy-handler-test.ts @@ -0,0 +1,78 @@ +import { describe, expect, test } from "@jest/globals"; +import type { Request, Response } from "express"; + +import type { NextApiRequest, NextApiResponse } from "../__types__/base"; +import { TurnkeyServerSDK } from "../sdk-client"; + +const serverConfig = { + apiBaseUrl: "https://api.turnkey.com", + apiPublicKey: "public-key", + apiPrivateKey: "private-key", + defaultOrganizationId: "organization-id", +}; + +// Express throws ERR_HTTP_HEADERS_SENT on a second send. Without a return +// after the 400, that rejection escapes the async handler and exits Node. +function createResponse() { + let sent = false; + + return { + statusCode: 0, + body: undefined as unknown, + status(statusCode: number) { + this.statusCode = statusCode; + return this; + }, + send(body: unknown) { + if (sent) { + throw Object.assign( + new Error("Cannot set headers after they are sent to the client"), + { code: "ERR_HTTP_HEADERS_SENT" }, + ); + } + sent = true; + this.body = body; + }, + json(body: unknown) { + this.send(body); + }, + }; +} + +const incompleteBodies = [{}, { methodName: "emailAuth" }, { params: [{}] }]; + +describe("proxy handler validation", () => { + test.each(incompleteBodies)( + "expressProxyHandler responds 400 once for %j", + async (body) => { + const response = createResponse(); + + await expect( + new TurnkeyServerSDK(serverConfig).expressProxyHandler({})( + { body } as Request, + response as unknown as Response, + ), + ).resolves.toBeUndefined(); + + expect(response.statusCode).toBe(400); + expect(response.body).toBe("methodName and params are required."); + }, + ); + + test.each(incompleteBodies)( + "nextProxyHandler responds 400 once for %j", + async (body) => { + const response = createResponse(); + + await expect( + new TurnkeyServerSDK(serverConfig).nextProxyHandler({})( + { body } as NextApiRequest, + response as unknown as NextApiResponse, + ), + ).resolves.toBeUndefined(); + + expect(response.statusCode).toBe(400); + expect(response.body).toBe("methodName and params are required."); + }, + ); +}); diff --git a/packages/sdk-server/src/sdk-client.ts b/packages/sdk-server/src/sdk-client.ts index 2af90c53d5..50249e4256 100644 --- a/packages/sdk-server/src/sdk-client.ts +++ b/packages/sdk-server/src/sdk-client.ts @@ -105,6 +105,7 @@ export class TurnkeyServerSDK { const { methodName, params } = request.body; if (!methodName || !params) { response.status(400).send("methodName and params are required."); + return; } try { @@ -137,6 +138,7 @@ export class TurnkeyServerSDK { const { methodName, params } = request.body; if (!methodName || !params) { response.status(400).send("methodName and params are required."); + return; } try {