namirasoft-node 1.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.
Files changed (70) hide show
  1. package/dist/AnomalyDetector.d.ts +26 -0
  2. package/dist/AnomalyDetector.js +74 -0
  3. package/dist/AnomalyDetector.js.map +1 -0
  4. package/dist/BaseApplication.d.ts +22 -0
  5. package/dist/BaseApplication.js +104 -0
  6. package/dist/BaseApplication.js.map +1 -0
  7. package/dist/BaseController.d.ts +15 -0
  8. package/dist/BaseController.js +11 -0
  9. package/dist/BaseController.js.map +1 -0
  10. package/dist/BaseDatabase.d.ts +4 -0
  11. package/dist/BaseDatabase.js +7 -0
  12. package/dist/BaseDatabase.js.map +1 -0
  13. package/dist/BaseMiddleware.d.ts +14 -0
  14. package/dist/BaseMiddleware.js +108 -0
  15. package/dist/BaseMiddleware.js.map +1 -0
  16. package/dist/BaseMySqlDatabase.d.ts +4 -0
  17. package/dist/BaseMySqlDatabase.js +11 -0
  18. package/dist/BaseMySqlDatabase.js.map +1 -0
  19. package/dist/BaseSequelizeDatabase.d.ts +15 -0
  20. package/dist/BaseSequelizeDatabase.js +120 -0
  21. package/dist/BaseSequelizeDatabase.js.map +1 -0
  22. package/dist/BaseSequelizeModel.d.ts +3 -0
  23. package/dist/BaseSequelizeModel.js +8 -0
  24. package/dist/BaseSequelizeModel.js.map +1 -0
  25. package/dist/BaseSequelizeTable.d.ts +8 -0
  26. package/dist/BaseSequelizeTable.js +11 -0
  27. package/dist/BaseSequelizeTable.js.map +1 -0
  28. package/dist/BaseTable.d.ts +5 -0
  29. package/dist/BaseTable.js +10 -0
  30. package/dist/BaseTable.js.map +1 -0
  31. package/dist/EmailService.d.ts +16 -0
  32. package/dist/EmailService.js +81 -0
  33. package/dist/EmailService.js.map +1 -0
  34. package/dist/EnvService.d.ts +6 -0
  35. package/dist/EnvService.js +18 -0
  36. package/dist/EnvService.js.map +1 -0
  37. package/dist/IPOperation.d.ts +7 -0
  38. package/dist/IPOperation.js +39 -0
  39. package/dist/IPOperation.js.map +1 -0
  40. package/dist/Meta.d.ts +19 -0
  41. package/dist/Meta.js +29 -0
  42. package/dist/Meta.js.map +1 -0
  43. package/dist/RequestHeaderService.d.ts +8 -0
  44. package/dist/RequestHeaderService.js +17 -0
  45. package/dist/RequestHeaderService.js.map +1 -0
  46. package/dist/ServerToServerOperation.d.ts +5 -0
  47. package/dist/ServerToServerOperation.js +24 -0
  48. package/dist/ServerToServerOperation.js.map +1 -0
  49. package/dist/index.d.ts +15 -0
  50. package/dist/index.js +32 -0
  51. package/dist/index.js.map +1 -0
  52. package/package.json +33 -0
  53. package/src/AnomalyDetector.ts +85 -0
  54. package/src/BaseApplication.ts +112 -0
  55. package/src/BaseController.ts +16 -0
  56. package/src/BaseDatabase.ts +5 -0
  57. package/src/BaseMiddleware.ts +121 -0
  58. package/src/BaseMySqlDatabase.ts +8 -0
  59. package/src/BaseSequelizeDatabase.ts +132 -0
  60. package/src/BaseSequelizeModel.ts +7 -0
  61. package/src/BaseSequelizeTable.ts +13 -0
  62. package/src/BaseTable.ts +10 -0
  63. package/src/EmailService.ts +97 -0
  64. package/src/EnvService.ts +18 -0
  65. package/src/IPOperation.ts +39 -0
  66. package/src/Meta.ts +35 -0
  67. package/src/RequestHeaderService.ts +19 -0
  68. package/src/ServerToServerOperation.ts +24 -0
  69. package/src/index.ts +15 -0
  70. package/tsconfig.json +30 -0
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.BaseTable = void 0;
4
+ class BaseTable {
5
+ constructor(database) {
6
+ this.database = database;
7
+ }
8
+ }
9
+ exports.BaseTable = BaseTable;
10
+ //# sourceMappingURL=BaseTable.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BaseTable.js","sourceRoot":"","sources":["../src/BaseTable.ts"],"names":[],"mappings":";;;AAEA,MAAa,SAAS;IAGlB,YAAY,QAAW;QAEnB,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAC7B,CAAC;CACJ;AAPD,8BAOC"}
@@ -0,0 +1,16 @@
1
+ /// <reference types="node" />
2
+ /// <reference types="node" />
3
+ import { AttachmentLike } from "nodemailer/lib/mailer";
4
+ import { Readable } from "stream";
5
+ export declare class EmailService {
6
+ host: string;
7
+ username: string;
8
+ username_from: string;
9
+ password: string;
10
+ error_title: string;
11
+ error_recipients: string;
12
+ constructor(host: string, username: string, username_from: string, password: string, error_title: string, error_recipients: string);
13
+ sendExeption(error: Error, meta: any, callback?: (err: Error | null, info: any) => void): void;
14
+ sendError(title: string, message: string, callback?: (err: Error | null, info: any) => void): void;
15
+ send(to: string, subject: string, text: string, html?: string | Buffer | Readable | AttachmentLike | undefined, callback?: (err: Error | null, info: any) => void): void;
16
+ }
@@ -0,0 +1,81 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.EmailService = void 0;
7
+ const nodemailer_1 = __importDefault(require("nodemailer"));
8
+ const nodemailer_smtp_transport_1 = __importDefault(require("nodemailer-smtp-transport"));
9
+ class EmailService {
10
+ constructor(host, username, username_from, password, error_title, error_recipients) {
11
+ this.host = host;
12
+ this.username = username;
13
+ this.username_from = username_from;
14
+ this.password = password;
15
+ this.error_title = error_title;
16
+ this.error_recipients = error_recipients;
17
+ }
18
+ sendExeption(error, meta, callback) {
19
+ let title = error.message;
20
+ let message = title;
21
+ if (meta)
22
+ message += "\r\n" + JSON.stringify(meta);
23
+ message += "\r\n" + error.stack;
24
+ this.sendError(title, message, callback);
25
+ }
26
+ sendError(title, message, callback) {
27
+ if (!title)
28
+ title = '';
29
+ let toks = this.error_recipients.split(',');
30
+ for (let i = 0; i < toks.length; i++) {
31
+ const email = toks[i];
32
+ this.send(email, this.error_title + " - " + title, message, undefined, callback);
33
+ }
34
+ }
35
+ send(to, subject, text, html, callback) {
36
+ if (!this.username)
37
+ return;
38
+ if (!this.password)
39
+ return;
40
+ let transform = {};
41
+ if (this.host === 'gmail')
42
+ transform = (0, nodemailer_smtp_transport_1.default)({
43
+ service: 'gmail',
44
+ host: 'smtp.gmail.com',
45
+ auth: {
46
+ user: this.username,
47
+ pass: this.password
48
+ }
49
+ });
50
+ else
51
+ transform = {
52
+ host: this.host,
53
+ port: 465,
54
+ secure: true,
55
+ auth: {
56
+ user: this.username,
57
+ pass: this.password
58
+ }
59
+ };
60
+ let transporter = nodemailer_1.default.createTransport(transform);
61
+ let mailOptions = {
62
+ from: this.username_from,
63
+ to,
64
+ subject,
65
+ text,
66
+ html
67
+ };
68
+ if (html)
69
+ mailOptions.html = html;
70
+ transporter.sendMail(mailOptions, function (error, info) {
71
+ if (callback)
72
+ callback(error, info);
73
+ else {
74
+ if (error)
75
+ console.log(error);
76
+ }
77
+ });
78
+ }
79
+ }
80
+ exports.EmailService = EmailService;
81
+ //# sourceMappingURL=EmailService.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EmailService.js","sourceRoot":"","sources":["../src/EmailService.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import { ConvertService } from "namirasoft-core";
2
+ export declare class EnvService extends ConvertService {
3
+ name: string;
4
+ constructor(name: string);
5
+ getNullString(): string | null;
6
+ }
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.EnvService = void 0;
4
+ const namirasoft_core_1 = require("namirasoft-core");
5
+ class EnvService extends namirasoft_core_1.ConvertService {
6
+ constructor(name) {
7
+ super();
8
+ this.name = name;
9
+ }
10
+ getNullString() {
11
+ let ans = process.env[this.name];
12
+ if (ans)
13
+ return ans;
14
+ return null;
15
+ }
16
+ }
17
+ exports.EnvService = EnvService;
18
+ //# sourceMappingURL=EnvService.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EnvService.js","sourceRoot":"","sources":["../src/EnvService.ts"],"names":[],"mappings":";;;AAAA,qDAAiD;AAEjD,MAAa,UAAW,SAAQ,gCAAc;IAG1C,YAAY,IAAY;QAEpB,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACrB,CAAC;IACQ,aAAa;QAElB,IAAI,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACjC,IAAI,GAAG;YACH,OAAO,GAAG,CAAC;QACf,OAAO,IAAI,CAAC;IAChB,CAAC;CACJ;AAfD,gCAeC"}
@@ -0,0 +1,7 @@
1
+ import * as express from 'express';
2
+ export declare class IPOperation {
3
+ static ERROR_MESSAGE_IP_IS_NOT_WHITELIST: string;
4
+ static getIP(req: express.Request): string;
5
+ static isWhitelist(req: express.Request, whitelist: string[]): boolean;
6
+ static checkWhitelist(req: express.Request, whitelist: string[]): void;
7
+ }
@@ -0,0 +1,39 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.IPOperation = void 0;
4
+ const request_ip_1 = require("@supercharge/request-ip");
5
+ const RequestHeaderService_1 = require("./RequestHeaderService");
6
+ const namirasoft_core_1 = require("namirasoft-core");
7
+ class IPOperation {
8
+ static getIP(req) {
9
+ var _a;
10
+ let ip = new RequestHeaderService_1.RequestHeaderService(req, 'cf-connecting-ip').getString();
11
+ if (!ip)
12
+ ip = new RequestHeaderService_1.RequestHeaderService(req, 'x-forwarded-for').getString();
13
+ if (!ip)
14
+ ip = (_a = (0, request_ip_1.getClientIp)(req)) !== null && _a !== void 0 ? _a : "";
15
+ ip = ip.split(',')[0];
16
+ return ip;
17
+ }
18
+ static isWhitelist(req, whitelist) {
19
+ let ip = this.getIP(req);
20
+ if (!whitelist)
21
+ return true;
22
+ if (whitelist.length === 0)
23
+ return true;
24
+ if (whitelist.includes(ip))
25
+ return true;
26
+ for (let item of whitelist)
27
+ if (ip.substring(0, item.length) === item)
28
+ return true;
29
+ return false;
30
+ }
31
+ static checkWhitelist(req, whitelist) {
32
+ let valid = this.isWhitelist(req, whitelist);
33
+ if (!valid)
34
+ namirasoft_core_1.ErrorOperation.throwHTTP(403, this.ERROR_MESSAGE_IP_IS_NOT_WHITELIST, this.getIP(req));
35
+ }
36
+ }
37
+ exports.IPOperation = IPOperation;
38
+ IPOperation.ERROR_MESSAGE_IP_IS_NOT_WHITELIST = `Ip does not match the whitelisted IP address: {0}`;
39
+ //# sourceMappingURL=IPOperation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"IPOperation.js","sourceRoot":"","sources":["../src/IPOperation.ts"],"names":[],"mappings":";;;AACA,wDAAsD;AACtD,iEAA8D;AAC9D,qDAAiD;AAEjD,MAAa,WAAW;IAGpB,MAAM,CAAC,KAAK,CAAC,GAAoB;;QAE7B,IAAI,EAAE,GAAG,IAAI,2CAAoB,CAAC,GAAG,EAAE,kBAAkB,CAAC,CAAC,SAAS,EAAE,CAAC;QACvE,IAAI,CAAC,EAAE;YACH,EAAE,GAAG,IAAI,2CAAoB,CAAC,GAAG,EAAE,iBAAiB,CAAC,CAAC,SAAS,EAAE,CAAC;QACtE,IAAI,CAAC,EAAE;YACH,EAAE,GAAG,MAAA,IAAA,wBAAW,EAAC,GAAG,CAAC,mCAAI,EAAE,CAAC;QAChC,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QACtB,OAAO,EAAE,CAAC;IACd,CAAC;IACD,MAAM,CAAC,WAAW,CAAC,GAAoB,EAAE,SAAmB;QAExD,IAAI,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACzB,IAAI,CAAC,SAAS;YACV,OAAO,IAAI,CAAC;QAChB,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC;YACtB,OAAO,IAAI,CAAC;QAChB,IAAI,SAAS,CAAC,QAAQ,CAAC,EAAE,CAAC;YACtB,OAAO,IAAI,CAAC;QAChB,KAAK,IAAI,IAAI,IAAI,SAAS;YACtB,IAAI,EAAE,CAAC,SAAS,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,KAAK,IAAI;gBACrC,OAAO,IAAI,CAAC;QACpB,OAAO,KAAK,CAAC;IACjB,CAAC;IACD,MAAM,CAAC,cAAc,CAAC,GAAoB,EAAE,SAAmB;QAE3D,IAAI,KAAK,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;QAC7C,IAAI,CAAC,KAAK;YACN,gCAAc,CAAC,SAAS,CAAC,GAAG,EAAE,IAAI,CAAC,iCAAiC,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;IAC/F,CAAC;;AAhCL,kCAiCC;AA/BU,6CAAiC,GAAG,mDAAmD,CAAC"}
package/dist/Meta.d.ts ADDED
@@ -0,0 +1,19 @@
1
+ /// <reference types="node" />
2
+ import * as express from 'express';
3
+ import { IncomingHttpHeaders } from "http";
4
+ export declare class Meta {
5
+ ip: string;
6
+ method: string;
7
+ url: string;
8
+ headers: IncomingHttpHeaders;
9
+ body: any;
10
+ start_time: Date | null;
11
+ end_time: Date | null;
12
+ duration: number | null;
13
+ code: number;
14
+ message: string;
15
+ error: Error | null;
16
+ constructor(req: express.Request);
17
+ onStart(): void;
18
+ onFinish(): void;
19
+ }
package/dist/Meta.js ADDED
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Meta = void 0;
4
+ const IPOperation_1 = require("./IPOperation");
5
+ class Meta {
6
+ constructor(req) {
7
+ this.start_time = null;
8
+ this.end_time = null;
9
+ this.duration = null;
10
+ this.code = 200;
11
+ this.message = "Success";
12
+ this.error = null;
13
+ this.ip = IPOperation_1.IPOperation.getIP(req);
14
+ this.method = req.method;
15
+ this.url = req.originalUrl;
16
+ this.headers = req.headers;
17
+ this.body = req.body;
18
+ }
19
+ onStart() {
20
+ this.start_time = new Date();
21
+ }
22
+ onFinish() {
23
+ var _a, _b, _c, _d;
24
+ this.end_time = new Date();
25
+ this.duration = ((_b = (_a = this.end_time) === null || _a === void 0 ? void 0 : _a.getTime()) !== null && _b !== void 0 ? _b : 0) - ((_d = (_c = this.start_time) === null || _c === void 0 ? void 0 : _c.getTime()) !== null && _d !== void 0 ? _d : 0);
26
+ }
27
+ }
28
+ exports.Meta = Meta;
29
+ //# sourceMappingURL=Meta.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Meta.js","sourceRoot":"","sources":["../src/Meta.ts"],"names":[],"mappings":";;;AAEA,+CAA4C;AAE5C,MAAa,IAAI;IAab,YAAY,GAAoB;QANhC,eAAU,GAAgB,IAAI,CAAC;QAC/B,aAAQ,GAAgB,IAAI,CAAC;QAC7B,aAAQ,GAAkB,IAAI,CAAC;QAC/B,SAAI,GAAW,GAAG,CAAC;QACnB,YAAO,GAAW,SAAS,CAAC;QAC5B,UAAK,GAAiB,IAAI,CAAC;QAGvB,IAAI,CAAC,EAAE,GAAG,yBAAW,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACjC,IAAI,CAAC,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC;QACzB,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC,WAAW,CAAC;QAC3B,IAAI,CAAC,OAAO,GAAG,GAAG,CAAC,OAAO,CAAC;QAC3B,IAAI,CAAC,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC;IACzB,CAAC;IACD,OAAO;QAEH,IAAI,CAAC,UAAU,GAAG,IAAI,IAAI,EAAE,CAAC;IACjC,CAAC;IACD,QAAQ;;QAEJ,IAAI,CAAC,QAAQ,GAAG,IAAI,IAAI,EAAE,CAAC;QAC3B,IAAI,CAAC,QAAQ,GAAG,CAAC,MAAA,MAAA,IAAI,CAAC,QAAQ,0CAAE,OAAO,EAAE,mCAAI,CAAC,CAAC,GAAG,CAAC,MAAA,MAAA,IAAI,CAAC,UAAU,0CAAE,OAAO,EAAE,mCAAI,CAAC,CAAC,CAAC;IACxF,CAAC;CACJ;AA9BD,oBA8BC"}
@@ -0,0 +1,8 @@
1
+ import * as express from 'express';
2
+ import { ConvertService } from 'namirasoft-core';
3
+ export declare class RequestHeaderService extends ConvertService {
4
+ private req;
5
+ private name;
6
+ constructor(req: express.Request, name: string);
7
+ getNullString(): string | null;
8
+ }
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RequestHeaderService = void 0;
4
+ const namirasoft_core_1 = require("namirasoft-core");
5
+ class RequestHeaderService extends namirasoft_core_1.ConvertService {
6
+ constructor(req, name) {
7
+ super();
8
+ this.req = req;
9
+ this.name = name;
10
+ }
11
+ getNullString() {
12
+ let item = this.req.headers[this.name];
13
+ return new namirasoft_core_1.ObjectService(item).getNullString();
14
+ }
15
+ }
16
+ exports.RequestHeaderService = RequestHeaderService;
17
+ //# sourceMappingURL=RequestHeaderService.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RequestHeaderService.js","sourceRoot":"","sources":["../src/RequestHeaderService.ts"],"names":[],"mappings":";;;AACA,qDAAgE;AAEhE,MAAa,oBAAqB,SAAQ,gCAAc;IAIpD,YAAY,GAAoB,EAAE,IAAY;QAE1C,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACrB,CAAC;IACQ,aAAa;QAElB,IAAI,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACvC,OAAO,IAAI,+BAAa,CAAC,IAAI,CAAC,CAAC,aAAa,EAAE,CAAC;IACnD,CAAC;CACJ;AAfD,oDAeC"}
@@ -0,0 +1,5 @@
1
+ import * as express from 'express';
2
+ export declare class ServerToServerOperation {
3
+ static isValid(sign_key: string, data: any, req: express.Request, sign_header: string): boolean;
4
+ static check(sign_key: string, data: any, req: express.Request, sign_header: string): void;
5
+ }
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ServerToServerOperation = void 0;
4
+ const namirasoft_core_1 = require("namirasoft-core");
5
+ const RequestHeaderService_1 = require("./RequestHeaderService");
6
+ class ServerToServerOperation {
7
+ static isValid(sign_key, data, req, sign_header) {
8
+ let signature = new RequestHeaderService_1.RequestHeaderService(req, sign_header).getString();
9
+ return namirasoft_core_1.SignOperation.isValid(sign_key, data, signature);
10
+ }
11
+ static check(sign_key, data, req, sign_header) {
12
+ if (!sign_key)
13
+ namirasoft_core_1.ErrorOperation.throwHTTP(401, "Invlid signature - No sign key.");
14
+ if (!sign_header)
15
+ namirasoft_core_1.ErrorOperation.throwHTTP(401, "Invlid signature - No sign header name.");
16
+ let signature = new RequestHeaderService_1.RequestHeaderService(req, sign_header).getString();
17
+ if (!signature)
18
+ namirasoft_core_1.ErrorOperation.throwHTTP(401, "Invlid signature - No signature.");
19
+ if (!this.isValid(sign_key, data, req, sign_header))
20
+ namirasoft_core_1.ErrorOperation.throwHTTP(401, "Invlid signature.");
21
+ }
22
+ }
23
+ exports.ServerToServerOperation = ServerToServerOperation;
24
+ //# sourceMappingURL=ServerToServerOperation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ServerToServerOperation.js","sourceRoot":"","sources":["../src/ServerToServerOperation.ts"],"names":[],"mappings":";;;AACA,qDAAgE;AAChE,iEAA8D;AAE9D,MAAa,uBAAuB;IAEhC,MAAM,CAAC,OAAO,CAAC,QAAgB,EAAE,IAAS,EAAE,GAAoB,EAAE,WAAmB;QAEjF,IAAI,SAAS,GAAG,IAAI,2CAAoB,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC,SAAS,EAAE,CAAC;QACvE,OAAO,+BAAa,CAAC,OAAO,CAAC,QAAQ,EAAE,IAAI,EAAE,SAAS,CAAC,CAAC;IAC5D,CAAC;IACD,MAAM,CAAC,KAAK,CAAC,QAAgB,EAAE,IAAS,EAAE,GAAoB,EAAE,WAAmB;QAE/E,IAAI,CAAC,QAAQ;YACT,gCAAc,CAAC,SAAS,CAAC,GAAG,EAAE,iCAAiC,CAAC,CAAC;QACrE,IAAI,CAAC,WAAW;YACZ,gCAAc,CAAC,SAAS,CAAC,GAAG,EAAE,yCAAyC,CAAC,CAAC;QAC7E,IAAI,SAAS,GAAG,IAAI,2CAAoB,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC,SAAS,EAAE,CAAC;QACvE,IAAI,CAAC,SAAS;YACV,gCAAc,CAAC,SAAS,CAAC,GAAG,EAAE,kCAAkC,CAAC,CAAC;QACtE,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,IAAI,EAAE,GAAG,EAAE,WAAW,CAAC;YAC/C,gCAAc,CAAC,SAAS,CAAC,GAAG,EAAE,mBAAmB,CAAC,CAAC;IAC3D,CAAC;CACJ;AAnBD,0DAmBC"}
@@ -0,0 +1,15 @@
1
+ export * from "./AnomalyDetector";
2
+ export * from "./BaseApplication";
3
+ export * from "./BaseController";
4
+ export * from "./BaseDatabase";
5
+ export * from "./BaseMiddleware";
6
+ export * from "./BaseSequelizeModel";
7
+ export * from "./BaseMySqlDatabase";
8
+ export * from "./BaseSequelizeTable";
9
+ export * from "./BaseSequelizeDatabase";
10
+ export * from "./BaseTable";
11
+ export * from "./EmailService";
12
+ export * from "./EnvService";
13
+ export * from "./IPOperation";
14
+ export * from "./RequestHeaderService";
15
+ export * from "./ServerToServerOperation";
package/dist/index.js ADDED
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./AnomalyDetector"), exports);
18
+ __exportStar(require("./BaseApplication"), exports);
19
+ __exportStar(require("./BaseController"), exports);
20
+ __exportStar(require("./BaseDatabase"), exports);
21
+ __exportStar(require("./BaseMiddleware"), exports);
22
+ __exportStar(require("./BaseSequelizeModel"), exports);
23
+ __exportStar(require("./BaseMySqlDatabase"), exports);
24
+ __exportStar(require("./BaseSequelizeTable"), exports);
25
+ __exportStar(require("./BaseSequelizeDatabase"), exports);
26
+ __exportStar(require("./BaseTable"), exports);
27
+ __exportStar(require("./EmailService"), exports);
28
+ __exportStar(require("./EnvService"), exports);
29
+ __exportStar(require("./IPOperation"), exports);
30
+ __exportStar(require("./RequestHeaderService"), exports);
31
+ __exportStar(require("./ServerToServerOperation"), exports);
32
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,oDAAkC;AAClC,oDAAkC;AAClC,mDAAiC;AACjC,iDAA+B;AAC/B,mDAAiC;AACjC,uDAAqC;AACrC,sDAAoC;AACpC,uDAAqC;AACrC,0DAAwC;AACxC,8CAA4B;AAC5B,iDAA+B;AAC/B,+CAA6B;AAC7B,gDAA8B;AAC9B,yDAAuC;AACvC,4DAA0C"}
package/package.json ADDED
@@ -0,0 +1,33 @@
1
+ {
2
+ "name": "namirasoft-node",
3
+ "version": "1.0.0",
4
+ "description": "Namira Software Corporation Node Package",
5
+ "main": "./dist/index.js",
6
+ "types": "./dist/index.d.ts",
7
+ "scripts": {},
8
+ "author": "Amir Abolhasani",
9
+ "license": "MIT",
10
+ "dependencies": {
11
+ "@supercharge/request-ip": "^1.2.0",
12
+ "@types/cors": "^2.8.15",
13
+ "@types/express": "^4.17.20",
14
+ "@types/nodemailer": "^6.4.13",
15
+ "@types/nodemailer-smtp-transport": "^2.7.7",
16
+ "@types/swagger-jsdoc": "^6.0.2",
17
+ "@types/swagger-ui-express": "^4.1.5",
18
+ "cors": "^2.8.5",
19
+ "express": "^4.18.2",
20
+ "joi": "^17.11.0",
21
+ "namirasoft-core": "^1.0.1",
22
+ "namirasoft-log": "^1.0.0",
23
+ "nodemailer": "^6.9.7",
24
+ "nodemailer-smtp-transport": "^2.7.4",
25
+ "request-ip": "^3.3.0",
26
+ "sequelize": "^6.33.0",
27
+ "swagger-jsdoc": "^6.2.8",
28
+ "swagger-ui-express": "^5.0.0"
29
+ },
30
+ "devDependencies": {
31
+ "@types/node": "^20.5.9"
32
+ }
33
+ }
@@ -0,0 +1,85 @@
1
+ export class AnomalyDetector
2
+ {
3
+ static Main: AnomalyDetector = new AnomalyDetector();
4
+ // configuration
5
+ MAX_STORAGE_SIZE = 10000;
6
+ MAX_STORAGE_PER_IP = 25;
7
+ MIN_AVG_TIME = 200;
8
+ MIN_DATA_REQUIRE_FOR_AVG = 4;
9
+ MIN_AVG_TIME_PER_URL = 400;
10
+ MIN_DATA_REQUIRE_FOR_AVG_PER_URL = 3;
11
+ TIME_FADE_RATE = 0.9;
12
+
13
+ Storage: { [ip: string]: { url: string, time: number }[] } = {};
14
+ Storageـurl: { [ip: string]: { [url: string]: { time: number }[] } } = {};
15
+ Orders: string[] = [];
16
+
17
+ private weightedAverage(array: { time: number }[], fade_rate: number)
18
+ {
19
+ let sum = 0;
20
+ let sum_coef = 0;
21
+ for (let i = 1; i < array.length; i++)
22
+ {
23
+ let diff = array[i].time - array[i - 1].time;
24
+ let coef = Math.pow(fade_rate, (array.length - (i + 1)));
25
+ sum += diff * coef;
26
+ sum_coef += coef;
27
+ }
28
+ return sum / sum_coef;
29
+ }
30
+
31
+ isAnomaly(ip: string, url: string): boolean
32
+ {
33
+ if (!this.Storage[ip])
34
+ {
35
+ this.Storage[ip] = [];
36
+ this.Storageـurl[ip] = {};
37
+ this.Orders.push(ip);
38
+ }
39
+
40
+ if (this.Orders.length > this.MAX_STORAGE_SIZE)
41
+ {
42
+ let index = this.Orders.shift();
43
+ if (index)
44
+ {
45
+ delete this.Storage[index];
46
+ delete this.Storageـurl[index];
47
+ }
48
+ }
49
+
50
+ if (this.Storage[ip].length >= this.MAX_STORAGE_PER_IP)
51
+ {
52
+ let record = this.Storage[ip].shift(); // remove first element
53
+ if (record)
54
+ this.Storageـurl[ip][record.url].shift(); // remove first element of url array
55
+ }
56
+
57
+ this.Storage[ip].push({
58
+ url: url,
59
+ time: +new Date()
60
+ });
61
+
62
+ if (!this.Storageـurl[ip][url])
63
+ this.Storageـurl[ip][url] = [];
64
+ this.Storageـurl[ip][url].push({
65
+ time: +new Date()
66
+ });
67
+
68
+ // check conditions
69
+ // simple
70
+ if (this.Storage[ip].length >= this.MIN_DATA_REQUIRE_FOR_AVG)
71
+ {
72
+ let avg = this.weightedAverage(this.Storage[ip], this.TIME_FADE_RATE);
73
+ if (avg < this.MIN_AVG_TIME)
74
+ return true;
75
+ }
76
+ // by requst url
77
+ if (this.Storageـurl[ip][url].length >= this.MIN_DATA_REQUIRE_FOR_AVG_PER_URL)
78
+ {
79
+ let avg = this.weightedAverage(this.Storageـurl[ip][url], this.TIME_FADE_RATE);
80
+ if (avg < this.MIN_AVG_TIME_PER_URL)
81
+ return true;
82
+ }
83
+ return false;
84
+ }
85
+ }
@@ -0,0 +1,112 @@
1
+ import express, { Router } from 'express';
2
+ import cors from "cors";
3
+ import swaggerUi from 'swagger-ui-express';
4
+ import swaggerJSDoc from 'swagger-jsdoc';
5
+ import { BaseDatabase } from './BaseDatabase';
6
+ import { ILogger } from "namirasoft-log";
7
+
8
+ export abstract class BaseApplication<D extends BaseDatabase>
9
+ {
10
+ private title: string;
11
+ private description: string;
12
+ private version: string;
13
+ private swaggerPath: string;
14
+ public app!: express.Express;
15
+ public database!: D;
16
+ public logger: ILogger;
17
+ protected abstract getDatabase(): D;
18
+ protected abstract getLogger(): ILogger;
19
+ protected abstract getRouter(): Router;
20
+ protected abstract getPort(): number;
21
+ constructor(title: string, description: string, version: string, swaggerPath: string)
22
+ {
23
+ this.title = title;
24
+ this.description = description;
25
+ this.version = version;
26
+ this.swaggerPath = swaggerPath;
27
+ this.logger = this.getLogger();
28
+ }
29
+ start()
30
+ {
31
+ this.startCrashHandler();
32
+ this.startDatabase();
33
+ this.startServer();
34
+ this.startSwagger();
35
+ }
36
+ protected startCrashHandler(): void
37
+ {
38
+ process.on('unhandledRejection', (reason) =>
39
+ {
40
+ if (reason instanceof Error)
41
+ this.logger.onCatchCritical(reason);
42
+ else
43
+ this.logger.critical(reason + "");
44
+ });
45
+ process.on('uncaughtException', (error) =>
46
+ {
47
+ this.logger.onCatchFatal(error);
48
+ });
49
+ }
50
+ protected startDatabase(): void
51
+ {
52
+ this.database = this.getDatabase();
53
+ this.database.init().then(() => this.database.sync(false));
54
+ }
55
+ protected startServer(): void
56
+ {
57
+ this.app = express();
58
+ this.app.use((req, res, next) =>
59
+ {
60
+ let excludes: string[] = [];
61
+ if (excludes.includes(req.path))
62
+ next();
63
+ else
64
+ express.json({ limit: '100kb' })(req, res, next);
65
+ });
66
+ // Express
67
+ this.app.use(express.static('static'));
68
+ // Cors
69
+ this.app.use(cors({ exposedHeaders: '*', }));
70
+ // api routes
71
+ this.app.use('/', this.getRouter());
72
+ // start server
73
+ const port = this.getPort();
74
+ this.app.listen(port, async () =>
75
+ {
76
+ this.logger.info(`Server listening on port ${port}`);
77
+ });
78
+ }
79
+ protected startSwagger(): void
80
+ {
81
+ const joptions = {
82
+ definition: {
83
+ openapi: "3.0.1",
84
+ info: {
85
+ title: this.title,
86
+ description: this.description,
87
+ version: this.version,
88
+ // license: {
89
+ // name: "MIT",
90
+ // url: "https://spdx.org/licenses/MIT.html",
91
+ // },
92
+ // contact: {
93
+ // name: "Amir Abolhasani",
94
+ // url: "https://namirasoft.com",
95
+ // email: "accounts@namirasoft.com",
96
+ // },
97
+ },
98
+ // servers: [
99
+ // {
100
+ // url: "http://localhost:3000",
101
+ // },
102
+ // ],
103
+ },
104
+ apis: ['./src/route/*.ts'],
105
+ };
106
+ const swaggerSpec = swaggerJSDoc(joptions);
107
+ var options = {
108
+ explorer: true
109
+ };
110
+ this.app.use(this.swaggerPath, swaggerUi.serve, swaggerUi.setup(swaggerSpec, options));
111
+ }
112
+ }
@@ -0,0 +1,16 @@
1
+ import * as express from 'express';
2
+ import { BaseDatabase } from './BaseDatabase';
3
+ import { SchemaLike } from 'joi';
4
+ import { AnomalyDetector } from './AnomalyDetector';
5
+ export abstract class BaseController<D extends BaseDatabase, State, Props>
6
+ {
7
+ showLogAtTheBeginning: boolean = false;
8
+ showLogAtTheEnd: boolean = true;
9
+ abstract getAnomaly(): AnomalyDetector | null;
10
+ abstract getBodySchema(): SchemaLike | null;
11
+ abstract getQuerySchema(): SchemaLike | null;
12
+ abstract getState(): State;
13
+ abstract preHandle(req: express.Request, res: express.Response, database: D, props: Props): Promise<void>;
14
+ abstract handle(req: express.Request, res: express.Response, database: D, props: Props): Promise<any>;
15
+ abstract postHandle(req: express.Request, res: express.Response, database: D, props: Props): Promise<void>;
16
+ }
@@ -0,0 +1,5 @@
1
+ export abstract class BaseDatabase
2
+ {
3
+ abstract init(): Promise<void>;
4
+ abstract sync(force: boolean): void;
5
+ }