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.
package/src/BaseTable.ts CHANGED
@@ -1,151 +1,151 @@
1
- import { ArraySchema, BaseTypeSchema, BaseVariableSchema, ObjectSchema, VariableType } from "namirasoft-schema";
2
- import { BaseDatabase } from "./BaseDatabase";
3
- import { ErrorOperation, BaseUUID, NamingConvention, BaseMetaColumn, TimeOperation } from "namirasoft-core";
4
- import { BaseTableColumnOptions } from "./BaseTableColumnOptions";
5
-
6
- export abstract class BaseTable<D extends BaseDatabase, ModelColumnOption extends BaseTableColumnOptions>
7
- {
8
- database: D;
9
- uuid: BaseUUID;
10
- constructor(database: D)
11
- {
12
- this.database = database;
13
- this.uuid = new BaseUUID(this.getShortName());
14
- }
15
- public abstract getName(): string;
16
- public abstract getShortName(): string;
17
- public getSecureColumns(): string[]
18
- {
19
- let columns: string[] = [];
20
- this.forEachColumn((name, column: ModelColumnOption) =>
21
- {
22
- if (column.secure)
23
- columns.push(name);
24
- });
25
- return columns;
26
- }
27
- public getReadOnlyColumns(): string[]
28
- {
29
- let columns: string[] = [];
30
- this.forEachColumn((name, column: ModelColumnOption) =>
31
- {
32
- if (column.read_only)
33
- columns.push(name);
34
- });
35
- return columns;
36
- }
37
- public abstract getColumnOption(name: string): ModelColumnOption;
38
- public abstract forEachColumn(handler: (name: string, column: ModelColumnOption) => void): void;
39
- public abstract getColumn(name: string): BaseMetaColumn;
40
- public getColumns(secure: boolean | null = false, read_only: boolean | null = null, filter?: any): string[]
41
- {
42
- let columns_secure: string[] = this.getSecureColumns();
43
- let columns_read_only: string[] = this.getReadOnlyColumns();
44
- let columns: string[] = [];
45
- this.forEachColumn((name, element) =>
46
- {
47
- let keys: string[] = [];
48
- if (filter)
49
- keys = Object.keys(filter);
50
- if (!filter || keys.length == 0 || keys.every(key => filter[key] == (element as any)[key]))
51
- columns.push(name)
52
- });
53
- if (secure !== null)
54
- columns = columns.filter(name => columns_secure.includes(name) == secure);
55
- if (read_only !== null)
56
- columns = columns.filter(name => columns_read_only.includes(name) == read_only);
57
- return columns;
58
- }
59
- public checkColumn(column: string, secure: boolean | null, read_only: boolean | null)
60
- {
61
- let columns: string[] = this.getColumns(secure, read_only)
62
- if (!columns.includes(column))
63
- ErrorOperation.throwHTTP(404, `Column '${column}' not found`);
64
- }
65
- public checkValue(column_name: string, value: string)
66
- {
67
- let c = this.getColumn(column_name);
68
- if (c.type.toLowerCase() === VariableType.Date.toLowerCase())
69
- if (!TimeOperation.isValidDate(value))
70
- throw ErrorOperation.getHTTP(400, `Invalid value for Date: ${value}`);
71
- if (c.type.toLowerCase() === VariableType.DateTime.toLowerCase())
72
- if (!TimeOperation.isValidDateTime(value))
73
- throw ErrorOperation.getHTTP(400, `Invalid value for DateTime: ${value}`);
74
- if (c.type.toLowerCase() === VariableType.Time.toLowerCase())
75
- if (!TimeOperation.isValidTime(value))
76
- throw ErrorOperation.getHTTP(400, `Invalid value for Time: ${value}`);
77
- }
78
- public getRealColumnName(column: string): string
79
- {
80
- return column;
81
- }
82
- public secure(obj: any)
83
- {
84
- if (obj.dataValues)
85
- obj = obj.dataValues;
86
- let secureColumns: string[] = this.getSecureColumns();
87
- secureColumns.forEach(col => delete obj[col]);
88
- return obj;
89
- }
90
- public getArraySchema(require: boolean, name?: string): ArraySchema
91
- {
92
- let ans = this.getSchema(require, name);
93
- return new ArraySchema(require, [ans]);
94
- }
95
- public getSchema(require: boolean, name?: string): ObjectSchema
96
- {
97
- if (!name)
98
- name = NamingConvention.lower_case_underscore.convert(this.getName(), NamingConvention.Pascal_Case);
99
- let columns_secure: string[] = this.getSecureColumns();
100
- let columns_read_only: string[] = this.getReadOnlyColumns();
101
- let ans = new ObjectSchema(name, require, null);
102
- this.forEachColumn((name, element) =>
103
- {
104
- if (!columns_secure.includes(name))
105
- ans.addField(this.getVariableSchema(name, element, columns_read_only.includes(name)));
106
- });
107
- return ans;
108
- }
109
- private getVariableSchema(name: string, element: ModelColumnOption, read_only: boolean): BaseVariableSchema
110
- {
111
- let schema = this.getTypeSchema(element);
112
- schema.read_only = read_only;
113
- let es = this.getExamples();
114
- schema.example = es[name] ?? "";
115
- return new BaseVariableSchema(name, schema);
116
- }
117
- protected abstract getTypeSchema(element: ModelColumnOption): BaseTypeSchema;
118
- protected getExamples(): { [name: string]: string }
119
- {
120
- return {};
121
- }
122
- public getSchemaNames(): string[]
123
- {
124
- return [];
125
- }
126
- public getSchemaByName(require: boolean, name?: string): ObjectSchema
127
- {
128
- let ans = this.getSchema(require, name);
129
- if (name)
130
- {
131
- let names = this.getSchemaNames();
132
- if (!names.includes(name))
133
- throw new Error("Wrong schema name was provided: " + name);
134
- this.setSchemaByName(ans);
135
- }
136
- return ans;
137
- }
138
- public getArraySchemaByName(require: boolean, name?: string): ArraySchema
139
- {
140
- let ans = this.getSchemaByName(require, name);
141
- return new ArraySchema(require, [ans]);
142
- }
143
- protected setSchemaByName(_: ObjectSchema): void
144
- {
145
- }
146
- public getNotFoundError(conditions: any | null)
147
- {
148
- let name = NamingConvention.lower_case_underscore.convert(this.getName(), NamingConvention.Pascal_Case);
149
- return ErrorOperation.getHTTP(404, "Could not find " + name + " for " + JSON.stringify(conditions));
150
- }
1
+ import { BaseMetaColumn, BaseUUID, ErrorOperation, NamingConvention, TimeOperation } from "namirasoft-core";
2
+ import { ArraySchema, BaseTypeSchema, BaseVariableSchema, ObjectSchema, VariableType } from "namirasoft-schema";
3
+ import { BaseDatabase } from "./BaseDatabase";
4
+ import { BaseTableColumnOptions } from "./BaseTableColumnOptions";
5
+
6
+ export abstract class BaseTable<D extends BaseDatabase, ModelColumnOption extends BaseTableColumnOptions>
7
+ {
8
+ database: D;
9
+ uuid: BaseUUID;
10
+ constructor(database: D)
11
+ {
12
+ this.database = database;
13
+ this.uuid = new BaseUUID(this.getShortName());
14
+ }
15
+ public abstract getName(): string;
16
+ public abstract getShortName(): string;
17
+ public getSecureColumns(): string[]
18
+ {
19
+ let columns: string[] = [];
20
+ this.forEachColumn((name, column: ModelColumnOption) =>
21
+ {
22
+ if (column.secure)
23
+ columns.push(name);
24
+ });
25
+ return columns;
26
+ }
27
+ public getReadOnlyColumns(): string[]
28
+ {
29
+ let columns: string[] = [];
30
+ this.forEachColumn((name, column: ModelColumnOption) =>
31
+ {
32
+ if (column.read_only)
33
+ columns.push(name);
34
+ });
35
+ return columns;
36
+ }
37
+ public abstract getColumnOption(name: string): ModelColumnOption;
38
+ public abstract forEachColumn(handler: (name: string, column: ModelColumnOption) => void): void;
39
+ public abstract getColumn(name: string): BaseMetaColumn;
40
+ public getColumns(secure: boolean | null = false, read_only: boolean | null = null, filter?: any): string[]
41
+ {
42
+ let columns_secure: string[] = this.getSecureColumns();
43
+ let columns_read_only: string[] = this.getReadOnlyColumns();
44
+ let columns: string[] = [];
45
+ this.forEachColumn((name, element) =>
46
+ {
47
+ let keys: string[] = [];
48
+ if (filter)
49
+ keys = Object.keys(filter);
50
+ if (!filter || keys.length == 0 || keys.every(key => filter[key] == (element as any)[key]))
51
+ columns.push(name)
52
+ });
53
+ if (secure !== null)
54
+ columns = columns.filter(name => columns_secure.includes(name) == secure);
55
+ if (read_only !== null)
56
+ columns = columns.filter(name => columns_read_only.includes(name) == read_only);
57
+ return columns;
58
+ }
59
+ public checkColumn(column: string, secure: boolean | null, read_only: boolean | null)
60
+ {
61
+ let columns: string[] = this.getColumns(secure, read_only)
62
+ if (!columns.includes(column))
63
+ ErrorOperation.throwHTTP(404, `Column '${column}' not found`);
64
+ }
65
+ public checkValue(column_name: string, value: string)
66
+ {
67
+ let c = this.getColumn(column_name);
68
+ if (c.type.toLowerCase() === VariableType.Date.toLowerCase())
69
+ if (!TimeOperation.isValidDate(value))
70
+ throw ErrorOperation.getHTTP(400, `Invalid value for Date: ${value}`);
71
+ if (c.type.toLowerCase() === VariableType.DateTime.toLowerCase())
72
+ if (!TimeOperation.isValidDateTime(value))
73
+ throw ErrorOperation.getHTTP(400, `Invalid value for DateTime: ${value}`);
74
+ if (c.type.toLowerCase() === VariableType.Time.toLowerCase())
75
+ if (!TimeOperation.isValidTime(value))
76
+ throw ErrorOperation.getHTTP(400, `Invalid value for Time: ${value}`);
77
+ }
78
+ public getRealColumnName(column: string): string
79
+ {
80
+ return column;
81
+ }
82
+ public secure(obj: any)
83
+ {
84
+ if (obj.dataValues)
85
+ obj = obj.dataValues;
86
+ let secureColumns: string[] = this.getSecureColumns();
87
+ secureColumns.forEach(col => delete obj[col]);
88
+ return obj;
89
+ }
90
+ public getArraySchema(require: boolean, name?: string): ArraySchema
91
+ {
92
+ let ans = this.getSchema(require, name);
93
+ return new ArraySchema(require, [ans]);
94
+ }
95
+ public getSchema(require: boolean, name?: string): ObjectSchema
96
+ {
97
+ if (!name)
98
+ name = NamingConvention.lower_case_underscore.convert(this.getName(), NamingConvention.Pascal_Case);
99
+ let columns_secure: string[] = this.getSecureColumns();
100
+ let columns_read_only: string[] = this.getReadOnlyColumns();
101
+ let ans = new ObjectSchema(name, require, null);
102
+ this.forEachColumn((name, element) =>
103
+ {
104
+ if (!columns_secure.includes(name))
105
+ ans.addField(this.getVariableSchema(name, element, columns_read_only.includes(name)));
106
+ });
107
+ return ans;
108
+ }
109
+ private getVariableSchema(name: string, element: ModelColumnOption, read_only: boolean): BaseVariableSchema
110
+ {
111
+ let schema = this.getTypeSchema(name, element);
112
+ schema.read_only = read_only;
113
+ let es = this.getExamples();
114
+ schema.example = es[name] ?? "";
115
+ return new BaseVariableSchema(name, schema);
116
+ }
117
+ protected abstract getTypeSchema(name: string, element: ModelColumnOption): BaseTypeSchema;
118
+ protected getExamples(): { [name: string]: string }
119
+ {
120
+ return {};
121
+ }
122
+ public getSchemaNames(): string[]
123
+ {
124
+ return [];
125
+ }
126
+ public getSchemaByName(require: boolean, name?: string): ObjectSchema
127
+ {
128
+ let ans = this.getSchema(require, name);
129
+ if (name)
130
+ {
131
+ let names = this.getSchemaNames();
132
+ if (!names.includes(name))
133
+ throw new Error("Wrong schema name was provided: " + name);
134
+ this.setSchemaByName(ans);
135
+ }
136
+ return ans;
137
+ }
138
+ public getArraySchemaByName(require: boolean, name?: string): ArraySchema
139
+ {
140
+ let ans = this.getSchemaByName(require, name);
141
+ return new ArraySchema(require, [ans]);
142
+ }
143
+ protected setSchemaByName(_: ObjectSchema): void
144
+ {
145
+ }
146
+ public getNotFoundError(conditions: any | null)
147
+ {
148
+ let name = NamingConvention.lower_case_underscore.convert(this.getName(), NamingConvention.Pascal_Case);
149
+ return ErrorOperation.getHTTP(404, "Could not find " + name + " for " + JSON.stringify(conditions));
150
+ }
151
151
  }
@@ -1,9 +1,9 @@
1
- export interface BaseTableColumnOptions
2
- {
3
- secure?: boolean;
4
- read_only?: boolean;
5
- searchable?: boolean;
6
- tags?: {
7
- type?: "BaseTypeSchema" | "BaseTypeSchema[]" | "BaseVariableSchema" | "BaseVariableSchema[]"
8
- }
1
+ export interface BaseTableColumnOptions
2
+ {
3
+ secure?: boolean;
4
+ read_only?: boolean;
5
+ searchable?: boolean;
6
+ tags?: {
7
+ type?: "BaseTypeSchema" | "BaseTypeSchema[]" | "BaseVariableSchema" | "BaseVariableSchema[]"
8
+ }
9
9
  };
@@ -0,0 +1,35 @@
1
+ import { BaseApplication } from './BaseApplication';
2
+ import { IDatabase } from './IDatabase';
3
+
4
+ export type BaseWorkerInfoType =
5
+ {
6
+ name: string,
7
+ }
8
+
9
+ export abstract class BaseWorker<D extends { [name: string]: IDatabase }>
10
+ {
11
+ protected log: {
12
+ enabled: boolean;
13
+ onStarted: boolean;
14
+ onFinished: boolean;
15
+ } = {
16
+ enabled: true,
17
+ onStarted: true,
18
+ onFinished: true
19
+ };
20
+ protected app: BaseApplication<D>;
21
+ protected info!: BaseWorkerInfoType;
22
+
23
+ constructor(app: BaseApplication<D>)
24
+ {
25
+ this.app = app;
26
+ this.start = this.start.bind(this);
27
+ this.stop = this.stop.bind(this);
28
+
29
+ this.info = this.getInfo();
30
+ }
31
+
32
+ abstract getInfo(): BaseWorkerInfoType;
33
+ abstract start(): Promise<void>;
34
+ abstract stop(): Promise<void>;
35
+ }
@@ -1,33 +1,33 @@
1
- import { ExecException, exec, execSync } from 'child_process';
2
- import { ConsoleOperation } from 'namirasoft-core';
3
- export class CommandOperation
4
- {
5
- static exec(command: string, cwd: string | undefined)
6
- {
7
- exec(command, { cwd }, (error: ExecException | null, stdout: string, stderr: string) =>
8
- {
9
- if (error)
10
- {
11
- ConsoleOperation.error(`error: ${error.message}`);
12
- return;
13
- }
14
- if (stderr)
15
- {
16
- ConsoleOperation.error(`stderr: ${stderr}`);
17
- return;
18
- }
19
- ConsoleOperation.log(`stdout:\n${stdout}`);
20
- });
21
- }
22
- static execSync(command: string, cwd: string | undefined)
23
- {
24
- try
25
- {
26
- return execSync(command, { cwd, encoding: 'utf-8' });
27
- } catch (error: any)
28
- {
29
- ConsoleOperation.error(error.stdout);
30
- throw error;
31
- }
32
- }
1
+ import { ExecException, exec, execSync } from 'child_process';
2
+ import { ConsoleOperation } from 'namirasoft-core';
3
+ export class CommandOperation
4
+ {
5
+ static exec(command: string, cwd: string | undefined)
6
+ {
7
+ exec(command, { cwd }, (error: ExecException | null, stdout: string, stderr: string) =>
8
+ {
9
+ if (error)
10
+ {
11
+ ConsoleOperation.error(`error: ${error.message}`);
12
+ return;
13
+ }
14
+ if (stderr)
15
+ {
16
+ ConsoleOperation.error(`stderr: ${stderr}`);
17
+ return;
18
+ }
19
+ ConsoleOperation.log(`stdout:\n${stdout}`);
20
+ });
21
+ }
22
+ static execSync(command: string, cwd: string | undefined)
23
+ {
24
+ try
25
+ {
26
+ return execSync(command, { cwd, encoding: 'utf-8' });
27
+ } catch (error: any)
28
+ {
29
+ ConsoleOperation.error(error.stdout);
30
+ throw error;
31
+ }
32
+ }
33
33
  }
@@ -1,41 +1,41 @@
1
- import * as crypto from 'node:crypto';
2
-
3
- export class EncryptionOperation
4
- {
5
- private static encrypt<T>(algorithm: string, secret: string, message: T): string
6
- {
7
- if (secret.length != 32)
8
- throw new Error("Secret length must be exactly 32");
9
- const secretBytes = Buffer.from(secret);
10
- const iv = crypto.randomBytes(16);
11
- const cipher = crypto.createCipheriv(algorithm, secretBytes, iv);
12
- const encrypted = Buffer.concat([cipher.update(JSON.stringify(message), 'utf8'), cipher.final()]);
13
- const authTag = (cipher as any).getAuthTag();
14
- const ivHex = iv.toString('hex');
15
- const authTagHex = authTag.toString('hex');
16
- const encryptedHex = encrypted.toString('hex');
17
- return [ivHex, authTagHex, encryptedHex].join(";");
18
- }
19
- private static decrypt<T>(algorithm: string, secret: string, message: string): T
20
- {
21
- const [ivHex, authTagHex, encryptedHex] = message.split(';');
22
- const iv = Buffer.from(ivHex, 'hex');
23
- const authTag = Buffer.from(authTagHex, 'hex');
24
- const encrypte = Buffer.from(encryptedHex, 'hex');
25
-
26
- const decipher = crypto.createDecipheriv(algorithm, secret, iv);
27
- (decipher as any).setAuthTag(authTag);
28
-
29
- let decrypted = decipher.update(encrypte);
30
- decrypted = Buffer.concat([decrypted, decipher.final()]);
31
- return JSON.parse(decrypted.toString());
32
- }
33
- static AES256GCMEncrypt<T>(secret: string, message: T): string
34
- {
35
- return EncryptionOperation.encrypt("aes-256-gcm", secret, message);
36
- }
37
- static AES256GCMDecrypt<T>(secret: string, message: string): T
38
- {
39
- return EncryptionOperation.decrypt("aes-256-gcm", secret, message);
40
- }
1
+ import * as crypto from 'node:crypto';
2
+
3
+ export class EncryptionOperation
4
+ {
5
+ private static encrypt<T>(algorithm: string, secret: string, message: T): string
6
+ {
7
+ if (secret.length != 32)
8
+ throw new Error("Secret length must be exactly 32");
9
+ const secretBytes = Buffer.from(secret);
10
+ const iv = crypto.randomBytes(16);
11
+ const cipher = crypto.createCipheriv(algorithm, secretBytes, iv);
12
+ const encrypted = Buffer.concat([cipher.update(JSON.stringify(message), 'utf8'), cipher.final()]);
13
+ const authTag = (cipher as any).getAuthTag();
14
+ const ivHex = iv.toString('hex');
15
+ const authTagHex = authTag.toString('hex');
16
+ const encryptedHex = encrypted.toString('hex');
17
+ return [ivHex, authTagHex, encryptedHex].join(";");
18
+ }
19
+ private static decrypt<T>(algorithm: string, secret: string, message: string): T
20
+ {
21
+ const [ivHex, authTagHex, encryptedHex] = message.split(';');
22
+ const iv = Buffer.from(ivHex, 'hex');
23
+ const authTag = Buffer.from(authTagHex, 'hex');
24
+ const encrypte = Buffer.from(encryptedHex, 'hex');
25
+
26
+ const decipher = crypto.createDecipheriv(algorithm, secret, iv);
27
+ (decipher as any).setAuthTag(authTag);
28
+
29
+ let decrypted = decipher.update(encrypte);
30
+ decrypted = Buffer.concat([decrypted, decipher.final()]);
31
+ return JSON.parse(decrypted.toString());
32
+ }
33
+ static AES256GCMEncrypt<T>(secret: string, message: T): string
34
+ {
35
+ return EncryptionOperation.encrypt("aes-256-gcm", secret, message);
36
+ }
37
+ static AES256GCMDecrypt<T>(secret: string, message: string): T
38
+ {
39
+ return EncryptionOperation.decrypt("aes-256-gcm", secret, message);
40
+ }
41
41
  }
@@ -1,23 +1,23 @@
1
- import smtpTransport from 'nodemailer-smtp-transport';
2
- import { BaseEmailService } from './BaseEmailService';
3
-
4
- export class GmailService extends BaseEmailService
5
- {
6
- password: string;
7
- constructor(username: string, password: string)
8
- {
9
- super(username);
10
- this.password = password;
11
- }
12
- protected override getTransform(): any
13
- {
14
- return smtpTransport({
15
- service: 'gmail',
16
- host: 'smtp.gmail.com',
17
- auth: {
18
- user: this.username,
19
- pass: this.password
20
- }
21
- });
22
- }
1
+ import smtpTransport from 'nodemailer-smtp-transport';
2
+ import { BaseEmailService } from './BaseEmailService';
3
+
4
+ export class GmailService extends BaseEmailService
5
+ {
6
+ password: string;
7
+ constructor(username: string, password: string)
8
+ {
9
+ super(username);
10
+ this.password = password;
11
+ }
12
+ protected override getTransform(): any
13
+ {
14
+ return smtpTransport({
15
+ service: 'gmail',
16
+ host: 'smtp.gmail.com',
17
+ auth: {
18
+ user: this.username,
19
+ pass: this.password
20
+ }
21
+ });
22
+ }
23
23
  }
package/src/IDatabase.ts CHANGED
@@ -1,13 +1,13 @@
1
- export interface IDatabase
2
- {
3
- getType(): string;
4
- getName(): string;
5
- init(): Promise<void>;
6
- connect(): Promise<void>;
7
- prepare(): Promise<void>;
8
- sync(force: boolean): Promise<void>;
9
- seedBefore(): Promise<void>;
10
- seedAfter(): Promise<void>;
11
- isHealthy(): Promise<boolean>;
12
- close(): Promise<void>;
1
+ export interface IDatabase
2
+ {
3
+ getType(): string;
4
+ getName(): string;
5
+ init(): Promise<void>;
6
+ connect(): Promise<void>;
7
+ prepare(): Promise<void>;
8
+ sync(force: boolean): Promise<void>;
9
+ seedBefore(): Promise<void>;
10
+ seedAfter(): Promise<void>;
11
+ isHealthy(): Promise<boolean>;
12
+ close(): Promise<void>;
13
13
  }
@@ -1,39 +1,39 @@
1
- import * as express from 'express';
2
- import { getClientIp } from '@supercharge/request-ip';
3
- import { RequestHeaderService } from './RequestHeaderService';
4
- import { ErrorOperation } from 'namirasoft-core';
5
-
6
- export class IPOperation
7
- {
8
- static ERROR_MESSAGE_IP_IS_NOT_WHITELIST = `Ip does not match the whitelisted IP address: {0}`;
9
- static getIP(req: express.Request): string
10
- {
11
- let ip = new RequestHeaderService(req, 'cf-connecting-ip').getString();
12
- if (!ip)
13
- ip = new RequestHeaderService(req, 'x-forwarded-for').getString();
14
- if (!ip)
15
- ip = getClientIp(req) ?? "";
16
- ip = ip.split(',')[0];
17
- return ip;
18
- }
19
- static isWhitelist(req: express.Request, whitelist: string[])
20
- {
21
- let ip = this.getIP(req);
22
- if (!whitelist)
23
- return true;
24
- if (whitelist.length === 0)
25
- return true;
26
- if (whitelist.includes(ip))
27
- return true;
28
- for (let item of whitelist)
29
- if (ip.substring(0, item.length) === item)
30
- return true;
31
- return false;
32
- }
33
- static checkWhitelist(req: express.Request, whitelist: string[])
34
- {
35
- let valid = this.isWhitelist(req, whitelist);
36
- if (!valid)
37
- ErrorOperation.throwHTTP(403, this.ERROR_MESSAGE_IP_IS_NOT_WHITELIST, this.getIP(req));
38
- }
1
+ import * as express from 'express';
2
+ import { getClientIp } from '@supercharge/request-ip';
3
+ import { RequestHeaderService } from './RequestHeaderService';
4
+ import { ErrorOperation } from 'namirasoft-core';
5
+
6
+ export class IPOperation
7
+ {
8
+ static ERROR_MESSAGE_IP_IS_NOT_WHITELIST = `Ip does not match the whitelisted IP address: {0}`;
9
+ static getIP(req: express.Request): string
10
+ {
11
+ let ip = new RequestHeaderService(req, 'cf-connecting-ip').getString();
12
+ if (!ip)
13
+ ip = new RequestHeaderService(req, 'x-forwarded-for').getString();
14
+ if (!ip)
15
+ ip = getClientIp(req) ?? "";
16
+ ip = ip.split(',')[0];
17
+ return ip;
18
+ }
19
+ static isWhitelist(req: express.Request, whitelist: string[])
20
+ {
21
+ let ip = this.getIP(req);
22
+ if (!whitelist)
23
+ return true;
24
+ if (whitelist.length === 0)
25
+ return true;
26
+ if (whitelist.includes(ip))
27
+ return true;
28
+ for (let item of whitelist)
29
+ if (ip.substring(0, item.length) === item)
30
+ return true;
31
+ return false;
32
+ }
33
+ static checkWhitelist(req: express.Request, whitelist: string[])
34
+ {
35
+ let valid = this.isWhitelist(req, whitelist);
36
+ if (!valid)
37
+ ErrorOperation.throwHTTP(403, this.ERROR_MESSAGE_IP_IS_NOT_WHITELIST, this.getIP(req));
38
+ }
39
39
  }