diff --git a/index.js b/index.js index a5582c4..296ee41 100644 --- a/index.js +++ b/index.js @@ -96,6 +96,7 @@ require(path.join(process.cwd(), "..", "server", "dist", "database.js")); allWorkFlowInfo[workflow.id]["subFlow"] = subFlowInfo; + } console.log("allWorkFlowInfo", JSON.stringify(allWorkFlowInfo, null, 2)); diff --git a/util.js b/util.js index 5412c2c..872826b 100644 --- a/util.js +++ b/util.js @@ -1,7 +1,7 @@ -const sleep = (ms)=>{ - return new Promise(resolve=>{ - console.log(`${(ms/1000).toFixed(2)}s SHOULD WAIT`); - setTimeout(resolve,ms); +const sleep = (ms) => { + return new Promise(resolve => { + console.log(`${(ms / 1000).toFixed(2)}s SHOULD WAIT`); + setTimeout(resolve, ms); }) } function convertStringToJson(string) { @@ -13,6 +13,43 @@ function convertStringToJson(string) { } } +const checkCondition = ({ data, condition }, conditionArray = new Set()) => { + let ands = true; + for (const key in condition) { + const conditionValue = condition[key]; + if (key == 'or') { + let ors = false; + for (const cond of conditionValue) { + // const orConditionChecking = checkCondition({ data, condition: cond }, conditionArray); + // ors = ors || orConditionChecking.ok; + ors = ors || checkCondition({ data, condition: cond }); + // conditionArray = new Set([...conditionArray, ...orConditionChecking.conditionArray]) + if (ors) break; + } + ands = ands && ors; + } else { + if (data[key] == 'true') data[key] = true; + if (data[key] == 'false') data[key] = false; + switch (key) { + case [Op.gt]: + ands = ands && data[key] > conditionValue; + // if (!conditionArray.has(key)) conditionArray.add(key); + break; + default: + ands = ands && data[key] == conditionValue; + // if (!conditionArray.has(key)) conditionArray.add(key); + } + } + if (!ands) { + // return { ok: false, conditionArray }; + return false; + } + } + + // return { ok: true, conditionArray }; + return true; +}; + function checkingOptions({ question, answer }) { let options = convertStringToJson(question?.options) || [], inputType = +question?.inputType || -1; @@ -22,35 +59,62 @@ function checkingOptions({ question, answer }) { const OptionsValidValue = options.map((option) => { return parseValue(option?.value); }) - const questionAnswer = answer[question.id]; if (questionAnswer === null || questionAnswer === undefined) return { ok: false } + let min = question?.min, + max = question?.max, + length = question?.length, + validation = question?.validation; + switch (inputType) { case 1: //TEXT case 3: - if (typeof questionAnswer !== "string" || questionAnswer.length == 0) { + if (typeof questionAnswer !== "string") { + return { + statusCode: 400, + message: ErrorMessages.InvalidData + } + } + if (length && isNumber(length) && questionAnswer.length > +length) { return { - ok: false + statusCode: 400, + message: ErrorMessages.InvalidTextLength(question.id, length) } } + if (validation && isValidRegex(validation)) { + let validationRegex = new RegExp(validation); + if (!validationRegex.test(questionAnswer)) return { + statusCode: 400, + message: ErrorMessages.InvalidTextPattern + } + } + break; case 2: //NUMBER - if (!isNumber(questionAnswer) || !OptionsValidValue.includes(questionAnswer?.toString())) { + if (!isNumber(questionAnswer)) { return { - ok: false + statusCode: 400, + message: ErrorMessages.InvalidNumber(question.id) } } + if (min && isNumber(min) && +min > +questionAnswer) return { + statusCode: 400, + message: ErrorMessages.InvalidMinNumber(question.id, min) + } + if (max && isNumber(max) && +max < +questionAnswer) return { + statusCode: 400, + message: ErrorMessages.InvalidMaxNumber(question.id, max) + } break; case 4: // tak entekhab case 6: - console.log("OptionsValidValue",OptionsValidValue); - console.log("questionAnswer",questionAnswer) if (!OptionsValidValue.includes(questionAnswer)) { return { - ok: false + statusCode: 400, + message: ErrorMessages.InvalidSelectedOption(question.id) } } break; @@ -58,70 +122,88 @@ function checkingOptions({ question, answer }) { case 7: if (Array.isArray(questionAnswer)) { for (let ans of questionAnswer) { - if (!OptionsValidValue.includes(ans)) return { ok: false } + if (!OptionsValidValue.includes(ans)) return { statusCode: 400, message: ErrorMessages.InvalidAdditionalData(question.id) }; } } else if (typeof questionAnswer === "string") { for (let ans of questionAnswer.split(",")) { - if (!OptionsValidValue.includes(ans)) return { ok: false } + if (!OptionsValidValue.includes(ans)) return { statusCode: 400, message: ErrorMessages.InvalidAdditionalData(question.id) }; } } else { - return { ok: false }; + return { statusCode: 400, message: ErrorMessages.InvalidData(question.id) }; } break; case 8: - console.log("oomadinja"); - console.log("javabesh", questionAnswer, isValidDateStrict(questionAnswer)) - if (!isValidDateStrict(questionAnswer)) return { ok: false }; + if (!isValidDateStrict(questionAnswer)) return { statusCode: 400, message: ErrorMessages.InvalidDate(question.id) }; + const questionDate = new Date(questionAnswer); + if (min) { + if (isValidDateStrict(min)) { + if (new Date(min) > questionDate) return { + statusCode: 400, + message: ErrorMessages.InvalidMinDate(question.id) + } + } else if (min === "now()") { + if (new Date() > questionDate) return { + statusCode: 400, + message: ErrorMessages.InvalidMinDate(question.id) + } + } else if (min.includes("day")) { + let days = min.match(/day(s)?\(([0-9]{1,2})\)/)[2]; + if ( + !isNaN(+days) + // && + // Date.now() < questionDate + && + Math.abs(Date.now() - questionDate.getTime()) > convertDaysToSeconds(days) + ) { + return { + statusCode: 400, + message: ErrorMessages.InvalidDayMinDate(question.id, days) + } + } + } + } + if (max) { + if (isValidDateStrict(max)) { + if (new Date(max) < questionDate) return { + statusCode: 400, + message: ErrorMessages.InvalidMaxDate(question.id) + } + } else if (max === "now()") { + if (new Date() < questionDate) return { + statusCode: 400, + message: ErrorMessages.InvalidMaxDate(question.id) + } + } else if (max.includes("day")) { + let days = max.match(/day(s)?\(([0-9]{1,2})\)/)[2]; + if ( + !isNaN(+days) + // && + // Date.now() < questionDate + && + Math.abs(Date.now() - questionDate.getTime()) < convertDaysToSeconds(days) + ) { + return { + statusCode: 400, + message: ErrorMessages.InvalidDayMaxDate(question.id, days) + } + } + } + } break; - case 10: - if (!isBoolean(questionAnswer)) return { ok: false } + if (!isBoolean(questionAnswer)) return { statusCode: 400, message: ErrorMessages.InvalidBooleanData(question.id) } break; default: return { - ok: false - } - } - return { - ok: true - } -} - -const checkCondition = ({ data, condition, inputType = 2, options = null }, conditionArray = new Set()) => { - let ands = true; - for (const key in condition) { - const conditionValue = condition[key]; - if (key == 'or') { - let ors = false; - for (const cond of conditionValue) { - const orConditionChecking = checkCondition({ data, condition: cond }, conditionArray); - ors = ors || orConditionChecking.ok; - conditionArray = new Set([...conditionArray, ...orConditionChecking.conditionArray]) - if (ors) break; + statusCode: 400, + message: ErrorMessages.InvalidInputType(question.id) } - ands = ands && ors; - } else { - if (data[key] == 'true') data[key] = true; - if (data[key] == 'false') data[key] = false; - - switch (key) { - case [Op.gt]: - ands = ands && data[key] > conditionValue; - if (!conditionArray.has(key)) conditionArray.add(key); - break; - default: - ands = ands && data[key] == conditionValue; - if (!conditionArray.has(key)) conditionArray.add(key); - } - } - if (!ands) { - return { ok: false, conditionArray }; - } } - - return { ok: true, conditionArray }; -}; -module.exports={ + return true; +} +module.exports = { sleep, - convertStringToJson + convertStringToJson, + checkingOptions, + checkCondition } \ No newline at end of file