@yobytechautomation/config-lib 0.2.9 → 0.3.1

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,4 +1,4 @@
1
- import { TypeOrmModuleOptions } from '@nestjs/typeorm';
1
+ import { TypeOrmModuleOptions } from "@nestjs/typeorm";
2
2
  export interface BaseConfigService {
3
3
  getDatabaseConfig(): TypeOrmModuleOptions;
4
4
  getPort(): number;
@@ -41,15 +41,16 @@ const axios_1 = __importDefault(require("axios"));
41
41
  const fs = __importStar(require("fs"));
42
42
  const path = __importStar(require("path"));
43
43
  const os = __importStar(require("os"));
44
+ const crypto = __importStar(require("crypto"));
44
45
  class BaseConfigServiceImpl {
45
46
  constructor() {
46
47
  this.env = process.env;
47
48
  this.checkIntegrity();
48
49
  }
49
50
  checkIntegrity() {
50
- const fileContent = fs.readFileSync(__filename, 'utf-8');
51
- if (!fileContent.includes('validateLicenseOrThrow')) {
52
- console.error('❌ License system tampered');
51
+ const fileContent = fs.readFileSync(__filename, "utf-8");
52
+ if (!fileContent.includes("validateLicenseOrThrow")) {
53
+ console.error("❌ License system tampered");
53
54
  process.exit(1);
54
55
  }
55
56
  }
@@ -57,65 +58,70 @@ class BaseConfigServiceImpl {
57
58
  setInterval(async () => {
58
59
  try {
59
60
  await this.validateLicenseOrThrow();
60
- console.log('💓 License heartbeat OK');
61
+ console.log("💓 License heartbeat OK");
61
62
  }
62
63
  catch (err) {
63
- console.error('💀 License revoked during runtime');
64
+ console.error("💀 License revoked during runtime");
64
65
  process.exit(1);
65
66
  }
66
67
  }, 5 * 60 * 1000);
67
68
  }
68
69
  getDatabaseConfig() {
69
- throw new Error('Method not implemented.');
70
+ throw new Error("Method not implemented.");
70
71
  }
71
72
  getPort() {
72
- throw new Error('Method not implemented.');
73
+ throw new Error("Method not implemented.");
73
74
  }
74
75
  getMode() {
75
- throw new Error('Method not implemented.');
76
+ throw new Error("Method not implemented.");
76
77
  }
77
78
  getConsulConfig() {
78
- throw new Error('Method not implemented.');
79
+ throw new Error("Method not implemented.");
79
80
  }
80
81
  getRedisConfig() {
81
- throw new Error('Method not implemented.');
82
+ throw new Error("Method not implemented.");
82
83
  }
83
84
  getJWTConfig() {
84
- throw new Error('Method not implemented.');
85
+ throw new Error("Method not implemented.");
85
86
  }
86
87
  getJUtilConfig() {
87
- throw new Error('Method not implemented.');
88
+ throw new Error("Method not implemented.");
88
89
  }
89
90
  getMailConfig() {
90
- throw new Error('Method not implemented.');
91
+ throw new Error("Method not implemented.");
91
92
  }
92
93
  getKAFKAConfig() {
93
- throw new Error('Method not implemented.');
94
+ throw new Error("Method not implemented.");
94
95
  }
95
96
  async validateLicenseOrThrow() {
96
- var _a;
97
- const cachePath = path.join(process.cwd(), '.license-cache.json');
97
+ var _a, _b, _c;
98
+ const cachePath = path.join(process.cwd(), ".license-cache.json");
98
99
  const apiKey = this.env.LICENSE_KEY;
99
100
  if (!apiKey) {
100
- throw new Error('LICENSE_KEY missing');
101
+ throw new Error("LICENSE_KEY missing");
101
102
  }
102
103
  try {
103
- const part1 = 'aHR0cHM6Ly9kZXYu';
104
- const part2 = 'd2F0ZXJhdXRvLnlvYnl0ZWNo';
105
- const part3 = 'LmluL2xpY2Vuc2UvY2hlY2s=';
106
- const url = Buffer.from(part1 + part2 + part3, 'base64').toString('utf-8');
104
+ const part1 = "aHR0cHM6Ly9kZXYu";
105
+ const part2 = "d2F0ZXJhdXRvLnlvYnl0ZWNo";
106
+ const part3 = "LmluL2xpY2Vuc2UvY2hlY2s=";
107
+ const url = Buffer.from(part1 + part2 + part3, "base64").toString("utf-8");
107
108
  const secret = process.env.LICENSE_SECRET;
108
109
  const machineId = os.hostname();
110
+ const signature = crypto
111
+ .createHmac("sha256", secret)
112
+ .update(apiKey + machineId)
113
+ .digest("hex");
109
114
  const res = await axios_1.default.get(url, {
110
115
  headers: {
111
- 'x-api-key': apiKey,
112
- 'x-license-secret': secret,
113
- 'x-machine-id': machineId,
116
+ "x-api-key": apiKey,
117
+ "x-license-secret": secret,
118
+ "x-machine-id": machineId,
119
+ 'x-signature': signature,
114
120
  },
115
121
  timeout: 5000,
116
122
  });
117
123
  const status = (_a = res === null || res === void 0 ? void 0 : res.data) === null || _a === void 0 ? void 0 : _a.status;
118
- if (status !== 'active') {
124
+ if (status !== "active") {
119
125
  throw new Error(`License ${status}. Please contact vendor.`);
120
126
  }
121
127
  const machineId2 = os.hostname();
@@ -123,27 +129,35 @@ class BaseConfigServiceImpl {
123
129
  lastValidated: new Date().toISOString(),
124
130
  machineId: machineId2,
125
131
  }));
126
- console.log('✅ License validated (online)');
132
+ console.log("✅ License validated (online)");
127
133
  }
128
134
  catch (err) {
129
- console.log('⚠️ Server not reachable, checking cache...');
130
- if (fs.existsSync(cachePath)) {
131
- const data = JSON.parse(fs.readFileSync(cachePath, 'utf-8'));
135
+ const errorMsg = (_c = (_b = err === null || err === void 0 ? void 0 : err.response) === null || _b === void 0 ? void 0 : _b.data) === null || _c === void 0 ? void 0 : _c.status;
136
+ // 🔥 CASE 1 — SERVER RESPONDED (LICENSE INVALID)
137
+ if (errorMsg) {
138
+ throw new Error(`License ${errorMsg}. Please contact vendor.`);
139
+ }
140
+ // 🔥 CASE 2 — SERVER NOT REACHABLE
141
+ console.error("❌ License server unreachable");
142
+ // ⚠️ OPTIONAL STRICT CACHE (VERY LIMITED USE)
143
+ const ALLOW_OFFLINE = false; // 🔥 set FALSE for production
144
+ if (ALLOW_OFFLINE && fs.existsSync(cachePath)) {
145
+ const data = JSON.parse(fs.readFileSync(cachePath, "utf-8"));
132
146
  if (data.machineId !== os.hostname()) {
133
- throw new Error('License cache copied from another machine');
147
+ throw new Error("License cache copied from another machine");
134
148
  }
135
149
  const last = new Date(data.lastValidated);
136
150
  const now = new Date();
137
- const diffHours = (now.getTime() - last.getTime()) / (1000 * 60 * 60);
138
- const MAX_OFFLINE_HOURS = 0.5; // 30 minutes
139
- if (diffHours <= MAX_OFFLINE_HOURS) {
140
- console.log('⚠️ Using cached license (temporary offline)');
151
+ const diffMinutes = (now.getTime() - last.getTime()) / (1000 * 60);
152
+ if (diffMinutes <= 5) {
153
+ // max 5 minutes only
154
+ console.log("⚠️ Temporary offline mode (5 min)");
141
155
  return;
142
156
  }
143
157
  }
144
- throw new Error(err.message || 'License validation failed');
158
+ throw new Error("License server unreachable. App blocked.");
145
159
  }
146
160
  }
147
161
  }
148
162
  exports.BaseConfigServiceImpl = BaseConfigServiceImpl;
149
- exports.BASE_CONFIG_SERVICE = Symbol('BASE_CONFIG_SERVICE');
163
+ exports.BASE_CONFIG_SERVICE = Symbol("BASE_CONFIG_SERVICE");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yobytechautomation/config-lib",
3
- "version": "0.2.9",
3
+ "version": "0.3.1",
4
4
  "description": "Shared multi-environment configuration helpers for SDC NestJS services",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",