mirror of
https://github.com/UNITRONIX/BetterDesk.git
synced 2026-09-10 09:35:39 +00:00
8579e88be4
Add PUBLIC_SERVER_ID, PUBLIC_RELAY_SERVER, and PUBLIC_API_URL with Settings UI, unified endpoint resolution across Dashboard/Keys, and fallbacks via PANEL_PUBLIC_HOST.
219 lines
5.9 KiB
JavaScript
219 lines
5.9 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');
|
|
const conn = require('./agentBundleConnection');
|
|
|
|
/**
|
|
* 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;
|
|
}
|
|
}
|
|
|
|
function normalizeHostInput(serverHost) {
|
|
if (!serverHost) {
|
|
return 'localhost';
|
|
}
|
|
const normalized = conn.normalizeServerHost(serverHost);
|
|
return normalized.valid ? normalized.host : String(serverHost).trim() || 'localhost';
|
|
}
|
|
|
|
function apiUrlForHost(host, useHttps) {
|
|
const port = String(config.goApiPort || config.apiPort || 21114);
|
|
const scheme = useHttps ? 'https' : 'http';
|
|
if (useHttps && port === '443') {
|
|
return `https://${host}`;
|
|
}
|
|
if (!useHttps && port === '80') {
|
|
return `http://${host}`;
|
|
}
|
|
return `${scheme}://${host}:${port}`;
|
|
}
|
|
|
|
/**
|
|
* RustDesk client config JSON payload: { host, relay, api, key }
|
|
* @param {{ host: string, relay?: string, api?: string } | string} endpointsOrHost
|
|
* @param {{ useHttps?: boolean }} [options]
|
|
*/
|
|
function buildRustDeskConfigPayload(endpointsOrHost, options = {}) {
|
|
const pubKey = getPublicKey() || '';
|
|
const useHttps = options.useHttps ?? conn.defaultUseHttps();
|
|
|
|
if (typeof endpointsOrHost === 'string') {
|
|
const host = normalizeHostInput(endpointsOrHost);
|
|
return {
|
|
host,
|
|
relay: host,
|
|
api: apiUrlForHost(host, useHttps),
|
|
key: pubKey,
|
|
};
|
|
}
|
|
|
|
const host = normalizeHostInput(endpointsOrHost.host);
|
|
const relay = normalizeHostInput(endpointsOrHost.relay || host);
|
|
const api = endpointsOrHost.api || apiUrlForHost(host, useHttps);
|
|
return {
|
|
host,
|
|
relay,
|
|
api,
|
|
key: pubKey,
|
|
};
|
|
}
|
|
|
|
/**
|
|
* QR / deep-link format: rustdesk://config/<standard-base64-json>
|
|
*/
|
|
function encodeRustDeskConfigUri(payload) {
|
|
const jsonStr = JSON.stringify(payload);
|
|
const b64 = Buffer.from(jsonStr).toString('base64');
|
|
return `rustdesk://config/${b64}`;
|
|
}
|
|
|
|
/**
|
|
* CLI / Import format for `rustdesk.exe --config`: reverse(base64(json)) without padding.
|
|
*/
|
|
function encodeRustDeskCliConfigString(payload) {
|
|
const jsonStr = JSON.stringify(payload);
|
|
let b64 = Buffer.from(jsonStr).toString('base64');
|
|
b64 = b64.replace(/=+$/, '');
|
|
return b64.split('').reverse().join('');
|
|
}
|
|
|
|
/**
|
|
* Generate QR code containing the RustDesk configuration URI.
|
|
* Format: rustdesk://config/<base64-encoded-json>
|
|
* @param {{ host: string, relay?: string, api?: string } | string} endpointsOrHost
|
|
*/
|
|
async function getServerConfigQR(endpointsOrHost) {
|
|
const pubKey = getPublicKey();
|
|
if (!pubKey) {
|
|
return null;
|
|
}
|
|
|
|
try {
|
|
const configPayload = buildRustDeskConfigPayload(endpointsOrHost);
|
|
const configUri = encodeRustDeskConfigUri(configPayload);
|
|
|
|
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;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Build the RustDesk client fields operators need to enter manually.
|
|
* @param {{ host: string, relay?: string, api?: string } | string} endpointsOrHost
|
|
*/
|
|
function getClientConfig(endpointsOrHost) {
|
|
const payload = buildRustDeskConfigPayload(endpointsOrHost);
|
|
const publicKey = payload.key;
|
|
|
|
return {
|
|
server_id: payload.host,
|
|
relay_server: payload.relay,
|
|
api_url: payload.api,
|
|
public_key: publicKey,
|
|
has_public_key: Boolean(publicKey),
|
|
deploy_config_string: publicKey ? encodeRustDeskCliConfigString(payload) : '',
|
|
config_uri: publicKey ? encodeRustDeskConfigUri(payload) : '',
|
|
};
|
|
}
|
|
|
|
/**
|
|
* 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,
|
|
getClientConfig,
|
|
getServerConfig,
|
|
buildRustDeskConfigPayload,
|
|
encodeRustDeskConfigUri,
|
|
encodeRustDeskCliConfigString,
|
|
normalizeHostInput,
|
|
apiUrlForHost,
|
|
};
|