ante-erp-cli 1.11.41 → 1.11.43
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/bin/ante-cli.js +3 -3
- package/package.json +1 -1
- package/src/commands/database-ports.js +5 -5
- package/src/commands/update.js +82 -0
- package/src/templates/docker-compose.yml.js +3 -0
- package/src/templates/env.js +5 -0
- package/src/utils/database-ports.js +9 -9
- package/src/utils/password.js +1 -0
package/bin/ante-cli.js
CHANGED
|
@@ -245,9 +245,9 @@ dbCmd
|
|
|
245
245
|
.option('--redis', 'Expose only Redis')
|
|
246
246
|
.option('--mongodb', 'Expose only MongoDB')
|
|
247
247
|
.option('--all', 'Expose all databases (default)', true)
|
|
248
|
-
.option('--postgres-port <port>', 'Custom host port for PostgreSQL (default:
|
|
249
|
-
.option('--redis-port <port>', 'Custom host port for Redis (default:
|
|
250
|
-
.option('--mongodb-port <port>', 'Custom host port for MongoDB (default:
|
|
248
|
+
.option('--postgres-port <port>', 'Custom host port for PostgreSQL (default: 64541)')
|
|
249
|
+
.option('--redis-port <port>', 'Custom host port for Redis (default: 61066)')
|
|
250
|
+
.option('--mongodb-port <port>', 'Custom host port for MongoDB (default: 50167)')
|
|
251
251
|
.option('--force', 'Skip confirmation prompts')
|
|
252
252
|
.option('--no-restart', 'Don\'t restart services automatically')
|
|
253
253
|
.action(exposeDbPorts);
|
package/package.json
CHANGED
|
@@ -80,15 +80,15 @@ function displaySecurityWarning() {
|
|
|
80
80
|
* Display database exposure information
|
|
81
81
|
*/
|
|
82
82
|
function displayExposureInfo(databases) {
|
|
83
|
-
console.log(chalk.cyan('This will expose the following ports:'));
|
|
83
|
+
console.log(chalk.cyan('This will expose the following databases with default ports:'));
|
|
84
84
|
databases.forEach((db) => {
|
|
85
85
|
const dbInfo = {
|
|
86
|
-
postgres: { name: 'PostgreSQL', port:
|
|
87
|
-
redis: { name: 'Redis', port:
|
|
88
|
-
mongodb: { name: 'MongoDB', port:
|
|
86
|
+
postgres: { name: 'PostgreSQL', port: 64541 },
|
|
87
|
+
redis: { name: 'Redis', port: 61066 },
|
|
88
|
+
mongodb: { name: 'MongoDB', port: 50167 },
|
|
89
89
|
};
|
|
90
90
|
if (dbInfo[db]) {
|
|
91
|
-
console.log(chalk.cyan(` • ${dbInfo[db].name}: ${dbInfo[db].port}`));
|
|
91
|
+
console.log(chalk.cyan(` • ${dbInfo[db].name}: Host Port ${dbInfo[db].port}`));
|
|
92
92
|
}
|
|
93
93
|
});
|
|
94
94
|
console.log();
|
package/src/commands/update.js
CHANGED
|
@@ -8,6 +8,7 @@ import { pullImagesSilent, stopServicesSilent, startServicesSilent, waitForServi
|
|
|
8
8
|
import { backup } from './backup.js';
|
|
9
9
|
import { getCurrentVersion, getLatestVersion } from './update-cli.js';
|
|
10
10
|
import { generateDockerCompose } from '../templates/docker-compose.yml.js';
|
|
11
|
+
import { generateSecurePassword } from '../utils/password.js';
|
|
11
12
|
|
|
12
13
|
/**
|
|
13
14
|
* Check if gate-app, guardian-app, facial-web, or pos-app is installed by checking docker-compose.yml
|
|
@@ -236,6 +237,83 @@ COMPANY_ID=1
|
|
|
236
237
|
writeFileSync(envFile, envContent);
|
|
237
238
|
}
|
|
238
239
|
|
|
240
|
+
/**
|
|
241
|
+
* Ensure customer app JWT configuration exists in .env file
|
|
242
|
+
* @param {string} envFile - Path to .env file
|
|
243
|
+
*/
|
|
244
|
+
function ensureCustomerAppJwtConfig(envFile) {
|
|
245
|
+
let envContent = readFileSync(envFile, 'utf8');
|
|
246
|
+
let modified = false;
|
|
247
|
+
|
|
248
|
+
// Check if CUSTOMER_APP_JWT_SECRET exists
|
|
249
|
+
if (!envContent.includes('CUSTOMER_APP_JWT_SECRET=')) {
|
|
250
|
+
console.log('⚙️ Adding missing CUSTOMER_APP_JWT_SECRET...');
|
|
251
|
+
|
|
252
|
+
// Generate new secret
|
|
253
|
+
const customerAppJwtSecret = generateSecurePassword(64);
|
|
254
|
+
|
|
255
|
+
// Find the ENCRYPTION_KEY line and add after it
|
|
256
|
+
if (envContent.includes('ENCRYPTION_KEY=')) {
|
|
257
|
+
envContent = envContent.replace(
|
|
258
|
+
/(ENCRYPTION_KEY=.*\n)/,
|
|
259
|
+
`$1\n# Customer App JWT Configuration\nCUSTOMER_APP_JWT_SECRET=${customerAppJwtSecret}\n`
|
|
260
|
+
);
|
|
261
|
+
} else {
|
|
262
|
+
// Fallback: add to security keys section or end of file
|
|
263
|
+
envContent += `\n# Customer App JWT Configuration\nCUSTOMER_APP_JWT_SECRET=${customerAppJwtSecret}\n`;
|
|
264
|
+
}
|
|
265
|
+
modified = true;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
// Check if CUSTOMER_APP_JWT_EXPIRY exists
|
|
269
|
+
if (!envContent.includes('CUSTOMER_APP_JWT_EXPIRY=')) {
|
|
270
|
+
console.log('⚙️ Adding CUSTOMER_APP_JWT_EXPIRY...');
|
|
271
|
+
envContent = envContent.replace(
|
|
272
|
+
/(CUSTOMER_APP_JWT_SECRET=.*\n)/,
|
|
273
|
+
`$1CUSTOMER_APP_JWT_EXPIRY=1y\n`
|
|
274
|
+
);
|
|
275
|
+
modified = true;
|
|
276
|
+
} else {
|
|
277
|
+
// Update old expiry value (15m -> 1y)
|
|
278
|
+
if (envContent.includes('CUSTOMER_APP_JWT_EXPIRY=15m')) {
|
|
279
|
+
console.log('⚙️ Updating CUSTOMER_APP_JWT_EXPIRY from 15m to 1y...');
|
|
280
|
+
envContent = envContent.replace(
|
|
281
|
+
/CUSTOMER_APP_JWT_EXPIRY=15m/,
|
|
282
|
+
'CUSTOMER_APP_JWT_EXPIRY=1y'
|
|
283
|
+
);
|
|
284
|
+
modified = true;
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
// Check if CUSTOMER_APP_REFRESH_TOKEN_EXPIRY exists
|
|
289
|
+
if (!envContent.includes('CUSTOMER_APP_REFRESH_TOKEN_EXPIRY=')) {
|
|
290
|
+
console.log('⚙️ Adding CUSTOMER_APP_REFRESH_TOKEN_EXPIRY...');
|
|
291
|
+
envContent = envContent.replace(
|
|
292
|
+
/(CUSTOMER_APP_JWT_EXPIRY=.*\n)/,
|
|
293
|
+
`$1CUSTOMER_APP_REFRESH_TOKEN_EXPIRY=1y\n`
|
|
294
|
+
);
|
|
295
|
+
modified = true;
|
|
296
|
+
} else {
|
|
297
|
+
// Update old expiry value (30d -> 1y)
|
|
298
|
+
if (envContent.includes('CUSTOMER_APP_REFRESH_TOKEN_EXPIRY=30d')) {
|
|
299
|
+
console.log('⚙️ Updating CUSTOMER_APP_REFRESH_TOKEN_EXPIRY from 30d to 1y...');
|
|
300
|
+
envContent = envContent.replace(
|
|
301
|
+
/CUSTOMER_APP_REFRESH_TOKEN_EXPIRY=30d/,
|
|
302
|
+
'CUSTOMER_APP_REFRESH_TOKEN_EXPIRY=1y'
|
|
303
|
+
);
|
|
304
|
+
modified = true;
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
// Write back if modified
|
|
309
|
+
if (modified) {
|
|
310
|
+
writeFileSync(envFile, envContent);
|
|
311
|
+
console.log('✅ Customer app JWT configuration updated');
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
return modified;
|
|
315
|
+
}
|
|
316
|
+
|
|
239
317
|
/**
|
|
240
318
|
* Format step title with numbering
|
|
241
319
|
* @param {number} step - Current step number
|
|
@@ -298,6 +376,10 @@ export async function update(options) {
|
|
|
298
376
|
// POS App health check removed - not required
|
|
299
377
|
if (!options.skipCleanup) totalSteps++; // Cleanup step
|
|
300
378
|
|
|
379
|
+
// Ensure customer app JWT configuration exists (run before tasks)
|
|
380
|
+
console.log(chalk.gray('Checking customer app JWT configuration...'));
|
|
381
|
+
ensureCustomerAppJwtConfig(envFile);
|
|
382
|
+
|
|
301
383
|
// Pre-calculate step numbers for each task (fixes step numbering bug)
|
|
302
384
|
let currentStep = 0;
|
|
303
385
|
const stepPreStart = !options.skipBackup ? ++currentStep : null;
|
|
@@ -134,6 +134,9 @@ services:
|
|
|
134
134
|
JWT_EXPIRATION: \${JWT_EXPIRATION:-24h}
|
|
135
135
|
DEVELOPER_KEY: \${DEVELOPER_KEY}
|
|
136
136
|
ENCRYPTION_KEY: \${ENCRYPTION_KEY}
|
|
137
|
+
CUSTOMER_APP_JWT_SECRET: \${CUSTOMER_APP_JWT_SECRET}
|
|
138
|
+
CUSTOMER_APP_JWT_EXPIRY: \${CUSTOMER_APP_JWT_EXPIRY:-1y}
|
|
139
|
+
CUSTOMER_APP_REFRESH_TOKEN_EXPIRY: \${CUSTOMER_APP_REFRESH_TOKEN_EXPIRY:-1y}
|
|
137
140
|
FRONTEND_URL: \${FRONTEND_URL:-http://localhost:${frontendPort}}
|
|
138
141
|
API_URL: \${API_URL:-http://localhost:${backendPort}}
|
|
139
142
|
SOCKET_URL: \${SOCKET_URL:-http://localhost:${backendPort}}
|
package/src/templates/env.js
CHANGED
|
@@ -55,6 +55,11 @@ JWT_EXPIRATION=24h
|
|
|
55
55
|
DEVELOPER_KEY=${credentials.developerKey}
|
|
56
56
|
ENCRYPTION_KEY=${credentials.encryptionKey}
|
|
57
57
|
|
|
58
|
+
# Customer App JWT Configuration
|
|
59
|
+
CUSTOMER_APP_JWT_SECRET=${credentials.customerAppJwtSecret}
|
|
60
|
+
CUSTOMER_APP_JWT_EXPIRY=1y
|
|
61
|
+
CUSTOMER_APP_REFRESH_TOKEN_EXPIRY=1y
|
|
62
|
+
|
|
58
63
|
# ------------------------------------------------------------------------------
|
|
59
64
|
# APPLICATION URLs
|
|
60
65
|
# ------------------------------------------------------------------------------
|
|
@@ -61,21 +61,21 @@ const DATABASE_PORTS = {
|
|
|
61
61
|
name: 'PostgreSQL',
|
|
62
62
|
service: 'postgres',
|
|
63
63
|
containerPort: 5432,
|
|
64
|
-
defaultHostPort:
|
|
64
|
+
defaultHostPort: 64541,
|
|
65
65
|
connectionExample: (host, hostPort, password) => `postgresql://ante:${password}@${host}:${hostPort}/ante_db`,
|
|
66
66
|
},
|
|
67
67
|
redis: {
|
|
68
68
|
name: 'Redis',
|
|
69
69
|
service: 'redis',
|
|
70
70
|
containerPort: 6379,
|
|
71
|
-
defaultHostPort:
|
|
71
|
+
defaultHostPort: 61066,
|
|
72
72
|
connectionExample: (host, hostPort, password) => `redis://${host}:${hostPort} (password: ${password})`,
|
|
73
73
|
},
|
|
74
74
|
mongodb: {
|
|
75
75
|
name: 'MongoDB',
|
|
76
76
|
service: 'mongodb',
|
|
77
77
|
containerPort: 27017,
|
|
78
|
-
defaultHostPort:
|
|
78
|
+
defaultHostPort: 50167,
|
|
79
79
|
connectionExample: (host, hostPort, password) => `mongodb://ante:${password}@${host}:${hostPort}/ante`,
|
|
80
80
|
},
|
|
81
81
|
};
|
|
@@ -153,8 +153,8 @@ export async function exposeDatabasePorts(composeFile, options = {}) {
|
|
|
153
153
|
(p) => !p.toString().includes(DATABASE_PORTS.postgres.containerPort.toString())
|
|
154
154
|
);
|
|
155
155
|
|
|
156
|
-
// Find available port
|
|
157
|
-
const hostPort = await findAvailablePort(postgresPort);
|
|
156
|
+
// Find available port (use fixed default if no custom port specified)
|
|
157
|
+
const hostPort = await findAvailablePort(postgresPort || DATABASE_PORTS.postgres.defaultHostPort);
|
|
158
158
|
const portMapping = `${hostPort}:${DATABASE_PORTS.postgres.containerPort}`;
|
|
159
159
|
|
|
160
160
|
doc.services.postgres.ports.push(portMapping);
|
|
@@ -172,8 +172,8 @@ export async function exposeDatabasePorts(composeFile, options = {}) {
|
|
|
172
172
|
(p) => !p.toString().includes(DATABASE_PORTS.redis.containerPort.toString())
|
|
173
173
|
);
|
|
174
174
|
|
|
175
|
-
// Find available port
|
|
176
|
-
const hostPort = await findAvailablePort(redisPort);
|
|
175
|
+
// Find available port (use fixed default if no custom port specified)
|
|
176
|
+
const hostPort = await findAvailablePort(redisPort || DATABASE_PORTS.redis.defaultHostPort);
|
|
177
177
|
const portMapping = `${hostPort}:${DATABASE_PORTS.redis.containerPort}`;
|
|
178
178
|
|
|
179
179
|
doc.services.redis.ports.push(portMapping);
|
|
@@ -191,8 +191,8 @@ export async function exposeDatabasePorts(composeFile, options = {}) {
|
|
|
191
191
|
(p) => !p.toString().includes(DATABASE_PORTS.mongodb.containerPort.toString())
|
|
192
192
|
);
|
|
193
193
|
|
|
194
|
-
// Find available port
|
|
195
|
-
const hostPort = await findAvailablePort(mongodbPort);
|
|
194
|
+
// Find available port (use fixed default if no custom port specified)
|
|
195
|
+
const hostPort = await findAvailablePort(mongodbPort || DATABASE_PORTS.mongodb.defaultHostPort);
|
|
196
196
|
const portMapping = `${hostPort}:${DATABASE_PORTS.mongodb.containerPort}`;
|
|
197
197
|
|
|
198
198
|
doc.services.mongodb.ports.push(portMapping);
|
package/src/utils/password.js
CHANGED