Skip to content

Commit

Permalink
fix: improve compatibility of Google Cloud Functions, req.body is t…
Browse files Browse the repository at this point in the history
…he parsed JSON payload (#937)
  • Loading branch information
Uzlopak committed Dec 4, 2023
1 parent fe00834 commit adcfa21
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 4 deletions.
18 changes: 14 additions & 4 deletions src/middleware/node/get-payload.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,21 @@ import AggregateError from "aggregate-error";
type IncomingMessage = any;

export function getPayload(request: IncomingMessage): Promise<string> {
// If request.body already exists we can stop here
// See https://github.com/octokit/webhooks.js/pull/23

if (request.body) return Promise.resolve(request.body);
if ("body" in request) {
if (
typeof request.body === "object" &&
"rawBody" in request &&
request.rawBody instanceof Buffer
) {
// The body is already an Object and rawBody is a Buffer (e.g. GCF)
return Promise.resolve(request.rawBody.toString("utf8"));
} else {
// The body is a String (e.g. Lambda)
return Promise.resolve(request.body);
}
}

// We need to load the payload from the request (normal case of Node.js server)
return new Promise((resolve, reject) => {
let data: Buffer[] = [];

Expand Down
44 changes: 44 additions & 0 deletions test/integration/node-middleware.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -654,3 +654,47 @@ describe("createNodeMiddleware(webhooks)", () => {
server.close();
});
});

test("request.body is already an Object and has request.rawBody as Buffer (e.g. GCF)", async () => {
expect.assertions(3);

const webhooks = new Webhooks({
secret: "mySecret",
});
const dataChunks: any[] = [];
const middleware = createNodeMiddleware(webhooks);

const server = createServer((req, res) => {
req.once("data", (chunk) => dataChunks.push(chunk));
req.once("end", () => {
// @ts-expect-error - TS2339: Property 'rawBody' does not exist on type 'IncomingMessage'.
req.rawBody = Buffer.concat(dataChunks);
// @ts-expect-error - TS2339: Property 'body' does not exist on type 'IncomingMessage'.
req.body = JSON.parse(req.rawBody);
middleware(req, res);
});
}).listen();

webhooks.on("push", (event) => {
expect(event.id).toBe("123e4567-e89b-12d3-a456-426655440000");
});

// @ts-expect-error complains about { port } although it's included in returned AddressInfo interface
const { port } = server.address();

const response = await fetch(`http://localhost:${port}/api/github/webhooks`, {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-GitHub-Delivery": "123e4567-e89b-12d3-a456-426655440000",
"X-GitHub-Event": "push",
"X-Hub-Signature-256": signatureSha256,
},
body: pushEventPayload,
});

expect(response.status).toEqual(200);
expect(await response.text()).toEqual("ok\n");

server.close();
});

0 comments on commit adcfa21

Please sign in to comment.