diff --git a/config/examples/vercel-input-es-output.yml b/config/examples/vercel-input-es-output.yml index 1242c336..90f51ac9 100644 --- a/config/examples/vercel-input-es-output.yml +++ b/config/examples/vercel-input-es-output.yml @@ -5,8 +5,10 @@ input: module: input-vercel port: 8400 useIndexFromUrlPath: true - clientSecret: # workers: 4 + clientSecrets: + - + - outputFilter: diff --git a/lib/plugins/input/vercel.js b/lib/plugins/input/vercel.js index 192459bf..27195f7d 100644 --- a/lib/plugins/input/vercel.js +++ b/lib/plugins/input/vercel.js @@ -106,16 +106,27 @@ class Vercel { } verifySignature (req, body) { - const signature = crypto - .createHmac('sha1', this.config.clientSecret) - .update(body) - .digest('hex') - - if (this.config.debug) { - consoleLogger.log("Vercel signature didn't match") + if (!Array.isArray(this.config.clientSecrets)) { + if (this.config.debug) { + consoleLogger.log('clientSecrets config value is not an array. Please set it to an array.') + } + return } - return signature === req.headers['x-zeit-signature'] + const verified = this.config.clientSecrets.some(clientSecret => { + const signature = crypto + .createHmac('sha1', clientSecret) + .update(body) + .digest('hex') + + if (this.config.debug) { + consoleLogger.log(`Vercel signature didn't match for Vercel Client Secret: ${clientSecret}`) + } + + return signature === req.headers['x-zeit-signature'] + }) + + return verified } HttpHandler (req, res) { diff --git a/test/vercel/vercelSignature.spec.js b/test/vercel/vercelSignature.spec.js new file mode 100644 index 00000000..ab66f681 --- /dev/null +++ b/test/vercel/vercelSignature.spec.js @@ -0,0 +1,47 @@ +/* global describe, it */ +const assert = require('assert') +const crypto = require('crypto') +const sampleClientSecret = 'idmnMEd7Yx4QmgzZpZ4axXoe' +const sampleBody = { + id: 1, + message: '1' +} +const sampleBodyBuf = Buffer.from(JSON.stringify(sampleBody)) +const sampleSignature = crypto + .createHmac('sha1', sampleClientSecret) + .update(sampleBodyBuf) + .digest('hex') + +const sampleReq = { + headers: { + 'x-zeit-signature': sampleSignature + } +} +const configWithArrayWithTwoClientSecrets = { + clientSecrets: [sampleClientSecret, sampleClientSecret] +} +const configWithArrayWithOneClientSecret = { + clientSecrets: [sampleClientSecret] +} +const EventEmitter = require('events') +const evem = new EventEmitter() + +/** + * Init Vercel Class + */ +const Vercel = require('../../lib/plugins/input/vercel') +const vercelWithArrayWithTwoSecrets = new Vercel(configWithArrayWithTwoClientSecrets, evem) +const vercelWithArrayWithOneSecret = new Vercel(configWithArrayWithOneClientSecret, evem) + +describe('verifySignature should', function () { + it('return true for an array with 2 secrets', function (done) { + const signature = vercelWithArrayWithTwoSecrets.verifySignature(sampleReq, sampleBodyBuf) + assert.strictEqual(signature, true) + done() + }) + it('return true for an array with 1 secret', function (done) { + const signature = vercelWithArrayWithOneSecret.verifySignature(sampleReq, sampleBodyBuf) + assert.strictEqual(signature, true) + done() + }) +})