Files
BetterDesk/web-nodejs/services/agentBundleConnection.js
UNITRONIX 6537c994f5 Enhance support agent functionality and improve API integration
- Added a new method to check if the agent has an active CDAP session, improving connection status reporting.
- Updated the SendHelpRequest function to utilize the engine for sending help requests, enhancing the request handling process.
- Refactored health check methods to include the Go management API, replacing the console health checks for better integration.
- Improved branding logo handling by introducing a PNG validation function, ensuring only valid images are used.
- Updated UI elements and localization strings to reflect changes in API endpoints and improve user experience.
2026-06-04 15:39:21 +02:00

136 lines
4.1 KiB
JavaScript

/**
* Connection profile helpers for the support-agent bundle generator.
* Operators supply a public hostname/IP; the console injects API URLs,
* server public key, and a backend-issued enrollment token.
*/
'use strict';
const config = require('../config/config');
const HOST_RE = /^[a-zA-Z0-9](?:[a-zA-Z0-9.-]{0,253}[a-zA-Z0-9])?$/;
const IP_V4_RE = /^(?:\d{1,3}\.){3}\d{1,3}$/;
function clip(s, max) {
if (typeof s !== 'string') return '';
return s.trim().slice(0, max);
}
/** Default API port from console config (BetterDesk Go API). */
function defaultApiPort() {
try {
const raw = config.hbbsApiUrl || config.betterdeskApiUrl || '';
const u = new URL(raw.includes('://') ? raw : `http://${raw}`);
if (u.port) return u.port;
return u.protocol === 'https:' ? '443' : '21114';
} catch (_) {
return '21114';
}
}
/** CDAP WebSocket gateway port (BetterDesk Go server). */
function defaultCdapPort() {
const fromEnv = parseInt(process.env.CDAP_PORT || process.env.SIGNAL_PORT, 10);
if (Number.isFinite(fromEnv) && fromEnv > 0) return fromEnv;
return 21122;
}
function formatOrigin(scheme, hostPart, port) {
const omitPort = (scheme === 'https' && port === 443) || (scheme === 'http' && port === 80);
return omitPort ? `${scheme}://${hostPart}` : `${scheme}://${hostPart}:${port}`;
}
/** Suggested host prefill from local server config. */
function defaultServerHost() {
try {
const raw = config.hbbsApiUrl || config.betterdeskApiUrl || '';
const u = new URL(raw.includes('://') ? raw : `http://${raw}`);
return u.hostname || '';
} catch (_) {
return '';
}
}
function defaultUseHttps() {
try {
const raw = config.hbbsApiUrl || config.betterdeskApiUrl || '';
const u = new URL(raw.includes('://') ? raw : `http://${raw}`);
return u.protocol === 'https:';
} catch (_) {
return false;
}
}
/**
* Normalize operator input: strip scheme/path/port — keep hostname or IPv4.
*/
function normalizeServerHost(input) {
let host = clip(input, 253);
if (!host) return { valid: false, error: 'server_host_required', host: '' };
host = host.replace(/^https?:\/\//i, '');
host = host.split('/')[0];
host = host.split(':')[0];
host = host.replace(/^\[|\]$/g, '');
const valid = HOST_RE.test(host) || IP_V4_RE.test(host);
if (!valid) {
return { valid: false, error: 'server_host_invalid', host: '' };
}
return { valid: true, host };
}
/**
* Build server { address, api_url, cdap/console ports and URLs } from host + TLS.
*/
function buildServerUrls(host, useHttps, apiPort) {
const port = String(apiPort || defaultApiPort());
const scheme = useHttps ? 'https' : 'http';
const wsScheme = useHttps ? 'wss' : 'ws';
const omitPort = (scheme === 'https' && port === '443') || (scheme === 'http' && port === '80');
const hostPart = host.includes(':') ? `[${host}]` : host;
const authority = omitPort ? hostPart : `${hostPart}:${port}`;
const origin = `${scheme}://${authority}`;
const cdapPort = defaultCdapPort();
const cdapUrl = `${wsScheme}://${hostPart}:${cdapPort}/cdap`;
return {
address: origin,
api_url: `${origin}/api`,
cdap_port: cdapPort,
cdap_url: cdapUrl,
};
}
function hostFromBranding(branding) {
if (branding?.server_host) return branding.server_host;
const addr = branding?.server?.address;
if (!addr) return '';
try {
return new URL(addr).hostname;
} catch (_) {
return String(addr).replace(/^https?:\/\//i, '').split(/[/:]/)[0];
}
}
function tlsFromBranding(branding) {
if (typeof branding?.use_https === 'boolean') return branding.use_https;
const addr = branding?.server?.address || '';
return addr.startsWith('https://');
}
function connectionFingerprint(branding) {
return `${hostFromBranding(branding)}|${tlsFromBranding(branding)}`;
}
module.exports = {
defaultApiPort,
defaultCdapPort,
defaultServerHost,
defaultUseHttps,
normalizeServerHost,
buildServerUrls,
connectionFingerprint,
};