@justin0713/opspilot 1.0.8 → 1.0.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.
- package/bin/opspilot.js +59 -0
- package/package.json +1 -1
package/bin/opspilot.js
CHANGED
|
@@ -398,6 +398,63 @@ function cmdUninstall(flags) {
|
|
|
398
398
|
console.log('');
|
|
399
399
|
}
|
|
400
400
|
|
|
401
|
+
function cmdResetAdmin() {
|
|
402
|
+
checkDocker();
|
|
403
|
+
|
|
404
|
+
const status = tryRun(`docker inspect -f "{{.State.Status}}" ${CONTAINER} 2>/dev/null`);
|
|
405
|
+
if (status !== 'running') {
|
|
406
|
+
die(
|
|
407
|
+
`Container '${CONTAINER}' is not running.\n\n` +
|
|
408
|
+
` Start it first: opspilot start --token <token>\n` +
|
|
409
|
+
` Then reset: opspilot reset-admin`
|
|
410
|
+
);
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
const newPassword = generatePassword();
|
|
414
|
+
|
|
415
|
+
// Python runs INSIDE the container — reads password from stdin (never exposed in ps/docker inspect)
|
|
416
|
+
const script = [
|
|
417
|
+
'import sys, os',
|
|
418
|
+
'sys.path.insert(0, "/app")',
|
|
419
|
+
'from user_store import hash_password, load_users, save_users',
|
|
420
|
+
'data_dir = os.environ.get("OPSPILOT_DATA_DIR", "/app/data")',
|
|
421
|
+
'uf = data_dir + "/users.json"',
|
|
422
|
+
'pw = sys.stdin.readline().strip()',
|
|
423
|
+
'ud = load_users(uf)',
|
|
424
|
+
'ul = ud.get("users", [])',
|
|
425
|
+
'admin = next((u for u in ul if u.get("role") == "admin"), None)',
|
|
426
|
+
'assert admin, "ERROR: no admin user found"',
|
|
427
|
+
'salt, hashed = hash_password(pw)',
|
|
428
|
+
'admin["password_salt"] = salt',
|
|
429
|
+
'admin["password_hash"] = hashed',
|
|
430
|
+
'save_users(uf, ud)',
|
|
431
|
+
'print("OK:" + admin["username"])',
|
|
432
|
+
].join('\n');
|
|
433
|
+
|
|
434
|
+
log('Resetting admin password inside container...');
|
|
435
|
+
const result = spawnSync(
|
|
436
|
+
'docker', ['exec', '-i', CONTAINER, 'python3', '-c', script],
|
|
437
|
+
{ input: newPassword, encoding: 'utf8', stdio: ['pipe', 'pipe', 'pipe'] }
|
|
438
|
+
);
|
|
439
|
+
|
|
440
|
+
if (result.status !== 0 || (result.stdout || '').startsWith('ERROR') || result.error) {
|
|
441
|
+
const detail = (result.stderr || result.stdout || String(result.error)).trim();
|
|
442
|
+
die(`Reset failed: ${detail}\n\nCheck logs: opspilot logs`);
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
// Persist to credentials file (chmod 600) for `opspilot password`
|
|
446
|
+
writeCredentials(newPassword);
|
|
447
|
+
|
|
448
|
+
console.log('');
|
|
449
|
+
ok('Admin password reset successfully.');
|
|
450
|
+
console.log(`${BOLD} Username :${RESET} admin`);
|
|
451
|
+
console.log(`${BOLD} Password :${RESET} ${BOLD}${newPassword}${RESET}`);
|
|
452
|
+
console.log('');
|
|
453
|
+
console.log(`${YELLOW}Save this password — or retrieve it later with:${RESET}`);
|
|
454
|
+
console.log(` ${CYAN}opspilot password${RESET}`);
|
|
455
|
+
console.log('');
|
|
456
|
+
}
|
|
457
|
+
|
|
401
458
|
function cmdInstallGuide() {
|
|
402
459
|
const platform = os.platform();
|
|
403
460
|
console.log(`
|
|
@@ -457,6 +514,7 @@ ${BOLD}Commands:${RESET}
|
|
|
457
514
|
${CYAN}status${RESET} Show container status
|
|
458
515
|
${CYAN}config${RESET} Show saved local config
|
|
459
516
|
${CYAN}password${RESET} Show first-run admin password (--clear to delete after reading)
|
|
517
|
+
${CYAN}reset-admin${RESET} Reset admin password (official recovery if password is lost)
|
|
460
518
|
${CYAN}uninstall${RESET} Remove container, image, data volume and local config
|
|
461
519
|
${CYAN}install-guide${RESET} Show Docker installation instructions for your platform
|
|
462
520
|
|
|
@@ -499,6 +557,7 @@ switch (cmd) {
|
|
|
499
557
|
break;
|
|
500
558
|
case 'status': cmdStatus(); break;
|
|
501
559
|
case 'config': cmdConfig(); break;
|
|
560
|
+
case 'reset-admin': cmdResetAdmin(); break;
|
|
502
561
|
case 'uninstall': cmdUninstall(parsed.flags); break;
|
|
503
562
|
case 'install-guide': cmdInstallGuide(); break;
|
|
504
563
|
case 'password':
|
package/package.json
CHANGED