CoolFace
Apppublic

sanket3280/code-execution

sourceHugging Faceupdated 10mo agoView on Hugging Face
0likes
validation.js198 linesDownload Raw Back to middleware
1/**2 * Validation Middleware3 * Provides reusable validation rules for common fields4 */5 6const { check, validationResult } = require('express-validator');7const { errorResponse } = require('../utils/response');8 9/**10 * Validation error handler middleware11 */12const handleValidationErrors = (req, res, next) => {13  const errors = validationResult(req);14  if (!errors.isEmpty()) {15    return errorResponse(res, 'Validation failed', 400, errors.array());16  }17  next();18};19 20/**21 * Common validation rules22 */23const validationRules = {24  // User validations25  username: check('username')26    .trim()27    .isLength({ min: 3, max: 30 })28    .withMessage('Username must be between 3 and 30 characters')29    .matches(/^[a-zA-Z0-9_-]+$/)30    .withMessage('Username can only contain letters, numbers, underscores, and hyphens'),31 32  email: check('email')33    .trim()34    .isEmail()35    .withMessage('Please provide a valid email')36    .normalizeEmail(),37 38  password: check('password')39    .isLength({ min: 8 })40    .withMessage('Password must be at least 8 characters')41    .matches(/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)/)42    .withMessage('Password must contain at least one uppercase letter, one lowercase letter, and one number'),43 44  // MongoDB ObjectId validation45  mongoId: (field = 'id') => check(field)46    .isMongoId()47    .withMessage(`Invalid ${field} format`),48 49  // Pagination validations50  page: check('page')51    .optional()52    .isInt({ min: 1 })53    .withMessage('Page must be a positive integer')54    .toInt(),55 56  limit: check('limit')57    .optional()58    .isInt({ min: 1, max: 100 })59    .withMessage('Limit must be between 1 and 100')60    .toInt(),61 62  // Problem validations63  difficulty: check('difficulty')64    .optional()65    .isIn(['easy', 'medium', 'hard'])66    .withMessage('Difficulty must be easy, medium, or hard'),67 68  category: check('category')69    .optional()70    .isString()71    .trim()72    .withMessage('Category must be a string'),73 74  // Challenge validations75  title: check('title')76    .trim()77    .isLength({ min: 3, max: 100 })78    .withMessage('Title must be between 3 and 100 characters'),79 80  description: check('description')81    .trim()82    .isLength({ min: 10, max: 5000 })83    .withMessage('Description must be between 10 and 5000 characters'),84 85  // Date validations86  startDate: check('startDate')87    .isISO8601()88    .withMessage('Start date must be a valid ISO 8601 date')89    .toDate(),90 91  endDate: check('endDate')92    .isISO8601()93    .withMessage('End date must be a valid ISO 8601 date')94    .toDate()95    .custom((value, { req }) => {96      if (req.body.startDate && new Date(value) <= new Date(req.body.startDate)) {97        throw new Error('End date must be after start date');98      }99      return true;100    }),101 102  // OTP validation103  otp: check('otp')104    .isLength({ min: 6, max: 6 })105    .withMessage('OTP must be 6 digits')106    .isNumeric()107    .withMessage('OTP must contain only numbers'),108};109 110/**111 * Validation rule sets for common operations112 */113const validationSets = {114  register: [115    validationRules.username,116    validationRules.email,117    validationRules.password,118    handleValidationErrors,119  ],120 121  login: [122    check('emailOrUsername')123      .trim()124      .notEmpty()125      .withMessage('Email or username is required'),126    check('password')127      .notEmpty()128      .withMessage('Password is required'),129    handleValidationErrors,130  ],131 132  updateProfile: [133    validationRules.username.optional(),134    check('avatar')135      .optional()136      .isURL()137      .withMessage('Avatar must be a valid URL'),138    handleValidationErrors,139  ],140 141  changePassword: [142    check('currentPassword')143      .notEmpty()144      .withMessage('Current password is required'),145    validationRules.password,146    handleValidationErrors,147  ],148 149  createProblem: [150    validationRules.title,151    validationRules.description,152    validationRules.difficulty,153    validationRules.category,154    handleValidationErrors,155  ],156 157  createChallenge: [158    validationRules.title,159    validationRules.description,160    validationRules.startDate,161    validationRules.endDate,162    check('problems')163      .isArray({ min: 1 })164      .withMessage('At least one problem is required'),165    handleValidationErrors,166  ],167 168  pagination: [169    validationRules.page,170    validationRules.limit,171    handleValidationErrors,172  ],173 174  forgotPassword: [175    validationRules.email,176    handleValidationErrors,177  ],178 179  verifyOTP: [180    validationRules.email,181    validationRules.otp,182    handleValidationErrors,183  ],184 185  resetPassword: [186    validationRules.email,187    validationRules.otp,188    validationRules.password,189    handleValidationErrors,190  ],191};192 193module.exports = {194  validationRules,195  validationSets,196  handleValidationErrors,197};198