mirror of
https://github.com/UNITRONIX/BetterDesk.git
synced 2026-09-10 17:45:42 +00:00
0496b1dbc4
Add RustDesk-compatible client API and telemetry support and introduce a single-container Docker build. New client_api_handlers.go implements /api/login, /api/login-options, /api/logout, /api/currentUser, /api/ab, /api/heartbeat, /api/sysinfo and /api/sysinfo_ver with TOTP flow and an in-memory TFA session store; auth middleware and Server registration updated accordingly. Database interface and SQLite/Postgres implementations gain UpdatePeerSysinfo (with tests), audit actions for sysinfo, and handleGetPeer now returns live_online/live_status. Also add Dockerfile, docker-compose.single.yml, supervisord entrypoint, UI fixes (QR color inversion, 403 error view), labels file, README updates, and other ancillary changes. Co-Authored-By: MrBrodacz - Design <215021251+MrBrodacz2025@users.noreply.github.com> Co-Authored-By: boruto79 <176351662+boruto79@users.noreply.github.com> Co-Authored-By: marcosacramento <marcosacramento@gmail.com> Co-Authored-By: Charles Olivier Savignac <1275666+sircharlo@users.noreply.github.com>
136 lines
3.4 KiB
JavaScript
136 lines
3.4 KiB
JavaScript
/**
|
|
* BetterDesk Console - Key Service
|
|
* Reads public key and API key from filesystem
|
|
*/
|
|
|
|
const fs = require('fs');
|
|
const QRCode = require('qrcode');
|
|
const config = require('../config/config');
|
|
|
|
/**
|
|
* Read public key from file
|
|
*/
|
|
function getPublicKey() {
|
|
try {
|
|
if (fs.existsSync(config.pubKeyPath)) {
|
|
return fs.readFileSync(config.pubKeyPath, 'utf8').trim();
|
|
}
|
|
return null;
|
|
} catch (err) {
|
|
console.warn('Could not read public key:', err.message);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get API key (masked for display)
|
|
*/
|
|
function getApiKey(masked = true) {
|
|
try {
|
|
if (fs.existsSync(config.apiKeyPath)) {
|
|
const key = fs.readFileSync(config.apiKeyPath, 'utf8').trim();
|
|
if (masked && key.length > 8) {
|
|
return key.substring(0, 4) + '****' + key.substring(key.length - 4);
|
|
}
|
|
return key;
|
|
}
|
|
return null;
|
|
} catch (err) {
|
|
console.warn('Could not read API key:', err.message);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Generate QR code containing the RustDesk configuration URI.
|
|
* Format: rustdesk://config/<base64-encoded-json>
|
|
* The JSON contains: { host, relay, api, key }
|
|
* @param {string} serverHost - server host/IP used for the config
|
|
*/
|
|
async function getServerConfigQR(serverHost) {
|
|
const pubKey = getPublicKey();
|
|
if (!pubKey) {
|
|
return null;
|
|
}
|
|
|
|
try {
|
|
const apiKey = getApiKey(false); // unmasked
|
|
const configPayload = {
|
|
host: serverHost || 'localhost',
|
|
relay: serverHost || 'localhost',
|
|
api: `http://${serverHost || 'localhost'}:${config.apiPort}`,
|
|
key: pubKey
|
|
};
|
|
if (apiKey) {
|
|
configPayload.key = pubKey;
|
|
}
|
|
const jsonStr = JSON.stringify(configPayload);
|
|
const b64 = Buffer.from(jsonStr).toString('base64');
|
|
const configUri = `rustdesk://config/${b64}`;
|
|
|
|
const qrDataUrl = await QRCode.toDataURL(configUri, {
|
|
errorCorrectionLevel: 'M',
|
|
type: 'image/png',
|
|
width: 256,
|
|
margin: 2,
|
|
color: {
|
|
dark: '#000000',
|
|
light: '#ffffff'
|
|
}
|
|
});
|
|
return qrDataUrl;
|
|
} catch (err) {
|
|
console.warn('Could not generate config QR code:', err.message);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Generate QR code for public key (legacy — raw key text)
|
|
*/
|
|
async function getPublicKeyQR() {
|
|
const pubKey = getPublicKey();
|
|
if (!pubKey) {
|
|
return null;
|
|
}
|
|
|
|
try {
|
|
const qrDataUrl = await QRCode.toDataURL(pubKey, {
|
|
errorCorrectionLevel: 'M',
|
|
type: 'image/png',
|
|
width: 256,
|
|
margin: 2,
|
|
color: {
|
|
dark: '#000000',
|
|
light: '#ffffff'
|
|
}
|
|
});
|
|
return qrDataUrl;
|
|
} catch (err) {
|
|
console.warn('Could not generate QR code:', err.message);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get server configuration info
|
|
*/
|
|
function getServerConfig() {
|
|
return {
|
|
publicKey: getPublicKey(),
|
|
apiKeyMasked: getApiKey(true),
|
|
hbbsApiUrl: config.hbbsApiUrl,
|
|
dbPath: config.dbPath,
|
|
pubKeyPath: config.pubKeyPath,
|
|
apiKeyPath: config.apiKeyPath
|
|
};
|
|
}
|
|
|
|
module.exports = {
|
|
getPublicKey,
|
|
getApiKey,
|
|
getPublicKeyQR,
|
|
getServerConfigQR,
|
|
getServerConfig
|
|
};
|