From aa0ece92dea4dc44b0a1924dfbc0b2f0b15568db Mon Sep 17 00:00:00 2001 From: Paras Yerunkar <135828004+ParasY1724@users.noreply.github.com> Date: Wed, 30 Oct 2024 16:34:00 +0530 Subject: [PATCH] Added Validations for Add-Post & Contact-Us (#112) --- server/routes/admin.js | 9 +-- server/routes/main.js | 7 +- server/validations/authValidator.js | 107 ++++++++++++++++++++++++++++ views/admin/add-post.ejs | 10 ++- 4 files changed, 125 insertions(+), 8 deletions(-) create mode 100644 server/validations/authValidator.js diff --git a/server/routes/admin.js b/server/routes/admin.js index a59d9f2..309a6bb 100644 --- a/server/routes/admin.js +++ b/server/routes/admin.js @@ -5,6 +5,7 @@ const User = require('../models/User'); const bcrypt = require('bcrypt'); const jwt = require('jsonwebtoken'); const passport = require('passport'); // Added passport import +const { validateRegistration, validatePost } = require('../validations/authValidator'); const adminLayout = '../views/layouts/admin'; const jwtSecret = process.env.JWT_SECRET; @@ -119,7 +120,7 @@ router.get('/add-post', authMiddleware, async (req, res) => { description: 'Simple Blog created with NodeJs, Express & MongoDb.', }; - res.render('admin/add-post', { locals, layout: adminLayout }); + res.render('admin/add-post', {locals, layout: adminLayout }); } catch (error) { console.log(error); } @@ -129,7 +130,7 @@ router.get('/add-post', authMiddleware, async (req, res) => { * POST /add-post * Admin Create New Post Route */ -router.post('/add-post', authMiddleware, async (req, res) => { +router.post('/add-post', authMiddleware,validatePost, async (req, res) => { try { const token = req.cookies.token const newPost = new Post({ @@ -170,7 +171,7 @@ router.get('/edit-post/:id', authMiddleware, async (req, res) => { * PUT /edit-post/:id * Admin Update Post Route */ -router.put('/edit-post/:id', authMiddleware, async (req, res) => { +router.put('/edit-post/:id', authMiddleware,validatePost, async (req, res) => { try { await Post.findByIdAndUpdate(req.params.id, { title: req.body.title, @@ -219,7 +220,7 @@ router.get('/register',restrictAuthRouteMiddleware, (req, res) => { -router.post('/register', async (req, res) => { +router.post('/register',validateRegistration, async (req, res) => { const { username, password } = req.body; // Simple validation diff --git a/server/routes/main.js b/server/routes/main.js index 7ac1b21..91930c3 100644 --- a/server/routes/main.js +++ b/server/routes/main.js @@ -3,6 +3,9 @@ const router = express.Router(); const Post = require('../models/Post'); const ContactMessage = require('../models/contactMessage'); const transporter = require('../config/nodemailerConfig'); +const { validateContact } = require('../validations/authValidator'); + + /** * GET / * HOME @@ -149,10 +152,10 @@ router.get('/contact', (req, res) => { }); }); -router.post('/send-message', async (req, res) => { +router.post('/send-message',validateContact ,async (req, res) => { const { name, email, message } = req.body; - try { + try {`` // Create a new contact message const newMessage = new ContactMessage({ name, email, message }); await newMessage.save(); diff --git a/server/validations/authValidator.js b/server/validations/authValidator.js new file mode 100644 index 0000000..ca7bbee --- /dev/null +++ b/server/validations/authValidator.js @@ -0,0 +1,107 @@ +const { body, validationResult } = require('express-validator'); + +// Validation middleware for registration +const validateRegistration = [ + body('username') + .trim() + .isLength({ min: 3 }) + .withMessage('Username must be at least 3 characters long') + .matches(/^[a-zA-Z0-9]+$/) + .withMessage('Username can only contain letters and numbers') + .escape(), + + body('password') + .isLength({ min: 8 }) + .withMessage('Password must be at least 8 characters long') + .matches(/\d/) + .withMessage('Password must contain at least one number') + .matches(/[!@#$%^&*]/) + .withMessage('Password must contain at least one special character') + .escape(), + + // Middleware to handle validation results + (req, res, next) => { + const errors = validationResult(req); + if (!errors.isEmpty()) { + req.flash('error', errors.array()[0].msg); + return res.redirect('/register'); + } + next(); + } +]; + +// Validation middleware for posts +const validatePost = [ + body('title') + .trim() + .notEmpty() + .withMessage('Title is required') + .isLength({ max: 200 }) + .withMessage('Title must not exceed 200 characters') + .escape(), + + body('body') + .trim() + .notEmpty() + .withMessage('Post content is required') + .escape(), + + body('author') + .trim() + .notEmpty() + .withMessage('Author name is required') + .escape(), + + (req, res, next) => { + const errors = validationResult(req); + if (!errors.isEmpty()) { + res.render('admin/add-post', {message: errors }); + } + next(); + } +]; + +// Validation middleware for contact form +const validateContact = [ + body('name') + .trim() + .notEmpty() + .withMessage('Name is required') + .isLength({ max: 100 }) + .withMessage('Name must not exceed 100 characters') + .escape(), + + body('email') + .trim() + .notEmpty() + .withMessage('Email is required') + .isEmail() + .withMessage('Please provide a valid email address') + .normalizeEmail(), + + body('message') + .trim() + .notEmpty() + .withMessage('Message is required') + .isLength({ max: 1000 }) + .withMessage('Message must not exceed 1000 characters') + .escape(), + + (req, res, next) => { + const errors = validationResult(req); + if (!errors.isEmpty()) { + return res.render('contact', { + currentRoute: '/contact', + message: errors.array()[0].msg, + user: req.cookies.token + }); + } + next(); + } +]; + +module.exports = { + validateRegistration, + validatePost, + validateContact +}; \ No newline at end of file diff --git a/views/admin/add-post.ejs b/views/admin/add-post.ejs index 153a817..5479839 100644 --- a/views/admin/add-post.ejs +++ b/views/admin/add-post.ejs @@ -184,13 +184,19 @@