85 lines
2.3 KiB
JavaScript
85 lines
2.3 KiB
JavaScript
import Joi from 'joi';
|
|
|
|
// Validation schema for contact form
|
|
const contactSchema = Joi.object({
|
|
firstName: Joi.string()
|
|
.trim()
|
|
.min(1)
|
|
.max(50)
|
|
.pattern(/^[a-zA-Z\s\-']+$/)
|
|
.required()
|
|
.messages({
|
|
'string.empty': 'First name is required',
|
|
'string.min': 'First name must be at least 1 character long',
|
|
'string.max': 'First name cannot exceed 50 characters',
|
|
'string.pattern.base':
|
|
'First name can only contain letters, spaces, hyphens, and apostrophes',
|
|
}),
|
|
|
|
lastName: Joi.string()
|
|
.trim()
|
|
.min(1)
|
|
.max(50)
|
|
.pattern(/^[a-zA-Z\s\-']+$/)
|
|
.required()
|
|
.messages({
|
|
'string.empty': 'Last name is required',
|
|
'string.min': 'Last name must be at least 1 character long',
|
|
'string.max': 'Last name cannot exceed 50 characters',
|
|
'string.pattern.base':
|
|
'Last name can only contain letters, spaces, hyphens, and apostrophes',
|
|
}),
|
|
|
|
email: Joi.string()
|
|
.trim()
|
|
.email({ minDomainSegments: 2, tlds: { allow: true } })
|
|
.max(254)
|
|
.required()
|
|
.messages({
|
|
'string.email': 'Please provide a valid email address',
|
|
'string.empty': 'Email address is required',
|
|
'string.max': 'Email address is too long',
|
|
}),
|
|
|
|
subject: Joi.string().trim().max(200).allow('').messages({
|
|
'string.max': 'Subject cannot exceed 200 characters',
|
|
}),
|
|
|
|
message: Joi.string().trim().min(10).max(5000).required().messages({
|
|
'string.empty': 'Message is required',
|
|
'string.min': 'Message must be at least 10 characters long',
|
|
'string.max': 'Message cannot exceed 5000 characters',
|
|
}),
|
|
|
|
// Honeypot field (should be empty)
|
|
website: Joi.string().allow('').max(0).messages({
|
|
'string.max': 'Invalid form submission',
|
|
}),
|
|
});
|
|
|
|
// Validation middleware
|
|
export const validateContactForm = (req, res, next) => {
|
|
const { error, value } = contactSchema.validate(req.body, {
|
|
abortEarly: false,
|
|
stripUnknown: true,
|
|
convert: true,
|
|
});
|
|
|
|
if (error) {
|
|
const errors = error.details.map((detail) => ({
|
|
field: detail.path[0],
|
|
message: detail.message,
|
|
}));
|
|
|
|
return res.status(400).json({
|
|
success: false,
|
|
message: 'Validation failed',
|
|
errors,
|
|
});
|
|
}
|
|
|
|
// Replace req.body with validated and sanitized data
|
|
req.body = value;
|
|
next();
|
|
};
|