fix: cron validation updated as reported in #206

This commit is contained in:
Raj Nandan Sharma
2025-01-21 22:02:39 +05:30
parent a2bd9883d1
commit f7cb4cd805
2 changed files with 120 additions and 6 deletions

View File

@@ -149,7 +149,121 @@ function IsValidNameServer(nameServer) {
const IsValidURL = function (url) {
return /^(http|https):\/\/[^ "]+$/.test(url);
};
function ValidateCronExpression(cronExp) {
// Check if expression is provided and is a string
if (!cronExp || typeof cronExp !== "string") {
return { isValid: false, message: "Cron expression must be a non-empty string" };
}
// Split the expression into its components
const fields = cronExp.trim().split(/\s+/);
// Standard cron should have 5 or 6 fields
// minute hour day-of-month month day-of-week [year]
if (fields.length < 5 || fields.length > 6) {
return {
isValid: false,
message: "Cron expression must have 5 or 6 fields"
};
}
// Define field constraints
const fieldConstraints = [
{ name: "minute", min: 0, max: 59 },
{ name: "hour", min: 0, max: 23 },
{ name: "day", min: 1, max: 31 },
{ name: "month", min: 1, max: 12 },
{ name: "weekday", min: 0, max: 6 },
{ name: "year", min: 1970, max: 2099 } // Optional field
];
// Valid characters in cron expressions
const validChars = /^[\d/*,\-]+$/;
// Validate each field
for (let i = 0; i < fields.length; i++) {
const field = fields[i];
const constraint = fieldConstraints[i];
// Check for valid characters
if (!validChars.test(field)) {
return {
isValid: false,
message: `Invalid characters in ${constraint.name} field`
};
}
// Handle special characters
if (field === "*") {
continue; // Asterisk is valid for all fields
}
// Handle lists (comma-separated values)
if (field.includes(",")) {
const values = field.split(",");
for (const value of values) {
if (!isValidRange(value, constraint.min, constraint.max)) {
return {
isValid: false,
message: `Invalid value in ${constraint.name} field: ${value}`
};
}
}
continue;
}
// Handle ranges (with hyphens)
if (field.includes("-")) {
const [start, end] = field.split("-").map(Number);
if (
start == null ||
end == null ||
start < constraint.min ||
end > constraint.max ||
start > end
) {
return {
isValid: false,
message: `Invalid range in ${constraint.name} field: ${field}`
};
}
continue;
}
// Handle steps (with forward slash)
if (field.includes("/")) {
const [range, step] = field.split("/");
if (range !== "*" && !isValidRange(range, constraint.min, constraint.max)) {
return {
isValid: false,
message: `Invalid range in ${constraint.name} field: ${range}`
};
}
if (!isValidRange(step, 1, constraint.max)) {
return {
isValid: false,
message: `Invalid step value in ${constraint.name} field: ${step}`
};
}
continue;
}
// Handle plain numbers
if (!isValidRange(field, constraint.min, constraint.max)) {
return {
isValid: false,
message: `Invalid value in ${constraint.name} field: ${field}`
};
}
}
return { isValid: true, message: "Valid cron expression" };
}
function isValidRange(value, min, max) {
const num = Number(value);
return !isNaN(num) && num >= min && num <= max;
}
export {
siteDataExtractFromDb,
storeSiteData,
@@ -157,5 +271,6 @@ export {
ValidateIpAddress,
IsValidHost,
IsValidNameServer,
IsValidURL
IsValidURL,
ValidateCronExpression
};

View File

@@ -11,6 +11,7 @@
import {
allRecordTypes,
ValidateIpAddress,
ValidateCronExpression,
IsValidHost,
IsValidNameServer
} from "$lib/clientTools.js";
@@ -130,13 +131,11 @@
//validating cron
const cron = newMonitor.cron;
const cronRegex =
/^((\*|([0-5]?\d)(-[0-5]?\d)?(\/[1-9]\d*)?|([0-5]?\d(,[0-5]?\d)*))\s+){4}(\*|([0-7](,[0-7])*|([0-7]-[0-7])))$/;
if (!cronRegex.test(cron)) {
invalidFormMessage = "Invalid Cron";
let cronValidation = ValidateCronExpression(cron);
if (cronValidation.isValid === false) {
invalidFormMessage = "Cron invalid: " + cronValidation.message;
return;
}
//if monitor type is API
if (newMonitor.monitor_type === "API") {
//validating url