mirror of
https://github.com/UNITRONIX/BetterDesk.git
synced 2026-09-10 17:45:42 +00:00
29d03492fb
Harden native, agent and Docker lifecycle paths with tracked update verification, rollback and preflight checks, safe uninstall semantics, and health verification. Add shared protocol tests, installer CI gates, and lifecycle documentation. Thanks: INSOLVE (Honorary); Marco Jakobs (@jacotec); MyNameisStitch (@MyNameisStitch); Redspin (@playerumpknow)
100 lines
3.6 KiB
JavaScript
100 lines
3.6 KiB
JavaScript
'use strict';
|
|
|
|
const fs = require('fs');
|
|
const os = require('os');
|
|
const path = require('path');
|
|
const {
|
|
validateDeployRequest,
|
|
deployServerBinaryAtomic,
|
|
buildAllowedDeployTargets,
|
|
resolveDeployScriptPath,
|
|
} = require('../lib/linuxServerBinaryDeploy');
|
|
|
|
const describeLinux = process.platform === 'linux' ? describe : describe.skip;
|
|
|
|
describeLinux('linuxServerBinaryDeploy', () => {
|
|
let tmpRoot;
|
|
let consoleRoot;
|
|
let serverRoot;
|
|
|
|
beforeEach(() => {
|
|
tmpRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'bd-deploy-'));
|
|
consoleRoot = path.join(tmpRoot, 'web-nodejs');
|
|
serverRoot = path.join(tmpRoot, 'betterdesk-server');
|
|
fs.mkdirSync(serverRoot, { recursive: true });
|
|
fs.writeFileSync(path.join(serverRoot, 'go.mod'), 'module example.com/test\n');
|
|
});
|
|
|
|
afterEach(() => {
|
|
fs.rmSync(tmpRoot, { recursive: true, force: true });
|
|
});
|
|
|
|
function writeBinary(filePath, size = 1024 * 1024) {
|
|
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
|
fs.writeFileSync(filePath, Buffer.alloc(size, 1));
|
|
}
|
|
|
|
test('validateDeployRequest accepts source under server root and allowed target', () => {
|
|
const source = path.join(serverRoot, 'betterdesk-server');
|
|
writeBinary(source);
|
|
const target = '/opt/rustdesk/betterdesk-server';
|
|
|
|
const validated = validateDeployRequest(source, target, {
|
|
consoleRoot,
|
|
projectRoot: tmpRoot,
|
|
serverSourceRoot: serverRoot,
|
|
});
|
|
|
|
expect(validated.sourceReal).toBe(path.resolve(source));
|
|
expect(validated.targetPath).toBe(path.resolve(target));
|
|
});
|
|
|
|
test('validateDeployRequest rejects source outside server root', () => {
|
|
const outside = path.join(tmpRoot, 'evil', 'betterdesk-server');
|
|
writeBinary(outside);
|
|
const target = '/opt/rustdesk/betterdesk-server';
|
|
|
|
expect(() => validateDeployRequest(outside, target, {
|
|
consoleRoot,
|
|
projectRoot: tmpRoot,
|
|
serverSourceRoot: serverRoot,
|
|
})).toThrow(/Source must be under/);
|
|
});
|
|
|
|
test('validateDeployRequest rejects disallowed target path', () => {
|
|
const source = path.join(serverRoot, 'betterdesk-server');
|
|
writeBinary(source);
|
|
|
|
expect(() => validateDeployRequest(source, '/tmp/betterdesk-server', {
|
|
consoleRoot,
|
|
projectRoot: tmpRoot,
|
|
serverSourceRoot: serverRoot,
|
|
})).toThrow(/Target path is not allowed/);
|
|
});
|
|
|
|
test('deployServerBinaryAtomic replaces target atomically', () => {
|
|
const targetDir = path.join(tmpRoot, 'bin');
|
|
const target = path.join(targetDir, 'betterdesk-server');
|
|
const source = path.join(serverRoot, 'betterdesk-server');
|
|
writeBinary(source);
|
|
fs.mkdirSync(targetDir, { recursive: true });
|
|
fs.writeFileSync(target, Buffer.from('old-binary'));
|
|
|
|
const result = deployServerBinaryAtomic(source, target);
|
|
expect(result.success).toBe(true);
|
|
expect(fs.readFileSync(target).length).toBe(1024 * 1024);
|
|
});
|
|
|
|
test('buildAllowedDeployTargets includes standard install paths', () => {
|
|
const targets = buildAllowedDeployTargets({ keysPath: '/opt/rustdesk' });
|
|
expect(targets.has('/opt/rustdesk/betterdesk-server')).toBe(true);
|
|
expect(targets.has('/opt/betterdesk/betterdesk-server')).toBe(true);
|
|
});
|
|
|
|
test('resolveDeployScriptPath points at panel helper script', () => {
|
|
expect(resolveDeployScriptPath(consoleRoot)).toBe(
|
|
path.join(consoleRoot, 'scripts/linux-deploy-server-binary.js')
|
|
);
|
|
});
|
|
});
|