Skip to content

Commit

Permalink
Merge pull request #283 from domwebber/main
Browse files Browse the repository at this point in the history
Add Extracted Signatures to Webhook Event Processing Return
  • Loading branch information
domwebber authored Dec 5, 2024
2 parents 1b94920 + e022aac commit 6acf1f1
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 8 deletions.
5 changes: 5 additions & 0 deletions .changeset/fair-years-exercise.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@great-detail/whatsapp": patch
---

Return x-hub-signature-256 header alongside event notification return
5 changes: 5 additions & 0 deletions .changeset/sweet-bobcats-shout.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@great-detail/whatsapp": patch
---

Explicitly set UTF-8 encoding in signature calculation
42 changes: 34 additions & 8 deletions src/Webhook/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,10 @@ export default class Webhook {
);
}

const xHubSignature1 = request.headers["x-hub-signature"]
?.toString()
.replace("sha1=", "");

const xHubSignature256 = request.headers["x-hub-signature-256"]
?.toString()
.replace("sha256=", "");
Expand All @@ -194,22 +198,44 @@ export default class Webhook {
}

// Async request body buffering
const bodyString = Buffer.from(request.body).toString("utf8");
const bodyString = request.body;
const eventNotification = JSON.parse(
bodyString,
) as WebhookEventNotification;

return {
eventNotification,
checkSignature: (appSecret: string) => {
const generatedSignature256 = createHmac("sha256", appSecret)
.update(bodyString)
.digest("hex");
// See: https://github.com/WhatsApp/WhatsApp-Nodejs-SDK/blob/58ca3d5fceea604e18393734578d9a7944a37b15/src/utils.ts#L77-L82
const getCalculatedSignature = (alg: string) => (appSecret: string) =>
createHmac(alg, appSecret)
.update(bodyString, "utf-8")

Check failure on line 209 in src/Webhook/index.ts

View workflow job for this annotation

GitHub Actions / lint / Lint

Prefer `utf8` over `utf-8`
.digest("hex");

const checkSignature = (alg: string, signature: string) => {
const signatureCalculator = getCalculatedSignature(alg);

const isAuthentic256 = xHubSignature256 === generatedSignature256;
return (appSecret: string) => {
const generatedSignature = signatureCalculator(appSecret);

const isAuthentic256 = signature === generatedSignature;

return isAuthentic256;
};
};

return {
eventNotification,
signature: {
sha1: {
value: xHubSignature1,
getCalculatedSignature: getCalculatedSignature("sha1"),
check: checkSignature("sha1", xHubSignature1),
},
sha256: {
value: xHubSignature256,
getCalculatedSignature: getCalculatedSignature("sha256"),
check: checkSignature("sha256", xHubSignature256),
},
},
checkSignature: checkSignature("sha256", xHubSignature256),
verifySignature(appSecret: string) {
if (!this.checkSignature(appSecret)) {
throw new InvalidHubSignatureWebhookError(
Expand Down

0 comments on commit 6acf1f1

Please sign in to comment.