Created
October 28, 2024 14:14
-
-
Save emerleite/beebcd91c8a42c20371979d656c9ed12 to your computer and use it in GitHub Desktop.
Revisions
-
emerleite created this gist
Oct 28, 2024 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,68 @@ import { createMiddleware } from 'hono/factory' export function metaValidateWebhookSignature() { return createMiddleware(async (c, next) => { const requestBody = await c.req.arrayBuffer() const payloadSignature = c.req.header('X-Hub-Signature-256') const validRequest = await verifySignature(c.env.META_API_SECRET, requestBody, payloadSignature) console.log('Meta Valid Request?', validRequest) if (!validRequest) { return c.json({ error: 'Invalid signature' }, 403) } await next() }) } /* Meta Docs https://developers.facebook.com/docs/messenger-platform/webhooks/ https://developers.facebook.com/docs/whatsapp/cloud-api/webhooks/components https://developers.facebook.com/docs/graph-api/webhooks/getting-started#create-endpoint https://developers.facebook.com/docs/whatsapp/cloud-api/guides/set-up-webhooks https://developers.facebook.com/docs/whatsapp/cloud-api/webhooks/payload-examples/ Research https://developers.facebook.com/docs/whatsapp/sample-app-endpoints https://stackoverflow.com/questions/72813196/how-to-register-whatsapp-webhooks-in-nodejs https://glitch.com/edit/#!/whatsapp-cloud-api-echo-bot https://www.linkedin.com/pulse/facebook-webhook-payload-signature-verification-aspnet-rehman-tw8xf/ */ async function verifySignature(secret, payload, signatureHeader) { if (!signatureHeader || signatureHeader.length == 0) { return false; } const signature = signatureHeader.split('sha256=')[1] if (!signature || signature.length == 0) { return false; } // Encode the secret and the order const encoder = new TextEncoder(); const encodedSecret = encoder.encode(secret); const encodedPayload = new Uint8Array(payload).buffer; // Import the secret key const key = await crypto.subtle.importKey( 'raw', encodedSecret, { name: 'HMAC', hash: 'SHA-256' }, false, ['sign'] ); // Create the HMAC signature const signatureArrayBuffer = await crypto.subtle.sign( 'HMAC', key, encodedPayload ); // Convert the ArrayBuffer to a hexadecimal string const calculatedSignature = Array.from(new Uint8Array(signatureArrayBuffer)) .map(byte => byte.toString(16).padStart(2, '0')) .join(''); return signature === calculatedSignature; }