badmfck-api-server 4.0.73 → 4.0.75

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.
@@ -95,7 +95,7 @@ async function Initializer(services) {
95
95
  }
96
96
  exports.Initializer = Initializer;
97
97
  class APIService extends BaseService_1.BaseService {
98
- version = "4.0.72";
98
+ version = "4.0.75";
99
99
  options;
100
100
  monitor = null;
101
101
  started = new Date();
@@ -13,6 +13,7 @@ exports.REQ_MICROSERVICE_CALL = new badmfck_signal_1.Req(undefined, "REQ_MICROSE
13
13
  class MicroserviceClient extends BaseService_1.BaseService {
14
14
  static #clients = new Map();
15
15
  static #listener = false;
16
+ static #nextID = 1;
16
17
  options;
17
18
  constructor(opt) {
18
19
  super("MicroserviceClient");
@@ -34,31 +35,32 @@ class MicroserviceClient extends BaseService_1.BaseService {
34
35
  }
35
36
  async requestMicroserviceCall(req) {
36
37
  const url = this.options.host + "/__ms_host_control/receiver";
37
- const ts = (+new Date()).toString();
38
- const nonce = crypto_1.default.randomBytes(16).toString("hex");
38
+ const ts = Date.now().toString();
39
+ const nonce = crypto_1.default.randomBytes(12).toString("hex");
39
40
  const headers = {
40
41
  "Content-Type": "application/json",
41
42
  "x-microservice-id": this.options.id,
42
43
  "x-microservice-ts": ts,
43
44
  "x-microservice-nonce": nonce
44
45
  };
45
- const data = Buffer.from(JSON.stringify(req), "utf8");
46
46
  const secret = Buffer.from(this.options.securityKey, "base64");
47
- const salt = crypto_1.default.createHash("sha256").update(nonce + ts).digest();
48
- const key = crypto_1.default.pbkdf2Sync(secret, salt, 100, 32, "sha256");
49
- const iv = crypto_1.default.pbkdf2Sync(secret, salt, 100, 16, "sha256");
50
- const aad = Buffer.from(ts + "." + nonce + "." + this.options.id + "." + this.options.password, "utf8");
47
+ const hash = crypto_1.default.createHash("sha256").update(nonce + ts + this.options.securityKey).digest();
48
+ const key = secret;
49
+ const iv = hash.subarray(0, 12);
50
+ const aad = Buffer.from(`${ts}.${nonce}.${this.options.id}`, "utf8");
51
+ const data = Buffer.from(JSON.stringify(req), "utf8");
51
52
  const cipher = crypto_1.default.createCipheriv("aes-256-gcm", key, iv);
52
53
  cipher.setAAD(aad);
53
54
  const encrypted = Buffer.concat([cipher.update(data), cipher.final()]);
54
55
  const tag = cipher.getAuthTag();
55
- const resp = await Http_1.Http.post(url, { tag: tag.toString("base64"), enc: encrypted.toString("base64") }, { headers });
56
+ const resp = await Http_1.Http.post(url, {
57
+ tag: tag.toString("base64"),
58
+ enc: encrypted.toString("base64")
59
+ }, { headers });
56
60
  if (!resp.ok)
57
- return { ...DefaultErrors_1.default.BAD_REQUEST, details: resp.details, stack: [resp.error] };
61
+ return { ...DefaultErrors_1.default.BAD_REQUEST, details: resp.details };
58
62
  const body = resp.data;
59
- if (body && typeof body === "object" && "error" in body)
60
- return body.error;
61
- return body.data ?? null;
63
+ return (body && typeof body === "object" && "error" in body) ? body.error : (body.data ?? null);
62
64
  }
63
65
  }
64
66
  exports.MicroserviceClient = MicroserviceClient;
@@ -1,34 +1,11 @@
1
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 __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || function (mod) {
19
- if (mod && mod.__esModule) return mod;
20
- var result = {};
21
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
- __setModuleDefault(result, mod);
23
- return result;
24
- };
25
2
  var __importDefault = (this && this.__importDefault) || function (mod) {
26
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
27
4
  };
28
5
  Object.defineProperty(exports, "__esModule", { value: true });
29
6
  exports.MicroserviceHost = void 0;
30
7
  const BaseService_1 = require("../BaseService");
31
- const DefaultErrors_1 = __importStar(require("../structures/DefaultErrors"));
8
+ const DefaultErrors_1 = __importDefault(require("../structures/DefaultErrors"));
32
9
  const crypto_1 = __importDefault(require("crypto"));
33
10
  class MicroserviceHost extends BaseService_1.BaseService {
34
11
  static #calls = new Set();
@@ -46,62 +23,49 @@ class MicroserviceHost extends BaseService_1.BaseService {
46
23
  return MicroserviceHost.#instances.get(id) || null;
47
24
  }
48
25
  async handleIncomingRequest(req) {
49
- console.log("Handling incoming request for MicroserviceHost:", this.getName());
50
26
  const nonce = req.headers["x-microservice-nonce"];
51
27
  const ts = req.headers["x-microservice-ts"];
52
28
  if (!nonce || !ts)
53
29
  return { ...DefaultErrors_1.default.BAD_REQUEST, details: "missing headers" };
54
- if (ts.length !== 13 || isNaN(+ts))
55
- return { ...DefaultErrors_1.default.BAD_REQUEST, details: "invalid timestamp" };
56
- if (+new Date() - (+ts) > 1000 * 60 * 2)
57
- return { ...DefaultErrors_1.default.BAD_REQUEST, details: "timestamp too old" };
58
- const checkCall = MicroserviceHost.#calls.has(nonce + "|" + ts);
59
- if (checkCall)
60
- return { ...DefaultErrors_1.default.BAD_REQUEST, details: "replay attack detected" };
61
- MicroserviceHost.#calls.add(nonce + "|" + ts);
62
- if (MicroserviceHost.#calls.size > 1000) {
63
- const first = MicroserviceHost.#calls.values().next().value;
64
- if (first)
65
- MicroserviceHost.#calls.delete(first);
66
- }
67
- const secret = Buffer.from(this.options.securityKey, "base64");
68
- const salt = crypto_1.default.createHash("sha256").update(nonce + ts).digest();
69
- const key = crypto_1.default.pbkdf2Sync(secret, salt, 100, 32, "sha256");
70
- const iv = crypto_1.default.pbkdf2Sync(secret, salt, 100, 16, "sha256");
71
- const aad = Buffer.from(ts + "." + nonce + "." + this.options.id + "." + this.options.password, "utf8");
72
- const tag = Buffer.from(req.data.tag, "base64");
73
- const enc = Buffer.from(req.data.enc, "base64");
74
- const decipher = crypto_1.default.createDecipheriv("aes-256-gcm", key, iv);
75
- decipher.setAAD(aad);
76
- decipher.setAuthTag(tag);
77
- const decrypted = Buffer.concat([decipher.update(enc), decipher.final()]);
78
- let request = null;
79
- try {
80
- request = JSON.parse(decrypted.toString("utf8"));
30
+ const requestTime = parseInt(ts);
31
+ const now = Date.now();
32
+ if (isNaN(requestTime) || Math.abs(now - requestTime) > 1000 * 60 * 2) {
33
+ return { ...DefaultErrors_1.default.BAD_REQUEST, details: "timestamp out of range" };
81
34
  }
82
- catch (e) {
83
- return { ...DefaultErrors_1.default.BAD_REQUEST, details: "invalid json request" };
84
- }
85
- if (!request) {
86
- return { ...DefaultErrors_1.default.BAD_REQUEST, details: "no request found" };
87
- }
88
- if (typeof request !== "object" || !request.requestName) {
89
- return { ...DefaultErrors_1.default.BAD_REQUEST, details: "invalid request object" };
35
+ const callKey = `${nonce}|${ts}`;
36
+ if (MicroserviceHost.#calls.has(callKey)) {
37
+ return { ...DefaultErrors_1.default.BAD_REQUEST, details: "replay attack detected" };
90
38
  }
91
- const reqCall = this.options.requests.find(r => r.name === request.requestName);
92
- if (!reqCall) {
93
- return { ...DefaultErrors_1.default.BAD_REQUEST, details: "request not found: " + request.requestName };
39
+ MicroserviceHost.#calls.add(callKey);
40
+ if (MicroserviceHost.#calls.size > 5000) {
41
+ const iterator = MicroserviceHost.#calls.values();
42
+ for (let i = 0; i < 100; i++) {
43
+ const val = iterator.next().value;
44
+ if (val)
45
+ MicroserviceHost.#calls.delete(val);
46
+ }
94
47
  }
95
- let response = null;
96
48
  try {
97
- response = await reqCall.request(request.requestData);
49
+ const secret = Buffer.from(this.options.securityKey, "base64");
50
+ const hash = crypto_1.default.createHash("sha256").update(nonce + ts + this.options.securityKey).digest();
51
+ const key = secret;
52
+ const iv = hash.subarray(0, 12);
53
+ const aad = Buffer.from(`${ts}.${nonce}.${this.options.id}`, "utf8");
54
+ const tag = Buffer.from(req.data.tag, "base64");
55
+ const enc = Buffer.from(req.data.enc, "base64");
56
+ const decipher = crypto_1.default.createDecipheriv("aes-256-gcm", key, iv);
57
+ decipher.setAAD(aad);
58
+ decipher.setAuthTag(tag);
59
+ const decrypted = Buffer.concat([decipher.update(enc), decipher.final()]);
60
+ const request = JSON.parse(decrypted.toString("utf8"));
61
+ const reqCall = this.options.requests.find(r => r.name === request?.requestName);
62
+ if (!reqCall)
63
+ return { ...DefaultErrors_1.default.BAD_REQUEST, details: "method not found" };
64
+ return await reqCall.request(request.requestData);
98
65
  }
99
66
  catch (e) {
100
- if (DefaultErrors_1.ErrorUtils.isError(e))
101
- return e;
102
- return { ...DefaultErrors_1.default.INTERNAL_SERVER_ERROR, details: "request execution error: " + e?.message };
67
+ return { ...DefaultErrors_1.default.BAD_REQUEST, details: "decryption error" };
103
68
  }
104
- return response;
105
69
  }
106
70
  }
107
71
  exports.MicroserviceHost = MicroserviceHost;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "badmfck-api-server",
3
- "version": "4.0.73",
3
+ "version": "4.0.75",
4
4
  "description": "Simple API http server based on express",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",