webupdate
This commit is contained in:
@@ -77,6 +77,7 @@ class CacheManager {
|
||||
for (const key of this.cache.keys()) {
|
||||
if (key.includes(pattern)) {
|
||||
this.cache.delete(key);
|
||||
this._removeLRUNode(key);
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -104,10 +104,10 @@ const notFoundHandler = (req, res) => {
|
||||
return;
|
||||
}
|
||||
|
||||
// SECURITY: Don't expose path in response to prevent information disclosure
|
||||
res.status(404).json({
|
||||
success: false,
|
||||
message: "Route not found",
|
||||
path: req.path,
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ const validators = {
|
||||
body("email")
|
||||
.isEmail()
|
||||
.withMessage("Valid email is required")
|
||||
.normalizeEmail()
|
||||
.normalizeEmail({ gmail_remove_dots: false })
|
||||
.trim(),
|
||||
body("password").notEmpty().withMessage("Password is required").trim(),
|
||||
],
|
||||
@@ -39,20 +39,20 @@ const validators = {
|
||||
body("email")
|
||||
.isEmail()
|
||||
.withMessage("Valid email is required")
|
||||
.normalizeEmail()
|
||||
.normalizeEmail({ gmail_remove_dots: false })
|
||||
.trim(),
|
||||
body("username")
|
||||
.isLength({ min: 3, max: 50 })
|
||||
.matches(/^[a-zA-Z0-9_-]+$/)
|
||||
.withMessage(
|
||||
"Username must be 3-50 characters and contain only letters, numbers, hyphens, and underscores"
|
||||
"Username must be 3-50 characters and contain only letters, numbers, hyphens, and underscores",
|
||||
)
|
||||
.trim(),
|
||||
body("password")
|
||||
.isLength({ min: 12 })
|
||||
.matches(/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&#])/)
|
||||
.withMessage(
|
||||
"Password must be at least 12 characters with uppercase, lowercase, number, and special character"
|
||||
"Password must be at least 12 characters with uppercase, lowercase, number, and special character",
|
||||
),
|
||||
body("role_id").notEmpty().withMessage("Role is required").trim(),
|
||||
],
|
||||
@@ -65,7 +65,7 @@ const validators = {
|
||||
.optional()
|
||||
.isEmail()
|
||||
.withMessage("Valid email is required")
|
||||
.normalizeEmail()
|
||||
.normalizeEmail({ gmail_remove_dots: false })
|
||||
.trim(),
|
||||
body("username")
|
||||
.optional()
|
||||
@@ -252,25 +252,66 @@ const validators = {
|
||||
.isLength({ min: 1, max: 255 })
|
||||
.matches(/^[a-z0-9-]+$/)
|
||||
.withMessage(
|
||||
"Slug must contain only lowercase letters, numbers, and hyphens"
|
||||
"Slug must contain only lowercase letters, numbers, and hyphens",
|
||||
)
|
||||
.trim(),
|
||||
body("content").notEmpty().withMessage("Content is required").trim(),
|
||||
],
|
||||
|
||||
// Generic ID validator
|
||||
idParam: [param("id").notEmpty().withMessage("ID is required").trim()],
|
||||
// Generic ID validator - SECURITY: Validate ID format to prevent injection
|
||||
idParam: [
|
||||
param("id")
|
||||
.notEmpty()
|
||||
.withMessage("ID is required")
|
||||
.trim()
|
||||
.matches(/^[a-zA-Z0-9_-]+$/)
|
||||
.withMessage("Invalid ID format")
|
||||
.isLength({ max: 100 })
|
||||
.withMessage("ID too long"),
|
||||
],
|
||||
|
||||
// Product ID validator
|
||||
productIdParam: [
|
||||
param("id")
|
||||
.notEmpty()
|
||||
.withMessage("Product ID is required")
|
||||
.trim()
|
||||
.matches(/^prod-[a-zA-Z0-9-]+$/)
|
||||
.withMessage("Invalid product ID format"),
|
||||
],
|
||||
|
||||
// User ID validator
|
||||
userIdParam: [
|
||||
param("id")
|
||||
.notEmpty()
|
||||
.withMessage("User ID is required")
|
||||
.trim()
|
||||
.matches(/^user-[a-f0-9-]+$/)
|
||||
.withMessage("Invalid user ID format"),
|
||||
],
|
||||
|
||||
// Pagination validators
|
||||
pagination: [
|
||||
query("page")
|
||||
.optional()
|
||||
.isInt({ min: 1 })
|
||||
.withMessage("Page must be a positive integer"),
|
||||
.withMessage("Page must be a positive integer")
|
||||
.toInt(),
|
||||
query("limit")
|
||||
.optional()
|
||||
.isInt({ min: 1, max: 100 })
|
||||
.withMessage("Limit must be between 1 and 100"),
|
||||
.withMessage("Limit must be between 1 and 100")
|
||||
.toInt(),
|
||||
],
|
||||
|
||||
// SECURITY: Sanitize search queries
|
||||
searchQuery: [
|
||||
query("q")
|
||||
.optional()
|
||||
.trim()
|
||||
.isLength({ max: 200 })
|
||||
.withMessage("Search query too long")
|
||||
.escape(),
|
||||
],
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user