File: //matrixSwot/backend/modules/schemaValidate.js
const moment = require("moment-timezone");
const atob = require("atob");
async function validSchema(method, schema, data, token) {
try {
if (schema.data && schema.data === "BASE64")
data = await JSON.parse(atob(data));
//Valida se a sessão possui um token válido
if (
(schema.token === true &&
token.user &&
token.user.user &&
(!token.user.user.id || isNaN(token.user.user.id))) ||
(schema.token && !token)
) {
return {
code: 401,
data: { error: `Invalid session token` }
};
}
//Valida se os parâmtros estão no schema
let invalidParams = ``;
Object.keys(data).forEach(q => {
if (
method === "get" &&
q !== "get_page" &&
q !== "get_limit" &&
q !== "get_orderBy" &&
q !== "get_order" &&
(schema.fields[q] === undefined || schema.fields[q] === null)
) {
invalidParams += ` ${q} |`;
}
});
if (invalidParams) {
return {
code: 400,
data: { error: `Invalid parameters |${invalidParams}` }
};
}
//----->Valida se dados requeridos no schema foram enviados
let requiredSchema = {};
Object.keys(schema.fields).forEach(q => {
if (
schema.fields[q].required &&
(data[q] === undefined || data[q] === null || data[q] === "")
) {
requiredSchema = {
...requiredSchema,
[q]: `This parameter is required`
};
}
});
if (Object.keys(requiredSchema).length > 0) {
return {
code: 400,
data: {
error: "Sent Parameters do not meet data rules",
fields: requiredSchema
}
};
}
//----->Valida se os parâmetros estão de acordo com schema
let invalidFields = {};
Object.keys(data).forEach(q => {
if (
(method === "get" &&
q !== "get_page" &&
q !== "get_limit" &&
q !== "get_searchExact" &&
q !== "get_orderBy" &&
q !== "get_order") ||
method !== "get"
) {
//----->Valida máximo de caracteres
if (
schema.fields[q] &&
schema.fields[q].max_size &&
data[q].length > schema.fields[q].max_size
) {
invalidFields = {
...invalidFields,
[q]: `Parameter must contain less than ${schema.fields[q].max_size} characters`
};
}
//----->Valida minimo de caracteres
if (
schema.fields[q] &&
schema.fields[q].min_size &&
data[q].length < schema.fields[q].min_size
) {
invalidFields = {
...invalidFields,
[q]: `Parameter must contain more than ${schema.fields[q].min_size} characters`
};
}
//----->Valida se é número
if (
schema.fields[q] &&
(schema.fields[q].type === "number" ||
schema.fields[q].type === "serial") &&
isNaN(data[q])
) {
invalidFields = {
...invalidFields,
[q]: `This parameter must be INTEGER`
};
}
//----->Valida valores numéricos máximo e minimo
if (
schema.fields[q] &&
(schema.fields[q].type === "number" ||
schema.fields[q].type === "serial") &&
!isNaN(data[q])
) {
if (
(schema.fields[q].max_value &&
parseInt(data[q], 10) > schema.fields[q].max_value) ||
((schema.fields[q].min_value === 0 || schema.fields[q].min_value) &&
parseInt(data[q], 10) < schema.fields[q].min_value)
) {
invalidFields = {
...invalidFields,
[q]: `This parameter must be a number between ${
!schema.fields[q].min_value || schema.fields[q].min_value === 0
? "0"
: schema.fields[q].min_value
} and ${schema.fields[q].max_value}`
};
}
}
//----->Valida se parâmetro tipo Options está correto
if (
schema.fields[q] &&
schema.fields[q].type === "options" &&
schema.fields[q].options.indexOf(data[q]) === -1
) {
invalidFields = {
...invalidFields,
[q]: `This parameter must be one of the options: ${schema.fields[q].options} `
};
}
//----->Valida se parâmetro tipo Email está correto
if (
schema.fields[q] &&
schema.fields[q].type === "email" &&
!validEmail(data[q])
) {
invalidFields = {
...invalidFields,
[q]: `The parameter sent is not a valid EMAIL`
};
}
//----->Valida caso seja um CPF
if (
schema.fields[q] &&
schema.fields[q].type === "cpf" &&
!validCPF(data[q])
) {
invalidFields = {
...invalidFields,
[q]: `The parameter sent is not a valid CPF`
};
}
//----->Valida caso seja um CNPJ
if (
schema.fields[q] &&
schema.fields[q].type === "cnpj" &&
!validCNPJ(data[q])
) {
invalidFields = {
...invalidFields,
[q]: `The parameter sent is not a valid CNPJ`
};
}
//----->Valida caso seja uma data
if (
schema.fields[q] &&
schema.fields[q].type === "date" &&
!moment(data[q], "YYYY-MM-DD", true).isValid()
) {
invalidFields = {
...invalidFields,
[q]: `The parameter sent is not a valid DATE -> Ex: 2020-01-01`
};
}
//----->Valida caso seja uma data e hora
if (
schema.fields[q] &&
schema.fields[q].type === "dateTime" &&
!moment(data[q], "YYYY-MM-DD HH:mm", true).isValid()
) {
invalidFields = {
...invalidFields,
[q]: `The parameter sent is not a valid DATE & TIME -> Ex: 2020-01-01 01:00`
};
}
}
});
if (Object.keys(invalidFields).length > 0) {
return {
code: 400,
data: {
error: "Sent Parameters do not meet data rules",
fields: invalidFields
}
};
}
} catch (err) {
console.log(err);
return false;
}
//---->Retorno com validação de todos os dados
return true;
}
//Validação de CNPJ
function validCNPJ(cnpj) {
cnpj = cnpj.replace(/[^\d]+/g, "");
if (
!cnpj ||
parseInt(cnpj.length, 10) !== 14 ||
String(cnpj) === "00000000000000" ||
String(cnpj) === "11111111111111" ||
String(cnpj) === "22222222222222" ||
String(cnpj) === "33333333333333" ||
String(cnpj) === "44444444444444" ||
String(cnpj) === "55555555555555" ||
String(cnpj) === "66666666666666" ||
String(cnpj) === "77777777777777" ||
String(cnpj) === "88888888888888" ||
String(cnpj) === "99999999999999"
)
return false;
let docLength = cnpj.length - 2;
let docNumbers = cnpj.substring(0, docLength);
let docDigits = cnpj.substring(docLength);
let docSum = 0;
let docPos = docLength - 7;
for (let i = docLength; i >= 1; i--) {
docSum += docNumbers.charAt(docLength - i) * docPos--;
if (docPos < 2) docPos = 9;
}
let result = docSum % 11 < 2 ? 0 : 11 - (docSum % 11);
if (result != docDigits.charAt(0)) return false;
docLength = docLength + 1;
docNumbers = cnpj.substring(0, docLength);
docSum = 0;
docPos = docLength - 7;
for (let i = docLength; i >= 1; i--) {
docSum += docNumbers.charAt(docLength - i) * docPos--;
if (docPos < 2) docPos = 9;
}
result = docSum % 11 < 2 ? 0 : 11 - (docSum % 11);
if (result != docDigits.charAt(1)) return false;
return true;
}
//Validação de CPF
function validCPF(req) {
var cpf = req.replace(/[^\d]+/g, "");
if (cpf === "") return false;
if (
(cpf.length !== 11 ||
cpf === "00000000000" ||
cpf === "11111111111" ||
cpf === "22222222222" ||
cpf === "33333333333" ||
cpf === "44444444444" ||
cpf === "55555555555" ||
cpf === "66666666666" ||
cpf === "77777777777" ||
cpf === "88888888888" ||
cpf === "99999999999") &&
process.env.LOCAL === "PROD"
)
return false;
var add = 0;
for (let i = 0; i < 9; i++) add += parseInt(cpf.charAt(i), 10) * (10 - i);
var rev = 11 - (add % 11);
if (rev === 10 || rev === 11) rev = 0;
if (rev !== parseInt(cpf.charAt(9), 10)) return false;
add = 0;
for (let i = 0; i < 10; i++) add += parseInt(cpf.charAt(i), 10) * (11 - i);
rev = 11 - (add % 11);
if (rev === 10 || rev === 11) rev = 0;
if (rev !== parseInt(cpf.charAt(10), 10)) return false;
return true;
}
function validEmail(email) {
let user = email.substring(0, email.indexOf("@"));
let domain = email.substring(email.indexOf("@") + 1, email.length);
if (
user.length >= 1 &&
domain.length >= 3 &&
user.search("@") == -1 &&
domain.search("@") == -1 &&
user.search(" ") == -1 &&
domain.search(" ") == -1 &&
domain.search(".") != -1 &&
domain.indexOf(".") >= 1 &&
domain.lastIndexOf(".") < domain.length - 1
) {
return true;
} else {
return false;
}
}
module.exports = { validSchema };