feat(validation): replace fieldValidation with express-validator on products and tags
Add products.validators.js and tags.validators.js following the same pattern as articles/users. Wire createProductRules, updateProductRules, and createTagRules into their respective routes via the validate middleware. Remove the local fieldValidation helper from both controllers and fix missing return statements on next() calls in products.controller.js.
This commit is contained in:
@@ -134,14 +134,10 @@ module.exports.getProduct = asyncHandler(async (req, res, next) => {
|
|||||||
module.exports.createProduct = asyncHandler(async (req, res, next) => {
|
module.exports.createProduct = asyncHandler(async (req, res, next) => {
|
||||||
const { loggedUser } = req;
|
const { loggedUser } = req;
|
||||||
|
|
||||||
fieldValidation(req.body.product.title, next);
|
|
||||||
fieldValidation(req.body.product.description, next);
|
|
||||||
fieldValidation(req.body.product.body, next);
|
|
||||||
|
|
||||||
const { title, description, body, tagList } = req.body.product;
|
const { title, description, body, tagList } = req.body.product;
|
||||||
const slugInDB = await Product.findOne({ where: { slug: slug(`${title}`) } });
|
const slugInDB = await Product.findOne({ where: { slug: slug(`${title}`) } });
|
||||||
if (slugInDB) {
|
if (slugInDB) {
|
||||||
next(new ErrorResponse("Title already exists", 400));
|
return next(new ErrorResponse("Title already exists", 400));
|
||||||
}
|
}
|
||||||
|
|
||||||
const product = await Product.create({
|
const product = await Product.create({
|
||||||
@@ -181,7 +177,7 @@ module.exports.deleteProduct = asyncHandler(async (req, res, next) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (!product) {
|
if (!product) {
|
||||||
next(new ErrorResponse("Product not found", 404));
|
return next(new ErrorResponse("Product not found", 404));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (product.authorId !== loggedUser.id) {
|
if (product.authorId !== loggedUser.id) {
|
||||||
@@ -203,7 +199,7 @@ module.exports.updateProduct = asyncHandler(async (req, res, next) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (!product) {
|
if (!product) {
|
||||||
next(new ErrorResponse("Product not found", 404));
|
return next(new ErrorResponse("Product not found", 404));
|
||||||
}
|
}
|
||||||
if (product.authorId !== loggedUser.id) {
|
if (product.authorId !== loggedUser.id) {
|
||||||
return next(new ErrorResponse("Unauthorized", 401, "Authentication required."));
|
return next(new ErrorResponse("Unauthorized", 401, "Authentication required."));
|
||||||
@@ -277,8 +273,3 @@ module.exports.deleteFavoriteProduct = asyncHandler(async (req, res, next) => {
|
|||||||
res.status(200).json({ product });
|
res.status(200).json({ product });
|
||||||
});
|
});
|
||||||
|
|
||||||
const fieldValidation = (field, next) => {
|
|
||||||
if (!field) {
|
|
||||||
return next(new ErrorResponse(`Missing fields`, 400));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|||||||
@@ -4,8 +4,6 @@ const ErrorResponse = require("../utils/errorResponse");
|
|||||||
|
|
||||||
module.exports.createTag = asyncHandler(async (req, res, next) => {
|
module.exports.createTag = asyncHandler(async (req, res, next) => {
|
||||||
try {
|
try {
|
||||||
|
|
||||||
fieldValidation(req.body.tag.name, next);
|
|
||||||
const { name } = req.body.tag;
|
const { name } = req.body.tag;
|
||||||
const tagInDB = await TagService.tagIsInDB(name);
|
const tagInDB = await TagService.tagIsInDB(name);
|
||||||
if (tagInDB) {
|
if (tagInDB) {
|
||||||
@@ -60,8 +58,3 @@ module.exports.getAllTags = asyncHandler(async (req, res, next) => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const fieldValidation = (field, next) => {
|
|
||||||
if (!field) {
|
|
||||||
return next(new ErrorResponse(`Missing fields`, 400));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|||||||
@@ -0,0 +1,27 @@
|
|||||||
|
const { body } = require('express-validator');
|
||||||
|
|
||||||
|
const createProductRules = [
|
||||||
|
body('product.title')
|
||||||
|
.notEmpty().withMessage("can't be blank")
|
||||||
|
.isLength({ max: 255 }).withMessage('must be at most 255 characters')
|
||||||
|
.trim(),
|
||||||
|
body('product.description')
|
||||||
|
.notEmpty().withMessage("can't be blank")
|
||||||
|
.isLength({ max: 1000 }).withMessage('must be at most 1000 characters')
|
||||||
|
.trim(),
|
||||||
|
body('product.body')
|
||||||
|
.notEmpty().withMessage("can't be blank"),
|
||||||
|
];
|
||||||
|
|
||||||
|
const updateProductRules = [
|
||||||
|
body('product.title')
|
||||||
|
.optional()
|
||||||
|
.isLength({ max: 255 }).withMessage('must be at most 255 characters')
|
||||||
|
.trim(),
|
||||||
|
body('product.description')
|
||||||
|
.optional()
|
||||||
|
.isLength({ max: 1000 }).withMessage('must be at most 1000 characters')
|
||||||
|
.trim(),
|
||||||
|
];
|
||||||
|
|
||||||
|
module.exports = { createProductRules, updateProductRules };
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
const { body } = require('express-validator');
|
||||||
|
|
||||||
|
const createTagRules = [
|
||||||
|
body('tag.name')
|
||||||
|
.notEmpty().withMessage("can't be blank")
|
||||||
|
.isLength({ max: 50 }).withMessage('must be at most 50 characters')
|
||||||
|
.trim(),
|
||||||
|
];
|
||||||
|
|
||||||
|
module.exports = { createTagRules };
|
||||||
@@ -1,10 +1,12 @@
|
|||||||
const express = require('express');
|
const express = require('express');
|
||||||
const { createTag, deleteTag, getAllTags } = require('../../../controllers/tags.controller');
|
const { createTag, deleteTag, getAllTags } = require('../../../controllers/tags.controller');
|
||||||
const auth = require('../../../middlewares/auth');
|
const auth = require('../../../middlewares/auth');
|
||||||
|
const validate = require('../../../middlewares/validate');
|
||||||
|
const { createTagRules } = require('../../../middlewares/validators/tags.validators');
|
||||||
|
|
||||||
const tagRouter = express.Router();
|
const tagRouter = express.Router();
|
||||||
|
|
||||||
tagRouter.post('/', auth.required, createTag);
|
tagRouter.post('/', auth.required, createTagRules, validate, createTag);
|
||||||
tagRouter.get('/', auth.optional, getAllTags);
|
tagRouter.get('/', auth.optional, getAllTags);
|
||||||
tagRouter.delete('/:name', auth.required, deleteTag);
|
tagRouter.delete('/:name', auth.required, deleteTag);
|
||||||
|
|
||||||
|
|||||||
@@ -9,13 +9,15 @@ const {
|
|||||||
updateProduct,
|
updateProduct,
|
||||||
} = require('../../../controllers/products.controller');
|
} = require('../../../controllers/products.controller');
|
||||||
const auth = require('../../../middlewares/auth');
|
const auth = require('../../../middlewares/auth');
|
||||||
|
const validate = require('../../../middlewares/validate');
|
||||||
|
const { createProductRules, updateProductRules } = require('../../../middlewares/validators/products.validators');
|
||||||
|
|
||||||
const productRouter = express.Router();
|
const productRouter = express.Router();
|
||||||
|
|
||||||
productRouter.get('/', auth.optional, getProducts);
|
productRouter.get('/', auth.optional, getProducts);
|
||||||
productRouter.post('/', auth.required, createProduct);
|
productRouter.post('/', auth.required, createProductRules, validate, createProduct);
|
||||||
productRouter.get('/:slug', auth.optional, getProduct);
|
productRouter.get('/:slug', auth.optional, getProduct);
|
||||||
productRouter.put('/:slug', auth.required, updateProduct);
|
productRouter.put('/:slug', auth.required, updateProductRules, validate, updateProduct);
|
||||||
productRouter.delete('/:slug', auth.required, deleteProduct);
|
productRouter.delete('/:slug', auth.required, deleteProduct);
|
||||||
productRouter.post('/:slug/favorite', auth.required, addFavoriteProduct);
|
productRouter.post('/:slug/favorite', auth.required, addFavoriteProduct);
|
||||||
productRouter.delete('/:slug/favorite', auth.required, deleteFavoriteProduct);
|
productRouter.delete('/:slug/favorite', auth.required, deleteFavoriteProduct);
|
||||||
|
|||||||
Reference in New Issue
Block a user