Files
BetterDesk/web-nodejs/scripts/linux-deploy-server-binary.js
T
UNITRONIX 87b0b21b0b fix(update): privileged Go server binary deploy from Linux panel
Hardened installs could not replace betterdesk-server in /opt/rustdesk
from Settings → Updates. Add a validated sudo deploy helper, extend
console update sudoers, and sync privileges before server deploy.

Fixes #183
2026-06-09 01:09:11 +02:00

86 lines
2.5 KiB
JavaScript
Executable File

#!/usr/bin/env node
'use strict';
/**
* Privileged Go server binary deploy (issue #182).
* Invoked via passwordless sudo from the panel update service.
*
* Reads a JSON payload from stdin:
* { "source": "...", "target": "...", "consoleRoot": "...", "serverSourceRoot": "..." }
*
* Or `--check` to verify the caller can run this script via sudo (exit 0).
*/
const fs = require('fs');
const path = require('path');
const config = require('../config/config');
const {
validateDeployRequest,
deployServerBinaryAtomic,
resolveServerSourceRoot,
} = require('../lib/linuxServerBinaryDeploy');
function readStdinPayload() {
if (process.stdin.isTTY) {
throw new Error('Expected JSON payload on stdin');
}
const data = fs.readFileSync(0, 'utf8').trim();
if (!data) {
throw new Error('Empty deploy payload');
}
return JSON.parse(data);
}
function runCheck() {
if (typeof process.getuid === 'function' && process.getuid() !== 0) {
throw new Error('Privileged deploy check must run as root (via sudo)');
}
process.stdout.write(JSON.stringify({ success: true, mode: 'check' }));
}
function runDeploy(payload) {
if (typeof process.getuid === 'function' && process.getuid() !== 0) {
throw new Error('Deploy must run as root (via sudo)');
}
const consoleRoot = payload.consoleRoot || path.join(__dirname, '..');
const projectRoot = payload.projectRoot || path.join(consoleRoot, '..');
const serverSourceRoot = payload.serverSourceRoot
|| resolveServerSourceRoot(consoleRoot, projectRoot);
const validated = validateDeployRequest(payload.source, payload.target, {
consoleRoot,
projectRoot,
serverSourceRoot,
keysPath: config.keysPath,
rustdeskDir: config.rustdeskDir,
extraTarget: process.env.BETTERDESK_SERVER_BINARY || null,
});
const result = deployServerBinaryAtomic(validated.sourceReal, validated.targetPath);
process.stdout.write(JSON.stringify({
success: result.success,
backupPath: result.backupPath || null,
error: result.error || null,
method: 'privileged',
targetPath: validated.targetPath,
}));
if (!result.success) {
process.exit(1);
}
}
try {
if (process.argv.includes('--check')) {
runCheck();
process.exit(0);
}
runDeploy(readStdinPayload());
} catch (err) {
process.stdout.write(JSON.stringify({
success: false,
error: err.message || String(err),
}));
process.exit(1);
}