Files
BetterDesk/web-nodejs/tests/bootstrapAdminCredentials.test.js
T
UNITRONIX 0bfecddd00 fix(docker): sync bootstrap admin password between Go and console (#385)
Fresh Docker installs without ADMIN_PASSWORD generated two different random
passwords: Go wrote /opt/rustdesk/.admin_credentials while the panel
authenticated against auth.db seeded by Node.js. Pre-bootstrap a shared
password in entrypoints before supervisord / server start.

Refs #385

Thanks: INSOLVE (Honorary); Marco Jakobs (@jacotec); MyNameisStitch (@MyNameisStitch); Redspin (@playerumpknow)
2026-08-24 15:08:35 +02:00

70 lines
2.4 KiB
JavaScript

'use strict';
/**
* Docker bootstrap-admin-credentials.sh — idempotent shared password (issue #385).
* Runs only when sh is available (Linux/macOS CI and Docker build hosts).
*/
const { spawnSync } = require('child_process');
const fs = require('fs');
const os = require('os');
const path = require('path');
const SCRIPT = path.join(__dirname, '..', '..', 'docker', 'bootstrap-admin-credentials.sh');
const shAvailable = process.platform !== 'win32';
(shAvailable ? describe : describe.skip)('bootstrap-admin-credentials.sh', () => {
let tmpDir;
beforeEach(() => {
tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'bd-bootstrap-'));
});
afterEach(() => {
fs.rmSync(tmpDir, { recursive: true, force: true });
});
function runBootstrap(extraEnv = {}) {
return spawnSync('sh', [SCRIPT], {
env: {
...process.env,
RUSTDESK_PATH: tmpDir,
DATA_DIR: path.join(tmpDir, 'data'),
...extraEnv,
},
encoding: 'utf8',
});
}
test('generates credentials file and exports matching env vars', () => {
const result = runBootstrap();
expect(result.status).toBe(0);
const credsFile = path.join(tmpDir, '.admin_credentials');
expect(fs.existsSync(credsFile)).toBe(true);
const content = fs.readFileSync(credsFile, 'utf8');
const match = content.match(/^Admin Password:\s*(.+)$/m);
expect(match).not.toBeNull();
expect(match[1].trim().length).toBeGreaterThan(0);
expect(result.stdout).toContain('Bootstrap admin credentials');
});
test('does not overwrite existing credentials file', () => {
const credsFile = path.join(tmpDir, '.admin_credentials');
fs.mkdirSync(tmpDir, { recursive: true });
fs.writeFileSync(credsFile, 'Admin Username: admin\nAdmin Password: existing-secret\n', { mode: 0o600 });
const first = runBootstrap();
expect(first.status).toBe(0);
expect(fs.readFileSync(credsFile, 'utf8')).toContain('existing-secret');
});
test('respects ADMIN_PASSWORD without writing a new file when env is set', () => {
const result = runBootstrap({ ADMIN_PASSWORD: 'preset-password-12345' });
expect(result.status).toBe(0);
const credsFile = path.join(tmpDir, '.admin_credentials');
expect(fs.existsSync(credsFile)).toBe(false);
});
});