
- Updated `.env` and added `.env.test` for environment variables. - Introduced API documentation in `API_DOCUMENTATION.md`. - Added authentication setup guide in `AUTHENTICATION_SETUP.md`. - Implemented user authentication with JWT and email verification. - Created new routes for user management and form submissions. - Added middleware for API key authentication and error handling. - Set up Redis for rate limiting and notifications. - Removed obsolete files and configurations related to the previous Rust implementation.
116 lines
2.9 KiB
JavaScript
116 lines
2.9 KiB
JavaScript
const { body, param, query, validationResult } = require("express-validator");
|
|
|
|
// Validation error handler
|
|
const handleValidationErrors = (req, res, next) => {
|
|
const errors = validationResult(req);
|
|
if (!errors.isEmpty()) {
|
|
return res.status(400).json({
|
|
success: false,
|
|
message: "Validation failed",
|
|
errors: errors.array().map((error) => ({
|
|
field: error.path,
|
|
message: error.msg,
|
|
value: error.value,
|
|
})),
|
|
});
|
|
}
|
|
next();
|
|
};
|
|
|
|
// Password validation
|
|
const passwordValidation = body("password")
|
|
.isLength({ min: 8 })
|
|
.withMessage("Password must be at least 8 characters long")
|
|
.matches(/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]/)
|
|
.withMessage(
|
|
"Password must contain at least one lowercase letter, one uppercase letter, one number, and one special character"
|
|
);
|
|
|
|
// Email validation
|
|
const emailValidation = body("email")
|
|
.isEmail()
|
|
.withMessage("Please provide a valid email address")
|
|
.normalizeEmail()
|
|
.isLength({ max: 255 })
|
|
.withMessage("Email address is too long");
|
|
|
|
// Registration validation
|
|
const validateRegistration = [
|
|
emailValidation,
|
|
passwordValidation,
|
|
body("first_name")
|
|
.optional()
|
|
.trim()
|
|
.isLength({ min: 1, max: 100 })
|
|
.withMessage("First name must be between 1 and 100 characters"),
|
|
body("last_name")
|
|
.optional()
|
|
.trim()
|
|
.isLength({ min: 1, max: 100 })
|
|
.withMessage("Last name must be between 1 and 100 characters"),
|
|
handleValidationErrors,
|
|
];
|
|
|
|
// Login validation
|
|
const validateLogin = [
|
|
body("email")
|
|
.isEmail()
|
|
.withMessage("Please provide a valid email address")
|
|
.normalizeEmail(),
|
|
body("password").notEmpty().withMessage("Password is required"),
|
|
handleValidationErrors,
|
|
];
|
|
|
|
// Forgot password validation
|
|
const validateForgotPassword = [emailValidation, handleValidationErrors];
|
|
|
|
// Reset password validation
|
|
const validateResetPassword = [
|
|
body("token")
|
|
.notEmpty()
|
|
.withMessage("Reset token is required")
|
|
.isLength({ min: 64, max: 64 })
|
|
.withMessage("Invalid reset token format"),
|
|
passwordValidation,
|
|
body("confirmPassword").custom((value, { req }) => {
|
|
if (value !== req.body.password) {
|
|
throw new Error("Password confirmation does not match password");
|
|
}
|
|
return true;
|
|
}),
|
|
handleValidationErrors,
|
|
];
|
|
|
|
// Profile update validation
|
|
const validateProfileUpdate = [
|
|
body("first_name")
|
|
.optional()
|
|
.trim()
|
|
.isLength({ min: 1, max: 100 })
|
|
.withMessage("First name must be between 1 and 100 characters"),
|
|
body("last_name")
|
|
.optional()
|
|
.trim()
|
|
.isLength({ min: 1, max: 100 })
|
|
.withMessage("Last name must be between 1 and 100 characters"),
|
|
body("email")
|
|
.optional()
|
|
.isEmail()
|
|
.withMessage("Please provide a valid email address")
|
|
.normalizeEmail()
|
|
.isLength({ max: 255 })
|
|
.withMessage("Email address is too long"),
|
|
handleValidationErrors,
|
|
];
|
|
|
|
module.exports = {
|
|
validateRegistration,
|
|
validateLogin,
|
|
validateForgotPassword,
|
|
validateResetPassword,
|
|
validateProfileUpdate,
|
|
handleValidationErrors,
|
|
passwordValidation,
|
|
emailValidation,
|
|
};
|