Skip to content

Commit

Permalink
Implement request data validation
Browse files Browse the repository at this point in the history
  • Loading branch information
hagopj13 committed Oct 27, 2019
1 parent 3a12d87 commit 23f31a3
Show file tree
Hide file tree
Showing 7 changed files with 87 additions and 2 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ It comes with many built-in features, such as authentication using JWT, request
- [MongoDB](https://www.mongodb.com) object data modeling using [Mongoose](https://mongoosejs.com)
- Dependency management with [Yarn](https://yarnpkg.com)
- Advanced production process management using [PM2](https://pm2.keymetrics.io)
- Logging using [winston](https://github.com/winstonjs/winston)
- Request data validation using [Joi](https://github.com/hapijs/joi)
- Logging using [winston](https://github.com/winstonjs/winston) and [morgan](https://github.com/expressjs/morgan)
- Centralized error handling mechanism
- Environment variables using [dotenv](https://github.com/motdotla/dotenv) and [cross-env](https://github.com/kentcdodds/cross-env#readme)
- Git hooks with [husky](https://github.com/typicode/husky) and [lint-staged](https://github.com/okonet/lint-staged)
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
"prettier:fix": "prettier --write **/*.js"
},
"dependencies": {
"@hapi/joi": "^16.1.7",
"bcryptjs": "^2.4.3",
"cross-env": "^6.0.3",
"dotenv": "^8.2.0",
Expand Down
19 changes: 19 additions & 0 deletions src/middlewares/validate.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
const Joi = require('@hapi/joi');
const httpStatus = require('http-status');
const { pick } = require('lodash');
const AppError = require('../utils/AppError');

const validate = schema => (req, res, next) => {
const validSchema = pick(schema, ['params', 'query', 'body']);
const toValidate = pick(req, Object.keys(validSchema));
const { value, error } = Joi.compile(validSchema).validate(toValidate, { abortEarly: true });

if (error) {
const errorMessage = error.details.map(details => details.message).join(', ');
return next(new AppError(httpStatus.BAD_REQUEST, errorMessage));
}
Object.assign(req, value);
return next();
};

module.exports = validate;
4 changes: 3 additions & 1 deletion src/routes/v1/auth.route.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
const express = require('express');
const validate = require('../../middlewares/validate');
const authValidation = require('../../validations/auth.validation');
const authController = require('../../controllers/auth.controller');

const router = express.Router();

router.post('/register', authController.register);
router.post('/register', validate(authValidation.register), authController.register);

module.exports = router;
23 changes: 23 additions & 0 deletions src/validations/auth.validation.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
const Joi = require('@hapi/joi');

const register = {
body: Joi.object().keys({
email: Joi.string()
.required()
.email(),
password: Joi.string()
.required()
.min(8)
.custom((value, helpers) => {
if (!value.match(/\d/) || !value.match(/[a-zA-Z]/)) {
return helpers.message('Password must contain at least one letter and one number');
}
return value;
}),
name: Joi.string().required(),
}),
};

module.exports = {
register,
};
1 change: 1 addition & 0 deletions src/validations/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports.authValidation = require('./auth.validation');
38 changes: 38 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,44 @@
esutils "^2.0.2"
js-tokens "^4.0.0"

"@hapi/address@^2.1.2":
version "2.1.2"
resolved "https://registry.yarnpkg.com/@hapi/address/-/address-2.1.2.tgz#1c794cd6dbf2354d1eb1ef10e0303f573e1c7222"
integrity sha512-O4QDrx+JoGKZc6aN64L04vqa7e41tIiLU+OvKdcYaEMP97UttL0f9GIi9/0A4WAMx0uBd6SidDIhktZhgOcN8Q==

"@hapi/formula@^1.2.0":
version "1.2.0"
resolved "https://registry.yarnpkg.com/@hapi/formula/-/formula-1.2.0.tgz#994649c7fea1a90b91a0a1e6d983523f680e10cd"
integrity sha512-UFbtbGPjstz0eWHb+ga/GM3Z9EzqKXFWIbSOFURU0A/Gku0Bky4bCk9/h//K2Xr3IrCfjFNhMm4jyZ5dbCewGA==

"@hapi/hoek@^8.2.4", "@hapi/hoek@^8.3.0":
version "8.3.2"
resolved "https://registry.yarnpkg.com/@hapi/hoek/-/hoek-8.3.2.tgz#91e7188edebc5d876f0b91a860f555ff06f0782b"
integrity sha512-NP5SG4bzix+EtSMtcudp8TvI0lB46mXNo8uFpTDw6tqxGx4z5yx+giIunEFA0Z7oUO4DuWrOJV9xqR2tJVEdyA==

"@hapi/joi@^16.1.7":
version "16.1.7"
resolved "https://registry.yarnpkg.com/@hapi/joi/-/joi-16.1.7.tgz#360857223a87bb1f5f67691537964c1b4908ed93"
integrity sha512-anaIgnZhNooG3LJLrTFzgGALTiO97zRA1UkvQHm9KxxoSiIzCozB3RCNCpDnfhTJD72QlrHA8nwGmNgpFFCIeg==
dependencies:
"@hapi/address" "^2.1.2"
"@hapi/formula" "^1.2.0"
"@hapi/hoek" "^8.2.4"
"@hapi/pinpoint" "^1.0.2"
"@hapi/topo" "^3.1.3"

"@hapi/pinpoint@^1.0.2":
version "1.0.2"
resolved "https://registry.yarnpkg.com/@hapi/pinpoint/-/pinpoint-1.0.2.tgz#025b7a36dbbf4d35bf1acd071c26b20ef41e0d13"
integrity sha512-dtXC/WkZBfC5vxscazuiJ6iq4j9oNx1SHknmIr8hofarpKUZKmlUVYVIhNVzIEgK5Wrc4GMHL5lZtt1uS2flmQ==

"@hapi/topo@^3.1.3":
version "3.1.6"
resolved "https://registry.yarnpkg.com/@hapi/topo/-/topo-3.1.6.tgz#68d935fa3eae7fdd5ab0d7f953f3205d8b2bfc29"
integrity sha512-tAag0jEcjwH+P2quUfipd7liWCNX2F8NvYjQp2wtInsZxnMlypdw0FtAOLxtvvkO+GSRRbmNi8m/5y42PQJYCQ==
dependencies:
"@hapi/hoek" "^8.3.0"

"@nodelib/fs.scandir@2.1.3":
version "2.1.3"
resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz#3a582bdb53804c6ba6d146579c46e52130cf4a3b"
Expand Down

0 comments on commit 23f31a3

Please sign in to comment.