Skip to content

event webhook - please provide example for usage in express  #1142

Closed
@psteinroe

Description

@psteinroe

Issue Summary

I am struggling with the EventWebhook signing procedure a while now and can't get it to work. Tried multiple options, including using the raw req body for the timestamp. The verification always fails..

Edit: I am using the verifySignature function from the eventwebhook package here.
Edit 2: Added sample data that was gathered by logging the respective constants.

Steps to Reproduce

  1. Setup an express server, deploy it somewhere and trigger the Webhook.

Code Snippet

import express from "express";
import cors from "cors";
import asyncHandler from "express-async-handler";
import createError from "http-errors";
// @ts-ignore
import { Ecdsa, Signature, PublicKey } from '@starkbank/ecdsa';
const app = express();
app.use(cors({ origin: true }));
app.use(
    express.json({
        verify: (req, res, buf) => {
            // @ts-ignore
            req.rawBody = buf;
        },
    })
);

const verifySignature = (publicKey: PublicKey, payload: any, signature: string, timestamp: string) => {
    let timestampPayload = typeof payload === 'object' ? JSON.stringify(payload) : payload;
    timestampPayload = timestamp + timestampPayload;
    const decodedSignature = Signature.fromBase64(signature);

    return Ecdsa.verify(timestampPayload, decodedSignature, publicKey);
}

app.post(
    "/event",
    asyncHandler(async (req, res) => {
        const signature = req.get('X-Twilio-Email-Event-Webhook-Signature');
        const timestamp = req.get('X-Twilio-Email-Event-Webhook-Timestamp');
        const payload = req.body;  // req.rawBody also does not work

        if (!signature || !timestamp || !payload) {
            throw createError(403, "Unauthorized Request");
        }

        console.log('verifying')
        console.log(signature)
        console.log(timestamp)
        console.log(JSON.stringify(payload))
        const publicKey = PublicKey.fromPem(functions.config().env.sendgrid.publicKey);
        if(!verifySignature(publicKey, payload, signature, timestamp)) {
            throw createError(403, "Unauthorized Request");
        }
        console.log('verified')

   
    })
);

// @ts-ignore
app.use((error, req, res, _) => {
    res.status(error.status || 500);
    res.json({
        status: error.status,
        message: error.message,
    });
    console.error(error.message)
});
// sample data from logs above
const TIMESTAMP = "1591866114"
const PAYLOAD = [{"email":"heyanna-test@hotmail.com","event":"bounce","ip":"167.89.17.173","mc_stats":"singlesend","phase_id":"send","reason":"550 5.5.0 Requested action not taken: mailbox unavailable (S2017062302). [VE1EUR03FT058.eop-EUR03.prod.protection.outlook.com]","send_at":"1591866054","sg_event_id":"Ym91bmNlLTAtMTU2MTI0NDktQTVjTHQweTBTWXlBLXN2N3RWNUQydy0x","sg_message_id":"A5cLt0y0SYyA-sv7tV5D2w.filterdrecv-p3iad2-784dbb6bd8-cmnvf-19-5EE1F2DB-11B.1","sg_template_id":"d-bb3d0c9fd0e1494f990a9d386437c6b0","sg_template_name":"Clone: Clone: Clone: Clone: Clone: Clone: Clone: Clone: Clone: Clone: Clone 2020-06-11T08:58:41.387Z","singlesend_id":"bfba94a4-abc1-11ea-b5ff-fac9c7677002","singlesend_name":"DEV-Test 11","smtp-id":"<A5cLt0y0SYyA-sv7tV5D2w@ismtpd0087p1mdw1.sendgrid.net>","status":"5.5.0","template_hash":"030c05c8aa7b8112e5e2d6a99def801d95ccb03f0cf0388874129b4dfb1f41e9","template_id":"d-bb3d0c9fd0e1494f990a9d386437c6b0","template_version_id":"a55a3135-fdf9-41af-8c29-7b93962baab7","timestamp":1591866077,"tls":1,"type":"bounce"}]
const PUBLIC_KEY = "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAETg3hldXJ3S/JlTbsYXdYCDuSpQHISB5C9xPgDkqjjPAyVIVhwSTR7UhIWC7mpvXa4vmCNyAucNmHAosg3p0/eA=="
const SIGNATURE = "MEYCIQCKLxRqhAbX/XlPl35AoiOII6l5D64R21TaiX4TB8sejQIhAJc/PM1SDCkfdyx6gu9Up1GjbJyHz2m6jicfyjaKJupj"

Exception/Log

Unauthorized Request

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions