191 lines
6.4 KiB
TypeScript
191 lines
6.4 KiB
TypeScript
import * as plugins from '../../plugins.js';
|
|
import * as paths from '../../paths.js';
|
|
import type { OpsServer } from '../classes.opsserver.js';
|
|
import * as interfaces from '../../../ts_interfaces/index.js';
|
|
|
|
export class ConfigHandler {
|
|
public typedrouter = new plugins.typedrequest.TypedRouter();
|
|
|
|
constructor(private opsServerRef: OpsServer) {
|
|
// Add this handler's router to the parent
|
|
this.opsServerRef.typedrouter.addTypedRouter(this.typedrouter);
|
|
this.registerHandlers();
|
|
}
|
|
|
|
private registerHandlers(): void {
|
|
// Get Configuration Handler (read-only)
|
|
this.typedrouter.addTypedHandler(
|
|
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_GetConfiguration>(
|
|
'getConfiguration',
|
|
async (dataArg, toolsArg) => {
|
|
const config = await this.getConfiguration();
|
|
return {
|
|
config,
|
|
section: dataArg.section,
|
|
};
|
|
}
|
|
)
|
|
);
|
|
}
|
|
|
|
private async getConfiguration(): Promise<interfaces.requests.IConfigData> {
|
|
const dcRouter = this.opsServerRef.dcRouterRef;
|
|
const opts = dcRouter.options;
|
|
const resolvedPaths = dcRouter.resolvedPaths;
|
|
|
|
// --- System ---
|
|
const storageBackend: 'filesystem' | 'custom' | 'memory' = opts.storage?.readFunction
|
|
? 'custom'
|
|
: opts.storage?.fsPath
|
|
? 'filesystem'
|
|
: 'memory';
|
|
|
|
const system: interfaces.requests.IConfigData['system'] = {
|
|
baseDir: resolvedPaths.dcrouterHomeDir,
|
|
dataDir: resolvedPaths.dataDir,
|
|
publicIp: opts.publicIp || null,
|
|
proxyIps: opts.proxyIps || [],
|
|
uptime: Math.floor(process.uptime()),
|
|
storageBackend,
|
|
storagePath: opts.storage?.fsPath || null,
|
|
};
|
|
|
|
// --- SmartProxy ---
|
|
let acmeInfo: interfaces.requests.IConfigData['smartProxy']['acme'] = null;
|
|
if (opts.smartProxyConfig?.acme) {
|
|
const acme = opts.smartProxyConfig.acme;
|
|
acmeInfo = {
|
|
enabled: acme.enabled !== false,
|
|
accountEmail: acme.accountEmail || '',
|
|
useProduction: acme.useProduction !== false,
|
|
autoRenew: acme.autoRenew !== false,
|
|
renewThresholdDays: acme.renewThresholdDays || 30,
|
|
};
|
|
}
|
|
|
|
let routeCount = 0;
|
|
if (dcRouter.routeConfigManager) {
|
|
try {
|
|
const merged = await dcRouter.routeConfigManager.getMergedRoutes();
|
|
routeCount = merged.routes.length;
|
|
} catch {
|
|
routeCount = opts.smartProxyConfig?.routes?.length || 0;
|
|
}
|
|
} else if (opts.smartProxyConfig?.routes) {
|
|
routeCount = opts.smartProxyConfig.routes.length;
|
|
}
|
|
|
|
const smartProxy: interfaces.requests.IConfigData['smartProxy'] = {
|
|
enabled: !!dcRouter.smartProxy,
|
|
routeCount,
|
|
acme: acmeInfo,
|
|
};
|
|
|
|
// --- Email ---
|
|
let emailDomains: string[] = [];
|
|
if (dcRouter.emailServer && (dcRouter.emailServer as any).domainRegistry) {
|
|
emailDomains = (dcRouter.emailServer as any).domainRegistry.getAllDomains();
|
|
} else if (opts.emailConfig?.domains) {
|
|
emailDomains = opts.emailConfig.domains.map((d: any) =>
|
|
typeof d === 'string' ? d : d.domain
|
|
);
|
|
}
|
|
|
|
let portMapping: Record<string, number> | null = null;
|
|
if (opts.emailPortConfig?.portMapping) {
|
|
portMapping = {};
|
|
for (const [ext, int] of Object.entries(opts.emailPortConfig.portMapping)) {
|
|
portMapping[String(ext)] = int as number;
|
|
}
|
|
}
|
|
|
|
const email: interfaces.requests.IConfigData['email'] = {
|
|
enabled: !!dcRouter.emailServer,
|
|
ports: opts.emailConfig?.ports || [],
|
|
portMapping,
|
|
hostname: opts.emailConfig?.hostname || null,
|
|
domains: emailDomains,
|
|
emailRouteCount: opts.emailConfig?.routes?.length || 0,
|
|
receivedEmailsPath: opts.emailPortConfig?.receivedEmailsPath || null,
|
|
};
|
|
|
|
// --- DNS ---
|
|
const dnsRecords = (opts.dnsRecords || []).map(r => ({
|
|
name: r.name,
|
|
type: r.type,
|
|
value: r.value,
|
|
ttl: r.ttl,
|
|
}));
|
|
|
|
const dns: interfaces.requests.IConfigData['dns'] = {
|
|
enabled: !!dcRouter.dnsServer,
|
|
port: 53,
|
|
nsDomains: opts.dnsNsDomains || [],
|
|
scopes: opts.dnsScopes || [],
|
|
recordCount: dnsRecords.length,
|
|
records: dnsRecords,
|
|
dnsChallenge: !!opts.dnsChallenge?.cloudflareApiKey,
|
|
};
|
|
|
|
// --- TLS ---
|
|
let tlsSource: 'acme' | 'static' | 'none' = 'none';
|
|
if (opts.tls?.certPath && opts.tls?.keyPath) {
|
|
tlsSource = 'static';
|
|
} else if (opts.smartProxyConfig?.acme?.enabled !== false && opts.smartProxyConfig?.acme) {
|
|
tlsSource = 'acme';
|
|
}
|
|
|
|
const tls: interfaces.requests.IConfigData['tls'] = {
|
|
contactEmail: opts.tls?.contactEmail || opts.smartProxyConfig?.acme?.accountEmail || null,
|
|
domain: opts.tls?.domain || null,
|
|
source: tlsSource,
|
|
certPath: opts.tls?.certPath || null,
|
|
keyPath: opts.tls?.keyPath || null,
|
|
};
|
|
|
|
// --- Cache ---
|
|
const cacheConfig = opts.cacheConfig;
|
|
const cache: interfaces.requests.IConfigData['cache'] = {
|
|
enabled: cacheConfig?.enabled !== false,
|
|
storagePath: cacheConfig?.storagePath || resolvedPaths.defaultTsmDbPath,
|
|
dbName: cacheConfig?.dbName || 'dcrouter',
|
|
defaultTTLDays: cacheConfig?.defaultTTLDays || 30,
|
|
cleanupIntervalHours: cacheConfig?.cleanupIntervalHours || 1,
|
|
ttlConfig: cacheConfig?.ttlConfig ? { ...cacheConfig.ttlConfig } as Record<string, number> : {},
|
|
};
|
|
|
|
// --- RADIUS ---
|
|
const radiusCfg = opts.radiusConfig;
|
|
const radius: interfaces.requests.IConfigData['radius'] = {
|
|
enabled: !!dcRouter.radiusServer,
|
|
authPort: radiusCfg?.authPort || null,
|
|
acctPort: radiusCfg?.acctPort || null,
|
|
bindAddress: radiusCfg?.bindAddress || null,
|
|
clientCount: radiusCfg?.clients?.length || 0,
|
|
vlanDefaultVlan: radiusCfg?.vlanAssignment?.defaultVlan ?? null,
|
|
vlanAllowUnknownMacs: radiusCfg?.vlanAssignment?.allowUnknownMacs ?? null,
|
|
vlanMappingCount: radiusCfg?.vlanAssignment?.mappings?.length || 0,
|
|
};
|
|
|
|
// --- Remote Ingress ---
|
|
const riCfg = opts.remoteIngressConfig;
|
|
const remoteIngress: interfaces.requests.IConfigData['remoteIngress'] = {
|
|
enabled: !!dcRouter.remoteIngressManager,
|
|
tunnelPort: riCfg?.tunnelPort || null,
|
|
hubDomain: riCfg?.hubDomain || null,
|
|
tlsConfigured: !!(riCfg?.tls?.certPath && riCfg?.tls?.keyPath),
|
|
};
|
|
|
|
return {
|
|
system,
|
|
smartProxy,
|
|
email,
|
|
dns,
|
|
tls,
|
|
cache,
|
|
radius,
|
|
remoteIngress,
|
|
};
|
|
}
|
|
}
|