fastify-webhook
Advanced tools
Comparing version 0.3.2 to 0.4.0
# Change Log | ||
## [0.4.0](https://github.com/smartiniOnGitHub/fastify-webhook/releases/tag/0.4.0) (2019-04-01) | ||
Summary Changelog: | ||
- Align with latest Fastify v1 (and related plugins) | ||
- Updated all dependencies | ||
- Updated Tap tests | ||
- Update code to use latest ES6/7/8 syntax | ||
- Improve tests and examples, to read 'secretKey' value from env var SECRET_KEY | ||
or otherwise from a fixed default value | ||
- Breaking Change: rename plugin option 'disableDefaultWebhook' into 'disableWebhook' | ||
- Add plugin option 'enableGetPlaceholder' (default false) to publish via GET | ||
a route with the same path of the webhook, | ||
but returning an HTTP Error 405 Method Not Allowed; | ||
add a sample usage in the 'example-enhanced' | ||
## [0.3.2](https://github.com/smartiniOnGitHub/fastify-webhook/releases/tag/0.3.2) (2019-02-03) | ||
@@ -4,0 +18,0 @@ Summary Changelog: |
@@ -26,3 +26,4 @@ /* | ||
// handle secret key (fixed) and user token (user-dependent), as a sample | ||
const webhookSecretKey = 'my example Secret Key' | ||
// if the env var SECRET_KEY is defined, it's value is used, otherwise a default value will be used | ||
const webhookSecretKey = process.env.SECRET_KEY || 'my example Secret Key' | ||
@@ -61,2 +62,4 @@ function checkSecretKey (request, reply, done) { | ||
handler: webhookHandlers.echo, | ||
// disableWebhook: false, // same as default | ||
enableGetPlaceholder: true, // as a sample | ||
secretKey: webhookSecretKey, | ||
@@ -63,0 +66,0 @@ beforeHandlers: [checkSecretKey, checkTokenEven] |
{ | ||
"name": "fastify-webhook", | ||
"version": "0.3.2", | ||
"version": "0.4.0", | ||
"description": "Fastify Plugin to serve webhooks with some default settings", | ||
@@ -11,12 +11,13 @@ "main": "src/plugin", | ||
"test:unit": "tap -J test/*.test.js test/*/*.test.js", | ||
"test:unit:debug": "tap -T --strict --node-arg=--inspect-brk test/*.test.js test/*/*.test.js", | ||
"test": "npm run lint && npm run test:unit" | ||
}, | ||
"dependencies": { | ||
"fastify-plugin": "^1.4.0" | ||
"fastify-plugin": "^1.5.0" | ||
}, | ||
"devDependencies": { | ||
"fastify": "^1.13.4", | ||
"fastify": "^1.14.4", | ||
"simple-get": "^3.0.3", | ||
"standard": "^12.0.1", | ||
"tap": "^12.5.1" | ||
"tap": "^12.6.1" | ||
}, | ||
@@ -23,0 +24,0 @@ "peerDependencies": {}, |
@@ -46,2 +46,4 @@ # fastify-webhook | ||
Fastify ^1.1.0 , Node.js 8.15.x or later. | ||
Note that plugin releases 0.x and 1.x are for Fastify 1.x, | ||
plugin releases 2.x are for Fastify 2.x, etc. | ||
@@ -64,3 +66,4 @@ | ||
Other plugin options: | ||
- 'disableDefaultWebhook' (default false) to disable the registration of the route for the webhook | ||
- 'disableWebhook' (default false) to disable the registration of the route for the webhook | ||
- 'enableGetPlaceholder' (default false) to publish via GET a route with the same path of the webhook but returning an HTTP Error 405 Method Not Allowed | ||
- 'secretKey' (default null) to specify a string as secret key that callers of the webhook must provide, or webhook will reply with an error | ||
@@ -67,0 +70,0 @@ - 'beforeHandlers' is a list of functions to be used as beforeHandler in the specific route of the webhook; currently the list contains an internal function to check the secret key (if given); otherwise you can define and use yours, with signature `function beforeHandler (req, reply, done)`. |
@@ -23,43 +23,57 @@ /* | ||
function fastifyWebHook (fastify, options, next) { | ||
const opts = options || {} | ||
const webhookUrl = opts.url || '/webhook' | ||
const webhookHandler = opts.handler || webhookHandlers.acknowledge | ||
const disableDefaultWebhook = opts.disableDefaultWebhook || false | ||
const webhookSecretKey = opts.secretKey || null | ||
const webhookBeforeHandlers = opts.beforeHandlers || [ | ||
function checkSecretKey (request, reply, done) { | ||
if (webhookSecretKey) { | ||
const contentType = request.headers['content-type'] || '' | ||
const secretKey = (request.body) ? request.body.secretKey : '' | ||
if (request.req.method !== 'POST' || | ||
!contentType.startsWith('application/json') || | ||
secretKey !== webhookSecretKey) { | ||
reply.code(403).send(new Error('Missing or wrong secret key')) | ||
} | ||
const { | ||
url = '/webhook', | ||
handler = webhookHandlers.acknowledge, | ||
disableWebhook = false, | ||
enableGetPlaceholder = false, | ||
secretKey = null, | ||
beforeHandlers = [ checkSecretKey ] | ||
} = options | ||
function checkSecretKey (request, reply, done) { | ||
if (secretKey) { | ||
const contentType = request.headers['content-type'] || '' | ||
const requestSecretKey = (request.body) ? request.body.secretKey : '' | ||
if (request.req.method !== 'POST' || | ||
!contentType.startsWith('application/json') || | ||
requestSecretKey !== secretKey) { | ||
reply.code(403).send(new Error('Missing or wrong secret key')) | ||
} | ||
done() | ||
} | ||
] | ||
done() | ||
} | ||
if (typeof webhookUrl !== 'string') { | ||
throw new TypeError(`The option url must be a string, instead got a '${typeof webhookUrl}'`) | ||
// check plugin options | ||
if (typeof url !== 'string') { | ||
throw new TypeError(`The option url must be a string, instead got a '${typeof url}'`) | ||
} | ||
if (typeof webhookHandler !== 'function') { | ||
throw new TypeError(`The option webhook must be a function, instead got a '${typeof webhookHandler}'`) | ||
if (typeof handler !== 'function') { | ||
throw new TypeError(`The option webhook must be a function, instead got a '${typeof handler}'`) | ||
} | ||
if (webhookSecretKey !== null && typeof webhookSecretKey !== 'string') { | ||
throw new TypeError(`The option secretKey must be a string, instead got a '${typeof webhookSecretKey}'`) | ||
if (typeof disableWebhook !== 'boolean') { | ||
throw new TypeError(`The option disableWebhook must be a boolean, instead got a '${typeof disableWebhook}'`) | ||
} | ||
if (webhookBeforeHandlers !== null && !Array.isArray(webhookBeforeHandlers)) { | ||
throw new TypeError(`The option beforeHandlers must be an array (of functions), instead got a '${typeof webhookBeforeHandlers}'`) | ||
if (typeof enableGetPlaceholder !== 'boolean') { | ||
throw new TypeError(`The option enableGetPlaceholder must be a boolean, instead got a '${typeof enableGetPlaceholder}'`) | ||
} | ||
if (secretKey !== null && typeof secretKey !== 'string') { | ||
throw new TypeError(`The option secretKey must be a string, instead got a '${typeof secretKey}'`) | ||
} | ||
if (beforeHandlers !== null && !Array.isArray(beforeHandlers)) { | ||
throw new TypeError(`The option beforeHandlers must be an array (of functions), instead got a '${typeof beforeHandlers}'`) | ||
} | ||
// execute plugin code | ||
if (!disableDefaultWebhook) { | ||
if (disableWebhook === false) { | ||
fastify.route({ | ||
method: 'POST', | ||
url: webhookUrl, | ||
beforeHandler: webhookBeforeHandlers, | ||
handler: webhookHandler | ||
url, | ||
beforeHandler: beforeHandlers, | ||
handler | ||
}) | ||
if (enableGetPlaceholder === true) { | ||
fastify.get(url, {}, (request, reply) => { | ||
reply.code(405).send(new Error('Placeholder for a webhook, you need to call via POST')) | ||
}) | ||
} | ||
} | ||
@@ -66,0 +80,0 @@ |
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
31385
261
78
3
Updatedfastify-plugin@^1.5.0