diff --git a/src/middleware/node/get-payload.ts b/src/middleware/node/get-payload.ts index 2856056e..f08da9b5 100644 --- a/src/middleware/node/get-payload.ts +++ b/src/middleware/node/get-payload.ts @@ -26,15 +26,7 @@ export function getPayload(request: IncomingMessage): Promise { request.on("error", (error: Error) => reject(new AggregateError([error]))); request.on("data", (chunk: string) => (data += chunk)); request.on("end", () => { - try { - // Call JSON.parse() only to check if the payload is valid JSON - JSON.parse(data); - resolve(data); - } catch (error: any) { - error.message = "Invalid JSON"; - error.status = 400; - reject(new AggregateError([error])); - } + resolve(data); }); }); } diff --git a/src/verify-and-receive.ts b/src/verify-and-receive.ts index 2165ab2b..bc14c0a8 100644 --- a/src/verify-and-receive.ts +++ b/src/verify-and-receive.ts @@ -4,11 +4,12 @@ import type { EmitterWebhookEventWithStringPayloadAndSignature, State, } from "./types"; +import AggregateError from "aggregate-error"; export async function verifyAndReceive( state: State & { secret: string }, event: EmitterWebhookEventWithStringPayloadAndSignature, -): Promise { +): Promise { // verify will validate that the secret is not undefined const matchesSignature = await verify( state.secret, @@ -26,9 +27,20 @@ export async function verifyAndReceive( ); } - return state.eventHandler.receive({ - id: event.id, - name: event.name, - payload: JSON.parse(event.payload), - }); + try { + return state.eventHandler.receive({ + id: event.id, + name: event.name, + payload: JSON.parse(event.payload), + }); + } catch (error: any) { + error.message = "Invalid JSON"; + error.status = 400; + let tmpStackTraceLimit = Error.stackTraceLimit; + Error.stackTraceLimit = 0; + const aggregateError = new AggregateError([error]); + Error.stackTraceLimit = tmpStackTraceLimit; + aggregateError.stack = error.stack; + throw aggregateError; + } } diff --git a/test/integration/node-middleware.test.ts b/test/integration/node-middleware.test.ts index 51d7eb13..e2500807 100644 --- a/test/integration/node-middleware.test.ts +++ b/test/integration/node-middleware.test.ts @@ -178,6 +178,8 @@ describe("createNodeMiddleware(webhooks)", () => { // @ts-expect-error complains about { port } although it's included in returned AddressInfo interface const { port } = server.address(); + const payload = '{"name":"invalid"'; + const response = await fetch( `http://localhost:${port}/api/github/webhooks`, { @@ -186,9 +188,9 @@ describe("createNodeMiddleware(webhooks)", () => { "Content-Type": "application/json", "X-GitHub-Delivery": "123e4567-e89b-12d3-a456-426655440000", "X-GitHub-Event": "push", - "X-Hub-Signature-256": signatureSha256, + "X-Hub-Signature-256": await sign("mySecret", payload), }, - body: "invalid", + body: payload, }, );