badmfck-api-server 2.9.8 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -12,6 +12,7 @@ type IHandler = Record<HTTPMethod, ((req: HTTPRequestVO) => Promise<TransferPack
|
|
12
12
|
controller: (req: HTTPRequestVO) => Promise<TransferPacketVO<any>>;
|
13
13
|
ignoreInterceptor?: boolean;
|
14
14
|
allowInterceptorError?: boolean;
|
15
|
+
validationModel?: any;
|
15
16
|
asStream?: boolean;
|
16
17
|
}>;
|
17
18
|
export interface IEndpointHandler {
|
@@ -21,6 +22,7 @@ export interface IEndpointHandler {
|
|
21
22
|
independed?: boolean;
|
22
23
|
allowInterceptorError?: boolean;
|
23
24
|
asStream?: boolean;
|
25
|
+
validationModel?: any;
|
24
26
|
}
|
25
27
|
export declare class BaseEndpoint implements IBaseEndpoint {
|
26
28
|
private inializedEndpointNames;
|
@@ -36,6 +38,7 @@ export declare class BaseEndpoint implements IBaseEndpoint {
|
|
36
38
|
getInitalizedEndpointNames(): String[];
|
37
39
|
precheck(req: HTTPRequestVO): Promise<TransferPacketVO<any> | null>;
|
38
40
|
execute(req: HTTPRequestVO): Promise<TransferPacketVO<any>>;
|
41
|
+
protected validateStructure(structure: any, req: HTTPRequestVO): Promise<void>;
|
39
42
|
protected createStream(req: HTTPRequestVO): HTTPRequestVO;
|
40
43
|
}
|
41
44
|
export {};
|
@@ -4,6 +4,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
4
4
|
};
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
6
6
|
exports.BaseEndpoint = void 0;
|
7
|
+
const Validator_1 = require("./helper/Validator");
|
7
8
|
const LogService_1 = require("./LogService");
|
8
9
|
const DefaultErrors_1 = __importDefault(require("./structures/DefaultErrors"));
|
9
10
|
const stream_1 = require("stream");
|
@@ -71,10 +72,15 @@ class BaseEndpoint {
|
|
71
72
|
let targetEP = BaseEndpoint.entrypoint + i.endpoint;
|
72
73
|
targetEP = targetEP.replaceAll("//", "/");
|
73
74
|
if (targetEP === req.endpoint) {
|
74
|
-
if (i.handler && typeof i.handler === "function")
|
75
|
+
if (i.handler && typeof i.handler === "function") {
|
76
|
+
if (i.validationModel)
|
77
|
+
await this.validateStructure(i.validationModel, req);
|
75
78
|
return i.handler.call(this, req);
|
79
|
+
}
|
76
80
|
const httpMethod = req.method.toUpperCase();
|
77
81
|
if (i.handler && i.handler[httpMethod] && typeof i.handler[httpMethod] === "function") {
|
82
|
+
if (i.validationModel)
|
83
|
+
await this.validateStructure(i.validationModel, req);
|
78
84
|
if (i.asStream)
|
79
85
|
req = this.createStream(req);
|
80
86
|
return i.handler[httpMethod].call(this, req);
|
@@ -84,6 +90,9 @@ class BaseEndpoint {
|
|
84
90
|
&& typeof i.handler[httpMethod] === "object"
|
85
91
|
&& "controller" in i.handler[httpMethod]
|
86
92
|
&& typeof i.handler[httpMethod].controller === "function") {
|
93
|
+
const vmodel = i.handler[httpMethod].validationModel;
|
94
|
+
if (vmodel)
|
95
|
+
await this.validateStructure(vmodel, req);
|
87
96
|
if (i.asStream)
|
88
97
|
req = this.createStream(req);
|
89
98
|
return i.handler[httpMethod].controller.call(this, req);
|
@@ -101,6 +110,15 @@ class BaseEndpoint {
|
|
101
110
|
data: null
|
102
111
|
};
|
103
112
|
}
|
113
|
+
async validateStructure(structure, req) {
|
114
|
+
if (!structure)
|
115
|
+
return;
|
116
|
+
if (typeof structure === "object" && (!req.data || typeof req.data !== "object"))
|
117
|
+
throw { ...DefaultErrors_1.default.BAD_REQUEST, details: "empty or invalid request" };
|
118
|
+
const report = await Validator_1.Validator.validateStructure(structure, req.data);
|
119
|
+
if (report)
|
120
|
+
throw { ...DefaultErrors_1.default.BAD_REQUEST, details: report };
|
121
|
+
}
|
104
122
|
createStream(req) {
|
105
123
|
const res = req.response;
|
106
124
|
res.setHeader('Content-Type', 'text/plain');
|
@@ -21,6 +21,7 @@ export declare enum ValidationReport {
|
|
21
21
|
}
|
22
22
|
export declare class Validator {
|
23
23
|
static validateObject(fields: string[], object: any): boolean;
|
24
|
+
static validateStructure(structure: any, object: any): Promise<string[] | undefined>;
|
24
25
|
static convertToType<T>(value: any, type: "string" | "number" | "boolean" | "date"): T | null;
|
25
26
|
static validateValue(value: string | number | boolean, opt?: IValidatorOptions): ValidationReport;
|
26
27
|
}
|
@@ -1,6 +1,10 @@
|
|
1
1
|
"use strict";
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
4
|
+
};
|
2
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
3
6
|
exports.Validator = exports.ValidationReport = void 0;
|
7
|
+
const dns_1 = __importDefault(require("dns"));
|
4
8
|
var ValidationReport;
|
5
9
|
(function (ValidationReport) {
|
6
10
|
ValidationReport[ValidationReport["OK"] = 1] = "OK";
|
@@ -20,6 +24,88 @@ class Validator {
|
|
20
24
|
}
|
21
25
|
return true;
|
22
26
|
}
|
27
|
+
static async validateStructure(structure, object) {
|
28
|
+
if (!structure)
|
29
|
+
return;
|
30
|
+
if (!object)
|
31
|
+
return ["no data"];
|
32
|
+
if (typeof structure !== "object") {
|
33
|
+
if (typeof object === "object")
|
34
|
+
return ["wrong datatype"];
|
35
|
+
if (typeof object !== typeof structure)
|
36
|
+
return ["datatype missmatch"];
|
37
|
+
return;
|
38
|
+
}
|
39
|
+
if (typeof structure === "function") {
|
40
|
+
let result = ['can`t validate data'];
|
41
|
+
try {
|
42
|
+
result = await structure(object);
|
43
|
+
}
|
44
|
+
catch (e) { }
|
45
|
+
return result;
|
46
|
+
}
|
47
|
+
let errors = [];
|
48
|
+
for (let i in structure) {
|
49
|
+
if (!(i in object))
|
50
|
+
errors.push("no field '" + i + "'");
|
51
|
+
if (typeof object[i] !== typeof structure[i])
|
52
|
+
errors.push("wrong datatype for field '" + i + "' expected " + typeof structure[i] + " got " + typeof object[i]);
|
53
|
+
if (typeof structure[i] === "object" || typeof structure[i] === "function") {
|
54
|
+
const result = await this.validateStructure(structure[i], object[i]);
|
55
|
+
if (result) {
|
56
|
+
for (let j of result)
|
57
|
+
errors.push(j);
|
58
|
+
}
|
59
|
+
}
|
60
|
+
if (typeof structure[i] === "string" && structure[i].includes(",")) {
|
61
|
+
const expected = structure[i].split(",").map((v) => v.trim().toLowerCase());
|
62
|
+
if (expected.length) {
|
63
|
+
const value = object[i].toString().toLowerCase().trim();
|
64
|
+
if (value.length === 0)
|
65
|
+
errors.push("empty value for field '" + i + "'");
|
66
|
+
else if (expected.indexOf(value) === -1)
|
67
|
+
errors.push("wrong value for field '" + i + "', expected " + expected.join(", ") + " got: " + value);
|
68
|
+
}
|
69
|
+
}
|
70
|
+
if (typeof structure[i] === "string" && structure[i].includes("regex:")) {
|
71
|
+
const regex = structure[i].substring(6);
|
72
|
+
const reg = new RegExp(regex);
|
73
|
+
if (reg.test(object[i]) === false)
|
74
|
+
errors.push("wrong value for field '" + i + "', false mask for: " + object[i]);
|
75
|
+
}
|
76
|
+
if (typeof structure[i] === "string" && (structure[i] === "@" || structure[i] === "email")) {
|
77
|
+
const value = object[i].toString().toLowerCase().trim();
|
78
|
+
if (value.replaceAll(/^[\w-\.]+@([\w-]+\.)+[\w-]{2,6}$/g, "").length !== 0)
|
79
|
+
errors.push("wrong value for field '" + i + "', expected email got: " + object[i]);
|
80
|
+
const domain = value.split("@")[1];
|
81
|
+
try {
|
82
|
+
await dns_1.default.promises.resolveMx(domain);
|
83
|
+
}
|
84
|
+
catch (e) {
|
85
|
+
return ["MX Domain is incorrect"];
|
86
|
+
}
|
87
|
+
}
|
88
|
+
if (typeof structure[i] === "number") {
|
89
|
+
if (isNaN(object[i]))
|
90
|
+
errors.push("wrong value for field '" + i + "', expected number got " + object[i]);
|
91
|
+
if (structure[i] != 0) {
|
92
|
+
if (structure[i] > 0) {
|
93
|
+
const max = structure[i];
|
94
|
+
if (object[i] > max)
|
95
|
+
errors.push("value for field '" + i + "' is too big, expected less than " + max + " got: " + object[i]);
|
96
|
+
}
|
97
|
+
else {
|
98
|
+
const min = structure[i] * -1;
|
99
|
+
if (object[i] < min)
|
100
|
+
errors.push("value for field '" + i + "' is too small, expected more than " + min + " got: " + object[i]);
|
101
|
+
}
|
102
|
+
}
|
103
|
+
}
|
104
|
+
}
|
105
|
+
if (errors.length > 0)
|
106
|
+
return errors;
|
107
|
+
return;
|
108
|
+
}
|
23
109
|
static convertToType(value, type) {
|
24
110
|
if (value === null || value === undefined)
|
25
111
|
return null;
|