Skip to content

Commit

Permalink
Checks (#2)
Browse files Browse the repository at this point in the history
* skip body check on GET and HEAD.
Closes #1.

* Added headers test. Added note to README.
  • Loading branch information
arb authored and cjihrig committed Jun 2, 2016
1 parent 65b139f commit f692c0b
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 9 deletions.
10 changes: 7 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

[![belly-button-style](https://cdn.rawgit.com/continuationlabs/belly-button/master/badge.svg)](https://github.com/continuationlabs/belly-button)

`celebrate` is an express middleware function that wraps the [joi](https://github.com/hapijs/joi) validation library. This allows you to use this middleware in any single route, or globally, and ensure that all of your inputs are correct before any handler function. The middleware allows you to validate `req.params`, `req.headers`, `req.query` and `req.body` (provided you are using `body-parser`).
`celebrate` is an Express middleware function that wraps the [joi](https://github.com/hapijs/joi) validation library. This allows you to use this middleware in any single route, or globally, and ensure that all of your inputs are correct before any handler function. The middleware allows you to validate `req.params`, `req.headers`, `req.query` and `req.body` (provided you are using `body-parser`).

## Usage

Expand All @@ -32,7 +32,7 @@ app.post('/signup', Celebrate({
// At this point, req.body has been validated and is equal to req.body.name if provided in the POST or set to 'admin' by joi
});

// By default, express will try to send our errors back as HTML, if you want the JSON, add an error handler here
// By default, Express will try to send our errors back as HTML, if you want the JSON, add an error handler here
app.use((err, req, res) => {
if (err.isJoi) {
return res.status(400).send(err);
Expand All @@ -47,7 +47,7 @@ app.use((err, req, res) => {

Returns a `function` with the middleware signature (`(req, res, next)`).

- `schema` - a object where `key` can be one of `'params', 'headers', 'query', and 'body'` and the `value` is a [joi](https://github.com/hapijs/joi/blob/master/API.md) validation schema. Only the `key`s specified will be validated against the incomming `req` object. If you omit a key, that part of the `req` object will not be validated. Every schema must have at least one valid of the valid keys.
- `schema` - a object where `key` can be one of `'params', 'headers', 'query', and 'body'` and the `value` is a [joi](https://github.com/hapijs/joi/blob/master/API.md) validation schema. Only the `key`s specified will be validated against the incomming `req` object. If you omit a key, that part of the `req` object will not be validated. A schema must contain at least one of the valid keys.

## Order

Expand All @@ -59,3 +59,7 @@ Returns a `function` with the middleware signature (`(req, res, next)`).
4. `req.body`

If at any point, any of the validation fails, the entire request will be considered invalid and the rest of the validation will be short-circuited.

## Issues

*Before* opening issues on this repo, make sure your joi schema is correct and working like it's supposed to. The bulk of this code is just exposing the joi API as Express middleware. All of the heavy lifting still happens inside joi.
8 changes: 7 additions & 1 deletion lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,13 @@ module.exports = (schema) => {
Insync.apply(validateSource, 'headers'),
Insync.apply(validateSource, 'params'),
Insync.apply(validateSource, 'query'),
Insync.apply(validateSource, 'body')
(next) => {
const method = req.method.toLowerCase();
if (method === 'get' || method === 'head') {
return next();
}
validateSource('body', next);
}
], next);
};
};
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
{
"name": "celebrate",
"version": "0.1.0",
"description": "A joi validation middleware for express.",
"description": "A joi validation middleware for Express.",
"main": "lib/index.js",
"scripts": {
"lint": "belly-button -f",
"test": "npm run lint && lab -v -a code -p -t 100"
"test": "npm run lint && lab -v -a code -p -c"
},
"repository": {
"type": "git",
Expand Down
49 changes: 46 additions & 3 deletions test/index.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
'use strict';

const Code = require('code');
const Lab = require('lab');
const Joi = require('joi');
const Lab = require('lab');
const Celebrate = require('../lib');

const lab = exports.lab = Lab.script();
Expand Down Expand Up @@ -33,6 +33,26 @@ describe('Celebrate Middleware', () => {
done();
});

it('validates req.headers', (done) => {
const middleware = Celebrate({
headers: {
accept: Joi.string().regex(/xml/)
}
});

middleware({
headers: {
accept: 'application/json'
}
}, null, (err) => {
expect(err).to.exist();
expect(err.isJoi).to.be.true();
console.log(err.details[0].message);
expect(err.details[0].message).to.equal('"accept" with value "application/json" fails to match the required pattern: /xml/');
done();
});
});

it('validates req.params', (done) => {
const middleware = Celebrate({
params: {
Expand Down Expand Up @@ -84,7 +104,8 @@ describe('Celebrate Middleware', () => {
body: {
first: 'john',
last: 123
}
},
method: 'POST'
}, null, (err) => {
expect(err).to.exist();
expect(err.isJoi).to.be.true();
Expand Down Expand Up @@ -133,7 +154,8 @@ describe('Celebrate Middleware', () => {
first: 'john',
last: 'doe'
},
query: undefined
query: undefined,
method: 'POST'
};
const middleware = Celebrate({
body: {
Expand All @@ -155,4 +177,25 @@ describe('Celebrate Middleware', () => {
done();
});
});

it('does not validate req.body if the method is "GET" or "HEAD"', (done) => {
const middleware = Celebrate({
body: {
first: Joi.string().required(),
last: Joi.string(),
role: Joi.number().integer()
}
});

middleware({
body: {
first: 'john',
last: 123
},
method: 'GET'
}, null, (err) => {
expect(err).to.be.undefined();
done();
});
});
});

0 comments on commit f692c0b

Please sign in to comment.