badmfck-api-server 3.1.7 → 3.1.9

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.
@@ -36,8 +36,6 @@ const badmfck_signal_1 = require("badmfck-signal");
36
36
  const LogService_1 = require("./LogService");
37
37
  const Monitor_1 = require("./monitor/Monitor");
38
38
  const path_1 = __importDefault(require("path"));
39
- const crypto_1 = __importDefault(require("crypto"));
40
- const fs_1 = __importDefault(require("fs"));
41
39
  const express_fileupload_1 = __importDefault(require("express-fileupload"));
42
40
  const os_1 = __importDefault(require("os"));
43
41
  const Liveness_1 = require("./routes/Liveness");
@@ -97,7 +95,7 @@ async function Initializer(services) {
97
95
  exports.Initializer = Initializer;
98
96
  class APIService extends BaseService_1.BaseService {
99
97
  static nextLogID = 0;
100
- version = "3.1.7";
98
+ version = "3.1.9";
101
99
  options;
102
100
  monitor = null;
103
101
  monitorIndexFile;
@@ -113,15 +111,14 @@ class APIService extends BaseService_1.BaseService {
113
111
  const self = "http://localhost:" + this.options.port;
114
112
  if (!this.options.corsHostWhiteList.find(val => val === self))
115
113
  this.options.corsHostWhiteList.push();
116
- if (this.options.monitor && this.options.monitor.length > 0) {
117
- exports.REQ_MONITOR_USERS.listener = async () => this.options.access.monitor ?? this.options.monitor ?? [];
118
- exports.REQ_DOC_USERS.listener = async () => this.options.access.documentation ?? [];
119
- this.monitor = new MonitorService_1.MonitorService();
120
- this.monitor.init();
121
- this.options.endpoints.push(new Monitor_1.Monitor());
122
- }
114
+ exports.REQ_MONITOR_USERS.listener = async () => this.options.access.monitor ?? this.options.monitor ?? [];
115
+ exports.REQ_DOC_USERS.listener = async () => this.options.access.documentation ?? [];
116
+ this.options.endpoints.push(new Monitor_1.Monitor(this.options));
123
117
  this.options.endpoints.push(new Documentation_1.Documentation(this.options));
124
118
  this.options.endpoints.push(new ExternalServiceEndpoint_1.ExternalServiceEndpoint());
119
+ new DocumentService_1.DocumentGenerator(this.options.endpoints);
120
+ this.monitor = new MonitorService_1.MonitorService();
121
+ this.monitor.init();
125
122
  this.options.endpoints.push(new Liveness_1.Liveness(this.started), new Readiness_1.Readiness(this.started));
126
123
  exports.REQ_HTTP_REQUESTS_COUNT.listener = async () => this.requestsCount;
127
124
  }
@@ -336,40 +333,6 @@ class APIService extends BaseService_1.BaseService {
336
333
  }
337
334
  app.use((req, res, next) => {
338
335
  const tme = +new Date();
339
- if (this.monitor && this.options && this.options.monitor) {
340
- if (req.method === "GET") {
341
- let monitorRequest = false;
342
- for (let i of this.options.monitor) {
343
- const hash = crypto_1.default.createHash("sha256").update(i.login + i.password).digest().toString("hex");
344
- if (req.originalUrl.endsWith("/sm-" + hash)) {
345
- monitorRequest = true;
346
- break;
347
- }
348
- }
349
- if (monitorRequest) {
350
- const date = new Date();
351
- try {
352
- if (!this.monitorIndexFile)
353
- this.monitorIndexFile = fs_1.default.readFileSync(path_1.default.resolve(__dirname, "monitor", "index.html"));
354
- res.setHeader("Content-Type", "text/html");
355
- res.setHeader("Content-Length", this.monitorIndexFile.byteLength);
356
- res.status(200).send(this.monitorIndexFile);
357
- }
358
- catch (e) {
359
- this.sendResponse(req.get("Referer") ?? "", res, {
360
- error: {
361
- code: 10002,
362
- message: "Internal server error",
363
- details: `${e}`
364
- },
365
- data: null,
366
- httpStatus: 500
367
- }, tme, req.path);
368
- }
369
- return;
370
- }
371
- }
372
- }
373
336
  this.sendResponse(req.get("Referer") ?? "", res, {
374
337
  error: DefaultErrors_1.default.UNKNOWN_REQUEST,
375
338
  data: null,
@@ -379,7 +342,6 @@ class APIService extends BaseService_1.BaseService {
379
342
  server.listen(this.options.port, () => {
380
343
  (0, LogService_1.logCrit)('${APIService.js}', 'API Service started at: ' + this.options.port + ", with base endpoint:" + this.options.baseEndPoint + ", ver.: " + this.version);
381
344
  });
382
- new DocumentService_1.DocumentGenerator(this.options.endpoints);
383
345
  }
384
346
  async sendResponse(ref, res, data, requestTime, endpoint, log, req) {
385
347
  if (data.blockResponse) {
@@ -37,6 +37,7 @@ export declare const S_LOG: Signal<{
37
37
  }>;
38
38
  export declare const S_LOG_CREATED: Signal<ILogItem>;
39
39
  export declare const S_LOG_CHANGE_LEVEL: Signal<LOG_LEVEL>;
40
+ export declare const REQ_CURRENT_LOG_LEVEL: Req<void, LOG_LEVEL>;
40
41
  export declare const S_LOG_FLUSH: Signal<void>;
41
42
  export declare const S_LOG_ADD_SERVICE_TO_WATCH: Signal<string>;
42
43
  export declare const S_LOG_REMOVE_SERVICE_FROM_WATCH: Signal<string>;
@@ -23,7 +23,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
23
23
  return result;
24
24
  };
25
25
  Object.defineProperty(exports, "__esModule", { value: true });
26
- exports.LogService = exports.REQ_LOG_UNIQUE_SERVICES = exports.REQ_LOG = exports.S_LOG_SET_TEXT_LIMIT = exports.S_LOG_REMOVE_SERVICE_FROM_WATCH = exports.S_LOG_ADD_SERVICE_TO_WATCH = exports.S_LOG_FLUSH = exports.S_LOG_CHANGE_LEVEL = exports.S_LOG_CREATED = exports.S_LOG = exports.logAPI = exports.logDB = exports.logError = exports.logCrit = exports.logWarn = exports.logInfo = exports.getDefaultLogOptions = exports.LOG_LEVEL = void 0;
26
+ exports.LogService = exports.REQ_LOG_UNIQUE_SERVICES = exports.REQ_LOG = exports.S_LOG_SET_TEXT_LIMIT = exports.S_LOG_REMOVE_SERVICE_FROM_WATCH = exports.S_LOG_ADD_SERVICE_TO_WATCH = exports.S_LOG_FLUSH = exports.REQ_CURRENT_LOG_LEVEL = exports.S_LOG_CHANGE_LEVEL = exports.S_LOG_CREATED = exports.S_LOG = exports.logAPI = exports.logDB = exports.logError = exports.logCrit = exports.logWarn = exports.logInfo = exports.getDefaultLogOptions = exports.LOG_LEVEL = void 0;
27
27
  const badmfck_signal_1 = __importStar(require("badmfck-signal"));
28
28
  const BaseService_1 = require("./BaseService");
29
29
  var LOG_LEVEL;
@@ -44,21 +44,34 @@ const getDefaultLogOptions = () => {
44
44
  };
45
45
  };
46
46
  exports.getDefaultLogOptions = getDefaultLogOptions;
47
- const logInfo = (message, ...optional) => { exports.S_LOG.invoke({ level: LOG_LEVEL.INFO, data: [message, optional] }); };
47
+ const logInfo = (message, ...optional) => {
48
+ exports.S_LOG.invoke({ level: LOG_LEVEL.INFO, data: [message, optional] });
49
+ };
48
50
  exports.logInfo = logInfo;
49
- const logWarn = (message, ...optional) => { exports.S_LOG.invoke({ level: LOG_LEVEL.WARN, data: [message, optional] }); };
51
+ const logWarn = (message, ...optional) => {
52
+ exports.S_LOG.invoke({ level: LOG_LEVEL.WARN, data: [message, optional] });
53
+ };
50
54
  exports.logWarn = logWarn;
51
- const logCrit = (message, ...optional) => { exports.S_LOG.invoke({ level: LOG_LEVEL.CRIT, data: [message, optional] }); };
55
+ const logCrit = (message, ...optional) => {
56
+ exports.S_LOG.invoke({ level: LOG_LEVEL.CRIT, data: [message, optional] });
57
+ };
52
58
  exports.logCrit = logCrit;
53
- const logError = (message, ...optional) => { exports.S_LOG.invoke({ level: LOG_LEVEL.ERROR, data: [message, optional] }); };
59
+ const logError = (message, ...optional) => {
60
+ exports.S_LOG.invoke({ level: LOG_LEVEL.ERROR, data: [message, optional] });
61
+ };
54
62
  exports.logError = logError;
55
- const logDB = (message, ...optional) => { exports.S_LOG.invoke({ level: LOG_LEVEL.DB, data: [message, optional] }); };
63
+ const logDB = (message, ...optional) => {
64
+ exports.S_LOG.invoke({ level: LOG_LEVEL.DB, data: [message, optional] });
65
+ };
56
66
  exports.logDB = logDB;
57
- const logAPI = (message, ...optional) => { exports.S_LOG.invoke({ level: LOG_LEVEL.API, data: [message, optional] }); };
67
+ const logAPI = (message, ...optional) => {
68
+ exports.S_LOG.invoke({ level: LOG_LEVEL.API, data: [message, optional] });
69
+ };
58
70
  exports.logAPI = logAPI;
59
71
  exports.S_LOG = new badmfck_signal_1.default();
60
72
  exports.S_LOG_CREATED = new badmfck_signal_1.default();
61
73
  exports.S_LOG_CHANGE_LEVEL = new badmfck_signal_1.default();
74
+ exports.REQ_CURRENT_LOG_LEVEL = new badmfck_signal_1.Req(undefined, "REQ_CURRENT_LOG_LEVEL");
62
75
  exports.S_LOG_FLUSH = new badmfck_signal_1.default();
63
76
  exports.S_LOG_ADD_SERVICE_TO_WATCH = new badmfck_signal_1.default();
64
77
  exports.S_LOG_REMOVE_SERVICE_FROM_WATCH = new badmfck_signal_1.default();
@@ -120,6 +133,7 @@ class LogService extends BaseService_1.BaseService {
120
133
  }
121
134
  });
122
135
  exports.S_LOG_CHANGE_LEVEL.subscribe(l => { this.level = l; });
136
+ exports.REQ_CURRENT_LOG_LEVEL.listener = async () => this.level;
123
137
  exports.S_LOG_FLUSH.subscribe(() => this.log = []);
124
138
  exports.S_LOG.subscribe((log) => {
125
139
  if (log.level < this.level)
@@ -75,7 +75,7 @@ class MysqlAdapter {
75
75
  }
76
76
  this.transactions = this.transactions.filter(i => !removedIDs.includes(i.id));
77
77
  if (this.options.debug && count - this.transactions.length > 0)
78
- console.log("Removed: ", count - this.transactions.length);
78
+ (0, LogService_1.logDB)("Removed: ", count - this.transactions.length);
79
79
  if (Date.now() - this.lastSuccessQueryTime > this.pingInterval) {
80
80
  if (!this.pool)
81
81
  return;
@@ -191,7 +191,7 @@ class MysqlAdapter {
191
191
  trxRequest.queries.push({ sql: "START TRANSACTION", status: "ok" });
192
192
  this.transactions.push(trxRequest);
193
193
  if (this.options.debug)
194
- console.log("Transactions pool: ", this.transactions);
194
+ (0, LogService_1.logDB)("Transactions pool: ", this.transactions);
195
195
  return { data: { transactionId: trxid } };
196
196
  }
197
197
  async tCommit(trxid) {
@@ -369,7 +369,7 @@ class MysqlAdapter {
369
369
  conn.release();
370
370
  conn.removeAllListeners();
371
371
  if (this.options.debug)
372
- console.log("Release connection: ", conn.threadId);
372
+ (0, LogService_1.logDB)("Release connection: ", conn.threadId);
373
373
  }
374
374
  catch (e) {
375
375
  (0, LogService_1.logCrit)("MysqlAdapter", `Can't release connection: ${e}`);
@@ -484,7 +484,7 @@ class MysqlAdapter {
484
484
  async rollbackTransaction(trx, donNotRemove) {
485
485
  let err = null;
486
486
  try {
487
- console.log("Rollback started", trx.conn.threadId);
487
+ (0, LogService_1.logDB)("Rollback started", trx.conn.threadId);
488
488
  await trx.conn.rollback();
489
489
  await trx.conn.commit();
490
490
  trx.conn.removeAllListeners();
@@ -492,7 +492,7 @@ class MysqlAdapter {
492
492
  if (!donNotRemove)
493
493
  this.transactions = this.transactions.filter(i => i.id !== trx.id);
494
494
  if (this.options.debug)
495
- console.log("Rollback complete", trx.conn.threadId);
495
+ (0, LogService_1.logDB)("Rollback complete", trx.conn.threadId);
496
496
  }
497
497
  catch (e) {
498
498
  (0, LogService_1.logCrit)("MysqlAdapter", "Can't rollback transaction", trx.queries);
@@ -502,7 +502,7 @@ class MysqlAdapter {
502
502
  return err;
503
503
  }
504
504
  async finish() {
505
- console.log("Finishing mysql service");
505
+ (0, LogService_1.logInfo)("Finishing mysql service");
506
506
  for (let i of this.transactions)
507
507
  this.rollbackTransaction(i);
508
508
  if (this.pool) {
@@ -18,6 +18,7 @@ class Documentation extends BaseEndpoint_1.BaseEndpoint {
18
18
  super("doc");
19
19
  this.apiServiceOptions = options;
20
20
  this.ignoreInDocumentation = true;
21
+ this.ignoreHttpLogging = true;
21
22
  this.registerEndpoints([{
22
23
  ignoreInDocumentation: true,
23
24
  endpoint: "json",
@@ -1,4 +1,5 @@
1
1
  import { Signal } from "badmfck-signal";
2
+ import { APIServiceOptions } from "../APIService";
2
3
  import { BaseEndpoint } from "../BaseEndpoint";
3
4
  import { HTTPRequestVO, TransferPacketVO } from "../structures/Interfaces";
4
5
  export interface IUserAction {
@@ -14,13 +15,17 @@ export declare const S_MONITOR_REGISTRATE_ACTION: Signal<IUserAction>;
14
15
  export declare class Monitor extends BaseEndpoint {
15
16
  ignoreHttpLogging: boolean;
16
17
  ignoreInDocumentation: boolean;
18
+ indexHtmlFile: string | null;
19
+ apiServiceOptions: APIServiceOptions;
17
20
  users: Map<string, IStatObject>;
18
- constructor();
21
+ constructor(options: APIServiceOptions);
22
+ html(req: HTTPRequestVO): Promise<TransferPacketVO>;
19
23
  controllers(req: HTTPRequestVO): Promise<TransferPacketVO>;
24
+ changeLogLevel(req: HTTPRequestVO): Promise<TransferPacketVO>;
20
25
  logs(req: HTTPRequestVO): Promise<TransferPacketVO>;
21
26
  netlog(req: HTTPRequestVO): Promise<TransferPacketVO>;
22
27
  metrics(req: HTTPRequestVO): Promise<TransferPacketVO>;
23
28
  serverStat(req: HTTPRequestVO): Promise<TransferPacketVO>;
24
- checkAuthentication(req: HTTPRequestVO): Promise<boolean>;
29
+ checkAuthentication(req: HTTPRequestVO): Promise<void>;
25
30
  }
26
31
  export {};
@@ -12,25 +12,81 @@ const crypto_1 = __importDefault(require("crypto"));
12
12
  const os_1 = __importDefault(require("os"));
13
13
  const DefaultErrors_1 = __importDefault(require("../structures/DefaultErrors"));
14
14
  const MonitorService_1 = require("../MonitorService");
15
+ const fs_1 = __importDefault(require("fs"));
16
+ const path_1 = __importDefault(require("path"));
15
17
  exports.S_MONITOR_REGISTRATE_ACTION = new badmfck_signal_1.Signal();
18
+ const logMap = {
19
+ ALL: 10,
20
+ API: 19,
21
+ INFO: 20,
22
+ DB: 25,
23
+ WARN: 30,
24
+ ERROR: 40,
25
+ CRIT: 50,
26
+ };
16
27
  class Monitor extends BaseEndpoint_1.BaseEndpoint {
17
28
  ignoreHttpLogging = true;
18
29
  ignoreInDocumentation = true;
30
+ indexHtmlFile = null;
31
+ apiServiceOptions;
19
32
  users = new Map();
20
- constructor() {
21
- super("--sys-monitor");
33
+ constructor(options) {
34
+ super("sm");
35
+ this.apiServiceOptions = options;
22
36
  this.registerEndpoints([
37
+ { ignoreInterceptor: true, endpoint: "html", handler: this.html },
23
38
  { ignoreInterceptor: true, endpoint: "log", handler: this.logs },
24
39
  { ignoreInterceptor: true, endpoint: "netlog", handler: this.netlog },
25
40
  { ignoreInterceptor: true, endpoint: "metrics", handler: this.metrics },
26
41
  { ignoreInterceptor: true, endpoint: "server", handler: this.serverStat },
27
- { ignoreInterceptor: true, endpoint: "controllers", handler: this.controllers }
42
+ { ignoreInterceptor: true, endpoint: "controllers", handler: this.controllers },
43
+ { ignoreInterceptor: true, endpoint: "changeLogLevel", handler: this.changeLogLevel, validationModel: {
44
+ level: Object.keys(logMap).join(",")
45
+ } }
28
46
  ]);
29
47
  }
48
+ async html(req) {
49
+ if (!this.indexHtmlFile) {
50
+ this.indexHtmlFile = fs_1.default.readFileSync(path_1.default.resolve(__dirname, "index.html")).toString("utf-8");
51
+ let bend = this.apiServiceOptions.baseEndPoint;
52
+ if (!bend.endsWith("/"))
53
+ bend += "/";
54
+ let end = this.endpoint;
55
+ if (!end.endsWith("/"))
56
+ end += "/";
57
+ if (end.startsWith("/"))
58
+ end = end.substring(1);
59
+ const endpoint = bend + end + "json";
60
+ this.indexHtmlFile = this.indexHtmlFile.replace(/{{host}}/g, endpoint);
61
+ let projectName = this.apiServiceOptions.projectName;
62
+ if (!projectName)
63
+ projectName = "API Server";
64
+ projectName += " - Monitoring";
65
+ if (this.apiServiceOptions.appVersion)
66
+ projectName += " (v.:" + this.apiServiceOptions.appVersion + ")";
67
+ this.indexHtmlFile = this.indexHtmlFile.replace(/{{title}}/g, projectName);
68
+ }
69
+ return {
70
+ rawResponse: true,
71
+ data: this.indexHtmlFile,
72
+ headers: {
73
+ "Content-Type": "text/html",
74
+ "Content-Length": this.indexHtmlFile.length.toString()
75
+ }
76
+ };
77
+ }
30
78
  async controllers(req) {
31
79
  this.checkAuthentication(req);
32
80
  return {};
33
81
  }
82
+ async changeLogLevel(req) {
83
+ this.checkAuthentication(req);
84
+ const val = logMap[req.data.level];
85
+ if (!val)
86
+ throw { ...DefaultErrors_1.default.BAD_REQUEST, details: "bad log level" };
87
+ LogService_1.S_LOG_CHANGE_LEVEL.invoke(req.data.level);
88
+ return { data: (await LogService_1.REQ_CURRENT_LOG_LEVEL.request()) };
89
+ }
34
90
  async logs(req) {
35
91
  this.checkAuthentication(req);
36
92
  const services = await LogService_1.REQ_LOG_UNIQUE_SERVICES.request();
@@ -65,23 +121,21 @@ class Monitor extends BaseEndpoint_1.BaseEndpoint {
65
121
  }
66
122
  async checkAuthentication(req) {
67
123
  const users = await APIService_1.REQ_MONITOR_USERS.request();
68
- const header = req.headers['authorization'];
124
+ if (!users || users.length == 0)
125
+ throw { ...DefaultErrors_1.default.UNAUTHORIZED, details: "No users found for documentation access" };
126
+ let header = req.headers['authorization'];
69
127
  if (!header)
70
128
  throw { ...DefaultErrors_1.default.UNAUTHORIZED, details: "No authorization header found" };
129
+ header = header.split(" ").pop() ?? "";
130
+ if (!header || header.length < 32)
131
+ throw { ...DefaultErrors_1.default.UNAUTHORIZED, details: "Wrong authorization header" };
71
132
  for (let i of users) {
72
- let hashStr = "";
73
- hashStr += req.endpoint;
74
- hashStr += JSON.stringify(i);
75
- hashStr += JSON.stringify(req.method.toUpperCase());
76
- hashStr += JSON.stringify(req.data ?? {});
77
- hashStr += JSON.stringify(req.params ?? {});
78
- let token = null;
79
- token = "sha256 " + crypto_1.default.createHash('sha256').update(hashStr).digest('hex');
80
- if (token == header) {
81
- return true;
133
+ const hash = crypto_1.default.createHash("sha256").update(i.login + ":" + i.password).digest("hex");
134
+ if (hash === header) {
135
+ return;
82
136
  }
83
137
  }
84
- throw { ...DefaultErrors_1.default.UNAUTHORIZED, details: "Invalid token" };
138
+ throw { ...DefaultErrors_1.default.UNAUTHORIZED, details: "Invalid user" };
85
139
  }
86
140
  }
87
141
  exports.Monitor = Monitor;