You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

125 lines
3.8 KiB

import { Request, Response, NextFunction } from "express"
import { Logging } from "@hibas123/nodelogging";
import { isBoolean, isString, isNumber, isObject, isDate, isArray, isSymbol } from "util";
import RequestError, { HttpStatusCode } from "../../helper/request_error";
export enum Types {
STRING,
NUMBER,
BOOLEAN,
EMAIL,
OBJECT,
DATE,
ARRAY,
ENUM
}
function isEmail(value: any): boolean {
return /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/.test(value)
}
export interface CheckObject {
type: Types
query?: boolean
optional?: boolean
/**
* Only when Type.ENUM
*
* values to check before
*/
values?: string[]
/**
* Only when Type.STRING
*/
notempty?: boolean // Only STRING
}
export interface Checks {
[index: string]: CheckObject// | Types
}
// req: Request, res: Response, next: NextFunction
export default function (fields: Checks, noadditional = false) {
return (req: Request, res: Response, next: NextFunction) => {
let errors: { message: string, field: string }[] = []
function check(data: any, field_name: string, field: CheckObject) {
if (data !== undefined && data !== null) {
switch (field.type) {
case Types.STRING:
if (isString(data)) {
if (!field.notempty) return;
if (data !== "") return;
}
break;
case Types.NUMBER:
if (isNumber(data)) return;
break;
case Types.EMAIL:
if (isEmail(data)) return;
break;
case Types.BOOLEAN:
if (isBoolean(data)) return;
break;
case Types.OBJECT:
if (isObject(data)) return;
break;
case Types.ARRAY:
if (isArray(data)) return;
break;
case Types.DATE:
if (isDate(data)) return;
break;
case Types.ENUM:
if (isString(data)) {
if (field.values.indexOf(data) >= 0) return;
}
break;
default:
Logging.error(`Invalid type to check: ${field.type} ${Types[field.type]}`)
}
errors.push({
message: res.__("Field {{field}} has wrong type. It should be from type {{type}}", { field: field_name, type: Types[field.type].toLowerCase() }),
field: field_name
})
} else {
if (!field.optional) errors.push({
message: res.__("Field {{field}} is not defined", { field: field_name }),
field: field_name
})
}
}
for (let field_name in fields) {
let field = fields[field_name]
let data = fields[field_name].query ? req.query[field_name] : req.body[field_name]
check(data, field_name, field)
}
if (noadditional) { //Checks if the data given has additional parameters
let should = Object.keys(fields);
should = should.filter(e => !fields[e].query); //Query parameters should not exist on body
let has = Object.keys(req.body);
has.every(e => {
if (should.indexOf(e) >= 0) {
return true;
} else {
errors.push({
message: res.__("Field {{field}} should not be there", { field: e }),
field: e
})
return false;
}
})
}
if (errors.length > 0) {
let err = new RequestError(errors, HttpStatusCode.BAD_REQUEST, true);
next(err);
} else
next()
}
}