namirasoft-node 1.4.131 → 1.4.133

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.
@@ -1,7 +1,7 @@
1
- export type BaseApplicationLink =
2
- {
3
- name: string;
4
- url: string;
5
- logo: string;
6
- description: string;
1
+ export type BaseApplicationLink =
2
+ {
3
+ name: string;
4
+ url: string;
5
+ logo: string;
6
+ description: string;
7
7
  };
@@ -1,227 +1,227 @@
1
- import * as express from 'express';
2
- import { AnomalyDetector } from './AnomalyDetector';
3
- import { Meta } from './Meta';
4
- import { EnvService, ErrorOperation, HTTPError, HTTPMethod, ObjectService } from 'namirasoft-core';
5
- import { BaseApplication } from './BaseApplication';
6
- import { BaseTypeSchema, BaseVariableSchema, ControllerSchema, JoiValidator } from 'namirasoft-schema';
7
- import { IDatabase } from './IDatabase';
8
-
9
- export abstract class BaseController<D extends { [name: string]: IDatabase }, State, Props, Output>
10
- {
11
- protected log: {
12
- show: boolean;
13
- can: (() => Promise<boolean>)[];
14
- onBefore: (() => Promise<void>)[];
15
- } = {
16
- show: true,
17
- can: [],
18
- onBefore: []
19
- };
20
- public app: BaseApplication<D>;
21
- public req: express.Request;
22
- public res: express.Response;
23
- public meta!: Meta;
24
- public modes: string[] = ["api"];
25
- protected output!: Output | null;
26
- protected result!: any;
27
- protected state!: State;
28
- protected props!: Props;
29
- protected validate_query: boolean = true;
30
- public bodyAs: {
31
- json: { enabled: boolean, limit: string },
32
- raw: { enabled: boolean, type: string }
33
- } = {
34
- json: {
35
- enabled: true,
36
- limit: "100kb"
37
- },
38
- raw: {
39
- enabled: false,
40
- type: "application/json"
41
- }
42
- };
43
- public generate_sdk: boolean = true;
44
- public generate_swagger: boolean = true;
45
- constructor(app: BaseApplication<D>, req: express.Request, res: express.Response)
46
- {
47
- this.app = app;
48
- this.req = req;
49
- this.res = res;
50
- }
51
- protected getAnomaly(): AnomalyDetector | null
52
- {
53
- return null;
54
- }
55
- abstract getInfo(): { name: string, tag: string, method: HTTPMethod, path: string, summary: string };
56
- abstract getHeadersSchema(): Promise<BaseVariableSchema[]>;
57
- abstract getParametersSchema(): Promise<BaseVariableSchema[]>;
58
- abstract getBodySchema(): Promise<BaseTypeSchema | null>;
59
- abstract getQueriesSchema(): Promise<BaseVariableSchema[]>;
60
- async getQueriesSchemaSimple(): Promise<BaseVariableSchema[] | null>
61
- {
62
- return null;
63
- }
64
- abstract getOutputSchema(): Promise<BaseTypeSchema | null>;
65
- abstract getState(): Promise<State>;
66
- abstract getProps(): Promise<Props>;
67
- abstract preHandle(): Promise<void>;
68
- abstract handle(): Promise<Output>;
69
- abstract postHandle(): Promise<void>;
70
-
71
- async run()
72
- {
73
- let info = this.getInfo();
74
- this.meta = new Meta(info, this.req);
75
- // output
76
- this.output = null;
77
- this.result = null;
78
-
79
- let showLog = async (log: () => void) =>
80
- {
81
- if (this.log.show)
82
- if (!this.log.can.some((x) => !x()))
83
- {
84
- try
85
- {
86
- for (let i = 0; i < this.log.onBefore.length; i++)
87
- await this.log.onBefore[i]();
88
- } catch (error)
89
- {
90
- this.app.logger.onCatchFatal(error);
91
- }
92
- log();
93
- }
94
- }
95
-
96
- let failed = false;
97
-
98
- try
99
- {
100
- // meta
101
- this.meta.onStart();
102
-
103
- let accpet: string = new ObjectService(this.req.headers.accept).getString("");
104
- let isJson = accpet.includes("application/json") || accpet.includes("*/*");
105
- let isSchema = accpet.includes("application/schema");
106
- if (isJson)
107
- {
108
- this.state = await this.getState();
109
- this.props = await this.getProps();
110
-
111
- // preHandle
112
- await this.preHandle();
113
-
114
- // check for anomaly
115
- let anomaly: AnomalyDetector | null = this.getAnomaly();
116
- if (anomaly != null)
117
- if (anomaly.isAnomaly(this.meta.ip, this.meta.url))
118
- ErrorOperation.throwHTTP(403, 'Suspicious activity detected.');
119
-
120
- // check
121
- JoiValidator.check(await this.getBodySchema(), this.req.body, "Body");
122
- if (this.validate_query)
123
- {
124
- let query = this.req.query;
125
- let schemas = await this.getQueriesSchemaSimple();
126
- if (schemas == null)
127
- schemas = await this.getQueriesSchema();
128
- else
129
- {
130
- for (let key of Object.keys(query))
131
- {
132
- let element = query[key];
133
- if (Array.isArray(element))
134
- query[key] = element.join(",");
135
- }
136
- }
137
- JoiValidator.checkArray(schemas, query, "Query String");
138
- }
139
-
140
- // call controller
141
- this.output = await this.handle();
142
-
143
- // postHandle
144
- await this.postHandle();
145
- }
146
- else if (isSchema)
147
- this.result = await this.getSchema();
148
- else
149
- ErrorOperation.throwHTTP(400, "Invalid accept: " + accpet);
150
- } catch (error)
151
- {
152
- failed = true;
153
- let message: string;
154
- if (error instanceof Error)
155
- {
156
- this.meta.error = error;
157
- message = error.message;
158
- }
159
- else
160
- message = error + "";
161
-
162
- if (error instanceof HTTPError)
163
- {
164
- this.meta.code = error.code;
165
- await showLog(() =>
166
- {
167
- this.app.logger.error(error.message, error.stack, JSON.stringify(this.meta, undefined, 4));
168
- });
169
- }
170
- else
171
- {
172
- this.meta.code = 500;
173
- if (error instanceof Error)
174
- {
175
- await showLog(() =>
176
- {
177
- this.app.logger.critical(error.message, error.stack, JSON.stringify(this.meta, undefined, 4));
178
- });
179
- }
180
- }
181
- this.meta.message = message;
182
- if (error instanceof HTTPError)
183
- this.result = this.meta.message;
184
- else
185
- this.result = "Sorry, internl server error.";
186
- }
187
- // result
188
- if (!this.result)
189
- {
190
- if (this.output == null)
191
- this.result = "Success";
192
- else
193
- this.result = this.output;
194
- }
195
-
196
- // finish
197
- this.meta.onFinish();
198
-
199
- if (!failed)
200
- await showLog(() =>
201
- {
202
- this.app.logger.info(JSON.stringify(this.meta, undefined, 4));
203
- });
204
-
205
- if (this.meta.redirect_location)
206
- return this.res.redirect(this.meta.code, this.meta.redirect_location);
207
- return this.res.status(this.meta.code).send(this.result);
208
- }
209
- async getSchema(): Promise<ControllerSchema>
210
- {
211
- let info = this.getInfo();
212
- let schema = new ControllerSchema(info.name, info.tag, info.method, info.path, info.summary);
213
- schema.headers = await this.getHeadersSchema();
214
- schema.parameters = await this.getParametersSchema();
215
- schema.body = await this.getBodySchema();
216
- schema.queries = await this.getQueriesSchema();
217
- schema.output = await this.getOutputSchema();
218
- schema.check();
219
- return schema;
220
- }
221
- protected _setCookie(name: string, value: any, expires: Date | undefined = undefined)
222
- {
223
- let DOMAIN = new EnvService("DOMAIN").getString();
224
- let domain = "." + DOMAIN;
225
- this.res.cookie(name, value, { domain, path: "/", sameSite: "none", secure: true, expires });
226
- }
1
+ import * as express from 'express';
2
+ import { AnomalyDetector } from './AnomalyDetector';
3
+ import { Meta } from './Meta';
4
+ import { EnvService, ErrorOperation, HTTPError, HTTPMethod, ObjectService } from 'namirasoft-core';
5
+ import { BaseApplication } from './BaseApplication';
6
+ import { BaseTypeSchema, BaseVariableSchema, ControllerSchema, JoiValidator } from 'namirasoft-schema';
7
+ import { IDatabase } from './IDatabase';
8
+
9
+ export abstract class BaseController<D extends { [name: string]: IDatabase }, State, Props, Output>
10
+ {
11
+ protected log: {
12
+ show: boolean;
13
+ can: (() => Promise<boolean>)[];
14
+ onBefore: (() => Promise<void>)[];
15
+ } = {
16
+ show: true,
17
+ can: [],
18
+ onBefore: []
19
+ };
20
+ public app: BaseApplication<D>;
21
+ public req: express.Request;
22
+ public res: express.Response;
23
+ public meta!: Meta;
24
+ public modes: string[] = ["api"];
25
+ protected output!: Output | null;
26
+ protected result!: any;
27
+ protected state!: State;
28
+ protected props!: Props;
29
+ protected validate_query: boolean = true;
30
+ public bodyAs: {
31
+ json: { enabled: boolean, limit: string },
32
+ raw: { enabled: boolean, type: string }
33
+ } = {
34
+ json: {
35
+ enabled: true,
36
+ limit: "100kb"
37
+ },
38
+ raw: {
39
+ enabled: false,
40
+ type: "application/json"
41
+ }
42
+ };
43
+ public generate_sdk: boolean = true;
44
+ public generate_swagger: boolean = true;
45
+ constructor(app: BaseApplication<D>, req: express.Request, res: express.Response)
46
+ {
47
+ this.app = app;
48
+ this.req = req;
49
+ this.res = res;
50
+ }
51
+ protected getAnomaly(): AnomalyDetector | null
52
+ {
53
+ return null;
54
+ }
55
+ abstract getInfo(): { name: string, tag: string, method: HTTPMethod, path: string, summary: string };
56
+ abstract getHeadersSchema(): Promise<BaseVariableSchema[]>;
57
+ abstract getParametersSchema(): Promise<BaseVariableSchema[]>;
58
+ abstract getBodySchema(): Promise<BaseTypeSchema | null>;
59
+ abstract getQueriesSchema(): Promise<BaseVariableSchema[]>;
60
+ async getQueriesSchemaSimple(): Promise<BaseVariableSchema[] | null>
61
+ {
62
+ return null;
63
+ }
64
+ abstract getOutputSchema(): Promise<BaseTypeSchema | null>;
65
+ abstract getState(): Promise<State>;
66
+ abstract getProps(): Promise<Props>;
67
+ abstract preHandle(): Promise<void>;
68
+ abstract handle(): Promise<Output>;
69
+ abstract postHandle(): Promise<void>;
70
+
71
+ async run()
72
+ {
73
+ let info = this.getInfo();
74
+ this.meta = new Meta(info, this.req);
75
+ // output
76
+ this.output = null;
77
+ this.result = null;
78
+
79
+ let showLog = async (log: () => void) =>
80
+ {
81
+ if (this.log.show)
82
+ if (!this.log.can.some((x) => !x()))
83
+ {
84
+ try
85
+ {
86
+ for (let i = 0; i < this.log.onBefore.length; i++)
87
+ await this.log.onBefore[i]();
88
+ } catch (error)
89
+ {
90
+ this.app.logger.onCatchFatal(error);
91
+ }
92
+ log();
93
+ }
94
+ }
95
+
96
+ let failed = false;
97
+
98
+ try
99
+ {
100
+ // meta
101
+ this.meta.onStart();
102
+
103
+ let accpet: string = new ObjectService(this.req.headers.accept).getString("");
104
+ let isJson = accpet.includes("application/json") || accpet.includes("*/*");
105
+ let isSchema = accpet.includes("application/schema");
106
+ if (isJson)
107
+ {
108
+ this.state = await this.getState();
109
+ this.props = await this.getProps();
110
+
111
+ // preHandle
112
+ await this.preHandle();
113
+
114
+ // check for anomaly
115
+ let anomaly: AnomalyDetector | null = this.getAnomaly();
116
+ if (anomaly != null)
117
+ if (anomaly.isAnomaly(this.meta.ip, this.meta.url))
118
+ ErrorOperation.throwHTTP(403, 'Suspicious activity detected.');
119
+
120
+ // check
121
+ JoiValidator.check(await this.getBodySchema(), this.req.body, "Body");
122
+ if (this.validate_query)
123
+ {
124
+ let query = this.req.query;
125
+ let schemas = await this.getQueriesSchemaSimple();
126
+ if (schemas == null)
127
+ schemas = await this.getQueriesSchema();
128
+ else
129
+ {
130
+ for (let key of Object.keys(query))
131
+ {
132
+ let element = query[key];
133
+ if (Array.isArray(element))
134
+ query[key] = element.join(",");
135
+ }
136
+ }
137
+ JoiValidator.checkArray(schemas, query, "Query String");
138
+ }
139
+
140
+ // call controller
141
+ this.output = await this.handle();
142
+
143
+ // postHandle
144
+ await this.postHandle();
145
+ }
146
+ else if (isSchema)
147
+ this.result = await this.getSchema();
148
+ else
149
+ ErrorOperation.throwHTTP(400, "Invalid accept: " + accpet);
150
+ } catch (error)
151
+ {
152
+ failed = true;
153
+ let message: string;
154
+ if (error instanceof Error)
155
+ {
156
+ this.meta.error = error;
157
+ message = error.message;
158
+ }
159
+ else
160
+ message = error + "";
161
+
162
+ if (error instanceof HTTPError)
163
+ {
164
+ this.meta.code = error.code;
165
+ await showLog(() =>
166
+ {
167
+ this.app.logger.error(error.message, error.stack, JSON.stringify(this.meta, undefined, 4));
168
+ });
169
+ }
170
+ else
171
+ {
172
+ this.meta.code = 500;
173
+ if (error instanceof Error)
174
+ {
175
+ await showLog(() =>
176
+ {
177
+ this.app.logger.critical(error.message, error.stack, JSON.stringify(this.meta, undefined, 4));
178
+ });
179
+ }
180
+ }
181
+ this.meta.message = message;
182
+ if (error instanceof HTTPError)
183
+ this.result = this.meta.message;
184
+ else
185
+ this.result = "Sorry, internl server error.";
186
+ }
187
+ // result
188
+ if (!this.result)
189
+ {
190
+ if (this.output == null)
191
+ this.result = "Success";
192
+ else
193
+ this.result = this.output;
194
+ }
195
+
196
+ // finish
197
+ this.meta.onFinish();
198
+
199
+ if (!failed)
200
+ await showLog(() =>
201
+ {
202
+ this.app.logger.info(JSON.stringify(this.meta, undefined, 4));
203
+ });
204
+
205
+ if (this.meta.redirect_location)
206
+ return this.res.redirect(this.meta.code, this.meta.redirect_location);
207
+ return this.res.status(this.meta.code).send(this.result);
208
+ }
209
+ async getSchema(): Promise<ControllerSchema>
210
+ {
211
+ let info = this.getInfo();
212
+ let schema = new ControllerSchema(info.name, info.tag, info.method, info.path, info.summary);
213
+ schema.headers = await this.getHeadersSchema();
214
+ schema.parameters = await this.getParametersSchema();
215
+ schema.body = await this.getBodySchema();
216
+ schema.queries = await this.getQueriesSchema();
217
+ schema.output = await this.getOutputSchema();
218
+ schema.check();
219
+ return schema;
220
+ }
221
+ protected _setCookie(name: string, value: any, expires: Date | undefined = undefined)
222
+ {
223
+ let DOMAIN = new EnvService("DOMAIN").getString();
224
+ let domain = "." + DOMAIN;
225
+ this.res.cookie(name, value, { domain, path: "/", sameSite: "none", secure: true, expires });
226
+ }
227
227
  }