nylas / nylas-nodejs

A NodeJS wrapper for the Nylas REST API for email, contacts, and calendar.
MIT License
169 stars 118 forks source link

Add support for verifying webhook signatures #442

Closed mrashed-dev closed 1 year ago

mrashed-dev commented 1 year ago

Description

This PR adds support for verifying the webhook signature of inbound webhook notifications.

Usage

const Nylas = require('nylas');
const express = require('express');
const cors = require('cors');

const app = express();

// Enable CORS
app.use(cors());

// The port the express app will run on
const port = 9000;

// Nylas app credentials
const NYLAS_CLIENT_SECRET = process.env.NYLAS_CLIENT_SECRET;
if (!NYLAS_CLIENT_SECRET) {
  throw new Error('NYLAS_CLIENT_SECRET is required')
}

// Create a callback route for the Nylas Event Webhook
app.post('/', express.json(), async (req, res) => {
  // Verify the Nylas Event Webhook signature to ensure the request is coming from Nylas
  const signature =
    req.headers['x-nylas-signature'] || req.headers['X-Nylas-Signature'];
  if (
    !WebhookNotification.verifyWebhookSignature(
      NYLAS_CLIENT_SECRET,
      signature,
      JSON.stringify(req.body)
    )
  ) {
    res.status(403).send('Invalid signature');
  }

  const { body } = req;

  // Log the webhook event to the console
  console.log('Webhook event received: ', JSON.stringify(body, undefined, 2));

  // Send a 200 response to the Nylas Event Webhook
  res.status(200).send({ success: true });
});

License

I confirm that this contribution is made under the terms of the MIT license and that I have the authority necessary to make this contribution on behalf of its copyright owner.

AaronDDM commented 1 year ago

Actually, @mrashed-dev could we not obtain the secret from the Client itself? If setup? Normally most users would probably setup the Nylas Client as well to expand the deltas.

mrashed-dev commented 1 year ago

@AaronDDM good call out, made it an optional override, will default to whatever the SDK was configured with.

ianzone commented 1 year ago

the second param of verifyWebhookSignature is a buffer, do you mean to pass Buffer.from(JSON.stringify(req.body), 'utf8') ?