ante-erp-cli 1.11.59 → 1.11.60

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ante-erp-cli",
3
- "version": "1.11.59",
3
+ "version": "1.11.60",
4
4
  "description": "Comprehensive CLI tool for managing ANTE ERP self-hosted installations",
5
5
  "type": "module",
6
6
  "bin": {
@@ -46,9 +46,9 @@ function getEnvValue(envPath, key) {
46
46
  }
47
47
 
48
48
  /**
49
- * Check if gate-app, guardian-app, or facial-web is installed by checking docker-compose.yml
49
+ * Check if optional apps are installed by checking docker-compose.yml
50
50
  * @param {string} composeFile - Path to docker-compose.yml
51
- * @returns {{hasGateApp: boolean, hasGuardianApp: boolean, hasFacialWeb: boolean}}
51
+ * @returns {{hasGateApp: boolean, hasGuardianApp: boolean, hasFacialWeb: boolean, hasPosApp: boolean, hasMlmApp: boolean, hasBackendMlm: boolean}}
52
52
  */
53
53
  function detectInstalledApps(composeFile) {
54
54
  try {
@@ -56,10 +56,13 @@ function detectInstalledApps(composeFile) {
56
56
  return {
57
57
  hasGateApp: composeContent.includes('gate-app:') || composeContent.includes('container_name: ante-gate-app'),
58
58
  hasGuardianApp: composeContent.includes('guardian-app:') || composeContent.includes('container_name: ante-guardian-app'),
59
- hasFacialWeb: composeContent.includes('facial-web:') || composeContent.includes('container_name: ante-facial-web')
59
+ hasFacialWeb: composeContent.includes('facial-web:') || composeContent.includes('container_name: ante-facial-web'),
60
+ hasPosApp: composeContent.includes('pos-app:') || composeContent.includes('container_name: ante-pos'),
61
+ hasMlmApp: composeContent.includes('mlm-app:') || composeContent.includes('container_name: ante-mlm'),
62
+ hasBackendMlm: composeContent.includes('backend-mlm:') || composeContent.includes('container_name: ante-backend-mlm')
60
63
  };
61
64
  } catch {
62
- return { hasGateApp: false, hasGuardianApp: false, hasFacialWeb: false };
65
+ return { hasGateApp: false, hasGuardianApp: false, hasFacialWeb: false, hasPosApp: false, hasMlmApp: false, hasBackendMlm: false };
63
66
  }
64
67
  }
65
68
 
@@ -87,7 +90,7 @@ export async function sslEnable(options) {
87
90
  console.log(chalk.gray(`Installation: ${installDir}\n`));
88
91
 
89
92
  // Detect which apps are installed
90
- const { hasGateApp, hasGuardianApp, hasFacialWeb } = detectInstalledApps(composeFile);
93
+ const { hasGateApp, hasGuardianApp, hasFacialWeb, hasPosApp, hasMlmApp, hasBackendMlm } = detectInstalledApps(composeFile);
91
94
 
92
95
  // Read current configuration
93
96
  const frontendUrl = getEnvValue(envPath, 'FRONTEND_URL');
@@ -95,6 +98,9 @@ export async function sslEnable(options) {
95
98
  const gateAppUrl = hasGateApp ? getEnvValue(envPath, 'GATE_APP_URL') : '';
96
99
  const guardianAppUrl = hasGuardianApp ? getEnvValue(envPath, 'GUARDIAN_APP_URL') : '';
97
100
  const facialWebUrl = hasFacialWeb ? getEnvValue(envPath, 'FACIAL_WEB_URL') : '';
101
+ const posAppUrl = hasPosApp ? getEnvValue(envPath, 'POS_APP_URL') : '';
102
+ const mlmAppUrl = hasMlmApp ? getEnvValue(envPath, 'MLM_APP_URL') : '';
103
+ const backendMlmUrl = hasBackendMlm ? getEnvValue(envPath, 'MLM_API_URL') : '';
98
104
 
99
105
  if (!frontendUrl || !apiUrl) {
100
106
  console.log(chalk.red('✗ Domain configuration not found'));
@@ -111,7 +117,10 @@ export async function sslEnable(options) {
111
117
  const allHttps = frontendUrl.startsWith('https://') && apiUrl.startsWith('https://') &&
112
118
  (!gateAppUrl || gateAppUrl.startsWith('https://')) &&
113
119
  (!guardianAppUrl || guardianAppUrl.startsWith('https://')) &&
114
- (!facialWebUrl || facialWebUrl.startsWith('https://'));
120
+ (!facialWebUrl || facialWebUrl.startsWith('https://')) &&
121
+ (!posAppUrl || posAppUrl.startsWith('https://')) &&
122
+ (!mlmAppUrl || mlmAppUrl.startsWith('https://')) &&
123
+ (!backendMlmUrl || backendMlmUrl.startsWith('https://'));
115
124
 
116
125
  if (allHttps) {
117
126
  console.log(chalk.yellow('⚠ Domains are already configured with HTTPS:\n'));
@@ -119,6 +128,9 @@ export async function sslEnable(options) {
119
128
  if (gateAppUrl) console.log(chalk.gray(` Gate App: ${gateAppUrl}`));
120
129
  if (guardianAppUrl) console.log(chalk.gray(` Guardian: ${guardianAppUrl}`));
121
130
  if (facialWebUrl) console.log(chalk.gray(` Facial Web: ${facialWebUrl}`));
131
+ if (posAppUrl) console.log(chalk.gray(` POS App: ${posAppUrl}`));
132
+ if (mlmAppUrl) console.log(chalk.gray(` MLM App: ${mlmAppUrl}`));
133
+ if (backendMlmUrl) console.log(chalk.gray(` Backend MLM: ${backendMlmUrl}`));
122
134
  console.log(chalk.gray(` API: ${apiUrl}\n`));
123
135
 
124
136
  // Check certificate status
@@ -153,6 +165,30 @@ export async function sslEnable(options) {
153
165
  }
154
166
  }
155
167
 
168
+ if (posAppUrl) {
169
+ const posAppDomain = extractDomain(posAppUrl);
170
+ const posAppStatus = await checkSSLStatus(posAppDomain);
171
+ if (posAppStatus.installed) {
172
+ console.log(chalk.green(`✓ POS App SSL: Valid (expires in ${posAppStatus.daysUntilExpiry} days)`));
173
+ }
174
+ }
175
+
176
+ if (mlmAppUrl) {
177
+ const mlmAppDomain = extractDomain(mlmAppUrl);
178
+ const mlmAppStatus = await checkSSLStatus(mlmAppDomain);
179
+ if (mlmAppStatus.installed) {
180
+ console.log(chalk.green(`✓ MLM App SSL: Valid (expires in ${mlmAppStatus.daysUntilExpiry} days)`));
181
+ }
182
+ }
183
+
184
+ if (backendMlmUrl) {
185
+ const backendMlmDomain = extractDomain(backendMlmUrl);
186
+ const backendMlmStatus = await checkSSLStatus(backendMlmDomain);
187
+ if (backendMlmStatus.installed) {
188
+ console.log(chalk.green(`✓ Backend MLM SSL: Valid (expires in ${backendMlmStatus.daysUntilExpiry} days)`));
189
+ }
190
+ }
191
+
156
192
  if (apiStatus.installed) {
157
193
  console.log(chalk.green(`✓ API SSL: Valid (expires in ${apiStatus.daysUntilExpiry} days)`));
158
194
  }
@@ -180,6 +216,9 @@ export async function sslEnable(options) {
180
216
  if (gateAppUrl) console.log(chalk.gray(` Gate App: ${gateAppUrl}`));
181
217
  if (guardianAppUrl) console.log(chalk.gray(` Guardian: ${guardianAppUrl}`));
182
218
  if (facialWebUrl) console.log(chalk.gray(` Facial Web: ${facialWebUrl}`));
219
+ if (posAppUrl) console.log(chalk.gray(` POS App: ${posAppUrl}`));
220
+ if (mlmAppUrl) console.log(chalk.gray(` MLM App: ${mlmAppUrl}`));
221
+ if (backendMlmUrl) console.log(chalk.gray(` Backend MLM: ${backendMlmUrl}`));
183
222
  console.log(chalk.gray(` API: ${apiUrl}\n`));
184
223
 
185
224
  // Detect domains to configure
@@ -230,6 +269,42 @@ export async function sslEnable(options) {
230
269
  }
231
270
  }
232
271
 
272
+ if (posAppUrl) {
273
+ const posAppDomain = extractDomain(posAppUrl);
274
+ if (posAppDomain !== 'localhost' && !posAppDomain.match(/^\d+\.\d+\.\d+\.\d+$/) && !domains.find(d => d.domain === posAppDomain)) {
275
+ domains.push({
276
+ name: 'POS App',
277
+ domain: posAppDomain,
278
+ port: posAppUrl.match(/:(\d+)/) ? posAppUrl.match(/:(\d+)/)[1] : 8084,
279
+ url: posAppUrl
280
+ });
281
+ }
282
+ }
283
+
284
+ if (mlmAppUrl) {
285
+ const mlmAppDomain = extractDomain(mlmAppUrl);
286
+ if (mlmAppDomain !== 'localhost' && !mlmAppDomain.match(/^\d+\.\d+\.\d+\.\d+$/) && !domains.find(d => d.domain === mlmAppDomain)) {
287
+ domains.push({
288
+ name: 'MLM App',
289
+ domain: mlmAppDomain,
290
+ port: mlmAppUrl.match(/:(\d+)/) ? mlmAppUrl.match(/:(\d+)/)[1] : 9005,
291
+ url: mlmAppUrl
292
+ });
293
+ }
294
+ }
295
+
296
+ if (backendMlmUrl) {
297
+ const backendMlmDomain = extractDomain(backendMlmUrl);
298
+ if (backendMlmDomain !== 'localhost' && !backendMlmDomain.match(/^\d+\.\d+\.\d+\.\d+$/) && !domains.find(d => d.domain === backendMlmDomain)) {
299
+ domains.push({
300
+ name: 'Backend MLM',
301
+ domain: backendMlmDomain,
302
+ port: backendMlmUrl.match(/:(\d+)/) ? backendMlmUrl.match(/:(\d+)/)[1] : 4001,
303
+ url: backendMlmUrl
304
+ });
305
+ }
306
+ }
307
+
233
308
  if (apiDomain !== 'localhost' && !apiDomain.match(/^\d+\.\d+\.\d+\.\d+$/) && apiDomain !== frontendDomain) {
234
309
  domains.push({
235
310
  name: 'API',
@@ -347,6 +422,21 @@ export async function sslEnable(options) {
347
422
  sslConfig.facialWebPort = facialWebUrl.match(/:(\d+)/) ? parseInt(facialWebUrl.match(/:(\d+)/)[1]) : 8083;
348
423
  }
349
424
 
425
+ if (posAppUrl) {
426
+ sslConfig.posAppDomain = posAppUrl;
427
+ sslConfig.posAppPort = posAppUrl.match(/:(\d+)/) ? parseInt(posAppUrl.match(/:(\d+)/)[1]) : 8084;
428
+ }
429
+
430
+ if (mlmAppUrl) {
431
+ sslConfig.mlmAppDomain = mlmAppUrl;
432
+ sslConfig.mlmAppPort = mlmAppUrl.match(/:(\d+)/) ? parseInt(mlmAppUrl.match(/:(\d+)/)[1]) : 9005;
433
+ }
434
+
435
+ if (backendMlmUrl) {
436
+ sslConfig.backendMlmDomain = backendMlmUrl;
437
+ sslConfig.backendMlmPort = backendMlmUrl.match(/:(\d+)/) ? parseInt(backendMlmUrl.match(/:(\d+)/)[1]) : 4001;
438
+ }
439
+
350
440
  await updateNginxForSSL(sslConfig);
351
441
  } catch (error) {
352
442
  console.log(chalk.red('\n✗ Failed to configure NGINX:'), error.message);
@@ -416,13 +506,16 @@ export async function sslStatus() {
416
506
  const composeFile = join(installDir, 'docker-compose.yml');
417
507
 
418
508
  // Detect which apps are installed
419
- const { hasGateApp, hasGuardianApp, hasFacialWeb } = detectInstalledApps(composeFile);
509
+ const { hasGateApp, hasGuardianApp, hasFacialWeb, hasPosApp, hasMlmApp, hasBackendMlm } = detectInstalledApps(composeFile);
420
510
 
421
511
  const frontendUrl = getEnvValue(envPath, 'FRONTEND_URL');
422
512
  const apiUrl = getEnvValue(envPath, 'API_URL');
423
513
  const gateAppUrl = hasGateApp ? getEnvValue(envPath, 'GATE_APP_URL') : '';
424
514
  const guardianAppUrl = hasGuardianApp ? getEnvValue(envPath, 'GUARDIAN_APP_URL') : '';
425
515
  const facialWebUrl = hasFacialWeb ? getEnvValue(envPath, 'FACIAL_WEB_URL') : '';
516
+ const posAppUrl = hasPosApp ? getEnvValue(envPath, 'POS_APP_URL') : '';
517
+ const mlmAppUrl = hasMlmApp ? getEnvValue(envPath, 'MLM_APP_URL') : '';
518
+ const backendMlmUrl = hasBackendMlm ? getEnvValue(envPath, 'MLM_API_URL') : '';
426
519
 
427
520
  if (!frontendUrl || !apiUrl) {
428
521
  console.log(chalk.red('✗ Domain configuration not found\n'));
@@ -451,6 +544,21 @@ export async function sslStatus() {
451
544
  domains.push({ name: 'Facial Web', domain: facialWebDomain, url: facialWebUrl });
452
545
  }
453
546
 
547
+ if (posAppUrl) {
548
+ const posAppDomain = extractDomain(posAppUrl);
549
+ domains.push({ name: 'POS App', domain: posAppDomain, url: posAppUrl });
550
+ }
551
+
552
+ if (mlmAppUrl) {
553
+ const mlmAppDomain = extractDomain(mlmAppUrl);
554
+ domains.push({ name: 'MLM App', domain: mlmAppDomain, url: mlmAppUrl });
555
+ }
556
+
557
+ if (backendMlmUrl) {
558
+ const backendMlmDomain = extractDomain(backendMlmUrl);
559
+ domains.push({ name: 'Backend MLM', domain: backendMlmDomain, url: backendMlmUrl });
560
+ }
561
+
454
562
  domains.push({ name: 'API', domain: apiDomain, url: apiUrl });
455
563
 
456
564
  for (const { name, domain, url } of domains) {
package/src/utils/ssl.js CHANGED
@@ -128,14 +128,16 @@ export async function obtainSSLCertificate(config) {
128
128
  * @param {string} [config.guardianAppDomain] - Guardian App domain URL (optional)
129
129
  * @param {string} [config.facialAppDomain] - Facial Web domain URL (optional)
130
130
  * @param {string} [config.posAppDomain] - POS App domain URL (optional)
131
- * @param {string} [config.clientAppDomain] - Client App domain URL (optional)
131
+ * @param {string} [config.mlmAppDomain] - MLM App domain URL (optional)
132
+ * @param {string} [config.backendMlmDomain] - Backend MLM API domain URL (optional)
132
133
  * @param {number} [config.frontendPort=8080] - Frontend port
133
134
  * @param {number} [config.apiPort=3001] - API port
134
135
  * @param {number} [config.gateAppPort=8081] - Gate App port
135
136
  * @param {number} [config.guardianAppPort=8082] - Guardian App port
136
137
  * @param {number} [config.facialWebPort=8083] - Facial Web port
137
138
  * @param {number} [config.posAppPort=8084] - POS App port
138
- * @param {number} [config.clientAppPort=9005] - Client App port
139
+ * @param {number} [config.mlmAppPort=9005] - MLM App port
140
+ * @param {number} [config.backendMlmPort=4001] - Backend MLM API port
139
141
  * @returns {Promise<void>}
140
142
  */
141
143
  export async function updateNginxForSSL(config) {
@@ -146,16 +148,16 @@ export async function updateNginxForSSL(config) {
146
148
  guardianAppDomain,
147
149
  facialAppDomain,
148
150
  posAppDomain,
149
- clientAppDomain,
150
- backendClientDomain,
151
+ mlmAppDomain,
152
+ backendMlmDomain,
151
153
  frontendPort = 8080,
152
154
  apiPort = 3001,
153
155
  gateAppPort = 8081,
154
156
  guardianAppPort = 8082,
155
157
  facialWebPort = 8083,
156
158
  posAppPort = 8084,
157
- clientAppPort = 9005,
158
- backendClientPort = 4001
159
+ mlmAppPort = 9005,
160
+ backendMlmPort = 4001
159
161
  } = config;
160
162
  const spinner = ora('Updating NGINX configuration for HTTPS...').start();
161
163
 
@@ -182,16 +184,16 @@ export async function updateNginxForSSL(config) {
182
184
  guardianAppDomain,
183
185
  facialAppDomain,
184
186
  posAppDomain,
185
- clientAppDomain,
186
- backendClientDomain,
187
+ mlmAppDomain,
188
+ backendMlmDomain,
187
189
  frontendPort,
188
190
  apiPort,
189
191
  gateAppPort,
190
192
  guardianAppPort,
191
193
  facialWebPort,
192
194
  posAppPort,
193
- clientAppPort,
194
- backendClientPort,
195
+ mlmAppPort,
196
+ backendMlmPort,
195
197
  ssl: true
196
198
  });
197
199