Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
7216325
Merge pull request #1 from ajaybor0/dev
ajaybor0 Jan 5, 2024
22b468c
Merge pull request #2 from ajaybor0/dev
ajaybor0 Jan 6, 2024
3c53e8f
Merge pull request #3 from ajaybor0/dev
ajaybor0 Jan 8, 2024
11b0b45
Merge pull request #4 from ajaybor0/dev
ajaybor0 Jan 9, 2024
a04817a
Merge pull request #5 from ajaybor0/dev
ajaybor0 Jan 10, 2024
7c4d9ed
Merge pull request #7 from ajaybor0/dev
ajaybor0 Jan 10, 2024
ae8c1e9
Merge pull request #8 from ajaybor0/dev
ajaybor0 Jan 11, 2024
36c6b71
Merge pull request #9 from ajaybor0/dev
ajaybor0 Jan 12, 2024
5ef6c7d
Merge pull request #10 from ajaybor0/dev
ajaybor0 Jan 12, 2024
2e69097
Merge pull request #11 from ajaybor0/dev
ajaybor0 Jan 12, 2024
b95d745
Merge pull request #12 from ajaybor0/dev
ajaybor0 Jan 12, 2024
2050670
Merge pull request #13 from ajaybor0/dev
ajaybor0 Jan 13, 2024
6600ed7
Merge pull request #14 from ajaybor0/dev
ajaybor0 Jan 13, 2024
b52d0e2
Merge pull request #16 from ajaybor0/dev
ajaybor0 Jan 13, 2024
dcaf858
Merge pull request #17 from ajaybor0/dev
ajaybor0 Jan 14, 2024
2605dad
Merge pull request #18 from ajaybor0/dev
ajaybor0 Jan 14, 2024
97a289b
Merge pull request #19 from ajaybor0/dev
ajaybor0 Jan 14, 2024
b96c7ff
Merge pull request #20 from ajaybor0/dev
ajaybor0 Jan 14, 2024
363898b
Merge pull request #21 from ajaybor0/dev
ajaybor0 Jan 14, 2024
ff57f8c
Merge pull request #22 from ajaybor0/dev
ajaybor0 Jan 15, 2024
018fb75
Merge pull request #23 from ajaybor0/dev
ajaybor0 Jan 16, 2024
c3632ad
Merge pull request #24 from ajaybor0/dev
ajaybor0 Jan 16, 2024
5b70e0c
Merge pull request #25 from ajaybor0/dev
ajaybor0 Jan 17, 2024
88fcf6d
Merge pull request #26 from ajaybor0/dev
ajaybor0 Jan 18, 2024
81fae1c
Merge pull request #27 from ajaybor0/dev
ajaybor0 Jan 18, 2024
76f8969
Merge pull request #28 from ajaybor0/dev
ajaybor0 Jan 18, 2024
8ef0dab
Merge pull request #29 from ajaybor0/dev
ajaybor0 Jan 18, 2024
22fda9f
Merge pull request #30 from ajaybor0/dev
ajaybor0 Jan 18, 2024
499657e
Merge pull request #31 from ajaybor0/dev
ajaybor0 Jan 19, 2024
feb7064
Merge pull request #34 from ajaybor0/dev
ajaybor0 Jan 19, 2024
d4af463
Merge pull request #35 from ajaybor0/dev
ajaybor0 Jan 19, 2024
35300e5
Merge pull request #36 from ajaybor0/dev
ajaybor0 Jan 19, 2024
e57ecbb
Add express-validator package
Tharuneshwarv Jan 20, 2024
43fd9f3
add validation for user routes
Tharuneshwarv Jan 20, 2024
f9a84c1
Merge pull request #38 from ajaybor0/dev
ajaybor0 Jan 21, 2024
bd0bb39
Add validation for userRoutes
Tharuneshwarv Jan 21, 2024
88b359a
Add validation for upload routes
Tharuneshwarv Jan 21, 2024
254493e
Add validation for productRoutes
Tharuneshwarv Jan 21, 2024
d19010d
Add validation for payment routes
Tharuneshwarv Jan 21, 2024
281defb
Add validation for order routes
Tharuneshwarv Jan 21, 2024
ce2bbe1
Merge branch 'main' of https://github.com/ajaybor0/MERN-eCommerce int…
Tharuneshwarv Jan 21, 2024
8d3a261
Add validation for password reset
Tharuneshwarv Jan 21, 2024
c973414
Add validation for payment
Tharuneshwarv Jan 22, 2024
6c2e240
password length validation
Tharuneshwarv Jan 22, 2024
5daa615
Add validation for file upload
Tharuneshwarv Jan 22, 2024
d9e9fc0
Merge pull request #39 from Tharuneshwarv/add_validation
ajaybor0 Jan 22, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions backend/middleware/validator.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { validationResult } from "express-validator"

const validator = (req, res, next) => {
const result = validationResult(req);
if(result.isEmpty())
return next();
res.status(400).json({ errors: result.array() });
}

export default validator;
52 changes: 47 additions & 5 deletions backend/routes/orderRoutes.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import express from 'express';
const router = express.Router();
import { protect, admin } from '../middleware/authMiddleware.js';
import {
addOrderItems,
Expand All @@ -9,12 +8,55 @@ import {
updateOrderToDeliver,
getOrders
} from '../controllers/orderController.js';
import validateRequest from '../middleware/validator.js';
import { param, check } from 'express-validator';

const router = express.Router();

const validator = {
getOrderById: [
param('id').notEmpty().withMessage('Id is required').isMongoId().withMessage('Invalid Id Format')
],
updateOrderToPaid: [
param('id').notEmpty().withMessage('Id is required').isMongoId().withMessage('Invalid Id Format')
],
updateOrderToDeliver: [
param('id').notEmpty().withMessage('Id is required').isMongoId().withMessage('Invalid Id Format')
],
addOrderItems: [
check('cartItems').notEmpty().withMessage('Cart items are required'),
check('shippingAddress').notEmpty().withMessage('Shipping address is required'),
check('paymentMethod').notEmpty().withMessage('Payment method is required'),
check('itemsPrice')
.notEmpty()
.withMessage('Items price is required')
.isNumeric()
.withMessage('Items price must be a number'),
check('taxPrice')
.notEmpty()
.withMessage('Tax price is required')
.isNumeric()
.withMessage('Tax price must be a number'),
check('shippingPrice')
.notEmpty()
.withMessage('Shipping price is required')
.isNumeric()
.withMessage('Shipping price must be a number'),
check('totalPrice')
.notEmpty()
.withMessage('Total price is required')
.isNumeric()
.withMessage('Total price must be a number')
]
}

router.route('/').post(protect, addOrderItems).get(protect, admin, getOrders);
router.route('/')
.post(validator.addOrderItems, validateRequest, protect, addOrderItems)
.get(protect, admin, getOrders);

router.get('/my-orders', protect, getMyOrders);
router.get('/:id', protect, getOrderById);
router.put('/:id/pay', protect, updateOrderToPaid);
router.put('/:id/deliver', protect, admin, updateOrderToDeliver);
router.get('/:id', validator.getOrderById, validateRequest, protect, getOrderById);
router.put('/:id/pay', validator.updateOrderToPaid, validateRequest, protect, updateOrderToPaid);
router.put('/:id/deliver', validator.updateOrderToDeliver, validateRequest, protect, admin, updateOrderToDeliver);

export default router;
31 changes: 29 additions & 2 deletions backend/routes/paymentRoutes.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,40 @@ import express from 'express';

import { protect } from '../middleware/authMiddleware.js';
import { config, order, validate } from '../controllers/paymentController.js';
import validateRequest from '../middleware/validator.js';
import {body, check} from 'express-validator';

const router = express.Router();

const validator = {
order: [
body().custom(body => {
if (Object.keys(body).length === 0)
throw new Error('Request Body is empty')
return true;
})
],
validate: [
body('razorpay_order_id')
.notEmpty()
.withMessage('Razorpay order ID is required')
.trim(),
body('razorpay_payment_id')
.notEmpty()
.withMessage('Razorpay payment ID is required')
.trim(),
body('razorpay_signature')
.notEmpty()
.withMessage('Razorpay signature is required')
.trim()
.escape()
]
}

router.get('/razorpay/config', config);

router.post('/razorpay/order', protect, order);
router.post('/razorpay/order', validator.order, validateRequest, protect, order);

router.post('/razorpay/order/validate', protect, validate);
router.post('/razorpay/order/validate', validator.validate, validateRequest, protect, validate);

export default router;
84 changes: 78 additions & 6 deletions backend/routes/productRoutes.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import express from 'express';
import express, { query } from 'express';
import {
getProducts,
getProduct,
Expand All @@ -9,16 +9,88 @@ import {
getTopProducts
} from '../controllers/productController.js';
import { protect, admin } from '../middleware/authMiddleware.js';
import validateRequest from '../middleware/validator.js';
import {body, check, param} from 'express-validator';

const router = express.Router();

router.route('/').post(protect, admin, createProduct).get(getProducts);
const validator = {
getProducts: [
check('limit').optional().isNumeric().withMessage('Limit parameter must be a number').custom(value => {
if(value < 0) throw new Error('Value should not be less than Zero');
return true;
}),
check('skip').optional().isNumeric().withMessage('skip parameter must be a number').custom(value => {
if(value < 0) throw new Error('Value should not be less than Zero');
return true;
}),
check('search').optional().trim().escape()
],
createProduct: [
check('name').trim().notEmpty().withMessage('Name is required').escape(),
check('image').notEmpty().withMessage('Image is required'),
check('description')
.trim()
.notEmpty()
.withMessage('Description is required')
.escape(),
check('brand').trim().notEmpty().withMessage('Brand is required').escape(),
check('category').trim().notEmpty().withMessage('Category is required').escape(),
check('price')
.notEmpty()
.withMessage('Price is required')
.isNumeric()
.withMessage('Price must be a number'),
check('countInStock')
.notEmpty()
.withMessage('Count in stock is required')
.isNumeric()
.withMessage('Count in stock must be a number')
],
createProductReview: [
param('id').notEmpty().withMessage('Id is required').isMongoId().withMessage('Invalid Id Format'),
body('rating').notEmpty().withMessage('Rating is Empty').bail().isNumeric().withMessage('Ratings must be number'),
body('comment').trim().escape()
],
getProduct: [
param('id').notEmpty().withMessage('Id is required').isMongoId().withMessage('Invalid Id Format')
],
deleteProduct: [
param('id').notEmpty().withMessage('Id is required').isMongoId().withMessage('Invalid Id Format')
],
updateProduct: [
check('name').trim().notEmpty().withMessage('Name is required').escape(),
check('image').notEmpty().withMessage('Image is required'),
check('description')
.trim()
.notEmpty()
.withMessage('Description is required')
.escape(),
check('brand').trim().notEmpty().withMessage('Brand is required').escape(),
check('category').trim().notEmpty().withMessage('Category is required').escape(),
check('price')
.notEmpty()
.withMessage('Price is required')
.isNumeric()
.withMessage('Price must be a number'),
check('countInStock')
.notEmpty()
.withMessage('Count in stock is required')
.isNumeric()
.withMessage('Count in stock must be a number'),
param('id').notEmpty().withMessage('Id is required').isMongoId().withMessage('Invalid Id Format')
]
}

router.route('/')
.post(validator.createProduct, validateRequest, protect, admin, createProduct)
.get(validator.getProducts, validateRequest, getProducts);
router.get('/top', getTopProducts);
router.post('/reviews/:id', protect, createProductReview);
router.post('/reviews/:id', validator.createProductReview, validateRequest, protect, createProductReview);
router
.route('/:id')
.get(getProduct)
.put(protect, admin, updateProduct)
.delete(protect, admin, deleteProduct);
.get(validator.getProduct, validateRequest, getProduct)
.put(validator.updateProduct, validateRequest, protect, admin, updateProduct)
.delete(validator.deleteProduct, validateRequest, protect, admin, deleteProduct);

export default router;
11 changes: 7 additions & 4 deletions backend/routes/uploadRoutes.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import express from 'express';
import express from 'express';import { body, check } from 'express-validator';
import multer from 'multer';
import validateRequest from '../middleware/validator.js';

const router = express.Router();

Expand All @@ -13,23 +14,25 @@ const storage = multer.diskStorage({
});

const fileFilter = (req, file, cb) => {
if (
if (
file.mimetype === 'image/png' ||
file.mimetype === 'image/jpg' ||
file.mimetype === 'image/jpeg'
) {
// To accept the file pass `true`, like so:
cb(null, true);
} else {
// To reject this file pass `false`, like so:
// To reject this file pass `false`, like so:
cb('Images only!');
}
};

const upload = multer({ storage, fileFilter }).single('image');

router.post('/', upload, (req, res) => {
console.log(req.file);
if (!req.file)
throw res.status(400).json({error: 'No file uploaded'});

res.send({
message: 'Image uploaded',
imageUrl: `/${req.file.path}`
Expand Down
54 changes: 45 additions & 9 deletions backend/routes/userRoutes.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import express from 'express';
const router = express.Router();
import {
loginUser,
registerUser,
Expand All @@ -15,24 +14,61 @@ import {
resetPassword
} from '../controllers/userController.js';
import { protect, admin } from '../middleware/authMiddleware.js';
import validateRequest from '../middleware/validator.js';
import {body, param} from 'express-validator';

const router = express.Router();
const validator = {
checkLogin: [
body('email').trim().notEmpty().withMessage('Email is Required').bail().isEmail().withMessage("Please enter a valid email address"),
body('password').trim().isString().notEmpty().withMessage('Password is Empty')
],
checkNewUser: [
body('email').trim().notEmpty().withMessage('Email is Required').bail().isEmail().withMessage("Please enter a valid email address"),
body('password').trim().isString().notEmpty().withMessage('Password is Empty').bail()
.isLength({ min: 6 }).withMessage('Password must be at least 6 characters'),
body('name').trim().notEmpty().withMessage('Name is Required').escape()
],
checkGetUserById: [
param('id').exists().withMessage('Id is required').isMongoId().withMessage('Invalid Id')
],
checkUpdateUser: [
body('email').trim().notEmpty().withMessage('Email is Required').bail().isEmail().withMessage("Please enter a valid email address"),
body('name').trim().notEmpty().withMessage('Name is Required').escape(),
body('isAdmin').isBoolean().withMessage('isAdmin value should be true/false'),
param('id').exists().withMessage('Id is required').isMongoId().withMessage('Invalid Id')
],
resetPasswordRequest: [
body('email').trim().notEmpty().withMessage('Email is Required').bail().isEmail().withMessage("Please enter a valid email address")
],
resetPassword: [
body('password').trim().notEmpty().withMessage('Password is Required').escape().bail()
.isLength({ min: 6 }).withMessage('Password must be at least 6 characters'),
param('id').exists().withMessage('Id is required').isMongoId().withMessage('Invalid Id'),
param('token').trim().notEmpty().withMessage('Token is Required')
]
}

router.route('/')
.post(validator.checkNewUser, validateRequest, registerUser)
.get(protect, admin, getUsers);

router.route('/').post(registerUser).get(protect, admin, getUsers);
router.route('/admins').get(protect, admin, admins);

router.post('/reset-password/request', resetPasswordRequest);
router.post('/reset-password/reset/:id/:token', resetPassword);
router.post('/login', loginUser);
router.post('/reset-password/request', validator.resetPasswordRequest, validateRequest, resetPasswordRequest);
router.post('/reset-password/reset/:id/:token', validator.resetPassword, validateRequest, resetPassword);
router.post('/login', validator.checkLogin, validateRequest, loginUser);
router.post('/logout', protect, logoutUser);

router
.route('/profile')
.get(protect, getUserProfile)
.put(protect, updateUserProfile);
.put(validator.checkNewUser, validateRequest, protect, updateUserProfile);

router
.route('/:id')
.get(protect, admin, getUserById)
.put(protect, admin, updateUser)
.delete(protect, admin, deleteUser);
.get(validator.checkGetUserById, validateRequest, protect, admin, getUserById)
.put(validator.checkUpdateUser, validateRequest, protect, admin, updateUser)
.delete(validator.checkGetUserById, validateRequest, protect, admin, deleteUser);

export default router;
21 changes: 21 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
"cookie-parser": "^1.4.6",
"cors": "^2.8.5",
"express": "^4.18.2",
"express-validator": "^7.0.1",
"jsonwebtoken": "^9.0.2",
"mongoose": "^8.0.3",
"multer": "^1.4.5-lts.1",
Expand Down