import * as plugins from '../../plugins.js'; import type { OpsServer } from '../classes.opsserver.js'; import * as interfaces from '../../../ts_interfaces/index.js'; export class VpnHandler { constructor(private opsServerRef: OpsServer) { this.registerHandlers(); } private registerHandlers(): void { const viewRouter = this.opsServerRef.viewRouter; const adminRouter = this.opsServerRef.adminRouter; // ---- Read endpoints (viewRouter — valid identity required via middleware) ---- // Get all registered VPN clients viewRouter.addTypedHandler( new plugins.typedrequest.TypedHandler( 'getVpnClients', async (dataArg, toolsArg) => { const manager = this.opsServerRef.dcRouterRef.vpnManager; if (!manager) { return { clients: [] }; } const clients = manager.listClients().map((c) => ({ clientId: c.clientId, enabled: c.enabled, serverDefinedClientTags: c.serverDefinedClientTags, description: c.description, assignedIp: c.assignedIp, createdAt: c.createdAt, updatedAt: c.updatedAt, expiresAt: c.expiresAt, })); return { clients }; }, ), ); // Get VPN server status viewRouter.addTypedHandler( new plugins.typedrequest.TypedHandler( 'getVpnStatus', async (dataArg, toolsArg) => { const manager = this.opsServerRef.dcRouterRef.vpnManager; const vpnConfig = this.opsServerRef.dcRouterRef.options.vpnConfig; if (!manager) { return { status: { running: false, subnet: vpnConfig?.subnet || '10.8.0.0/24', wgListenPort: vpnConfig?.wgListenPort ?? 51820, serverPublicKeys: null, registeredClients: 0, connectedClients: 0, }, }; } const connected = await manager.getConnectedClients(); return { status: { running: manager.running, subnet: manager.getSubnet(), wgListenPort: vpnConfig?.wgListenPort ?? 51820, serverPublicKeys: manager.getServerPublicKeys(), registeredClients: manager.listClients().length, connectedClients: connected.length, }, }; }, ), ); // Get currently connected VPN clients viewRouter.addTypedHandler( new plugins.typedrequest.TypedHandler( 'getVpnConnectedClients', async (dataArg, toolsArg) => { const manager = this.opsServerRef.dcRouterRef.vpnManager; if (!manager) { return { connectedClients: [] }; } const connected = await manager.getConnectedClients(); return { connectedClients: connected.map((c) => ({ clientId: c.registeredClientId || c.clientId, assignedIp: c.assignedIp, connectedSince: c.connectedSince, bytesSent: c.bytesSent, bytesReceived: c.bytesReceived, transport: c.transportType, })), }; }, ), ); // ---- Write endpoints (adminRouter — admin identity required via middleware) ---- // Create a new VPN client adminRouter.addTypedHandler( new plugins.typedrequest.TypedHandler( 'createVpnClient', async (dataArg, toolsArg) => { const manager = this.opsServerRef.dcRouterRef.vpnManager; if (!manager) { return { success: false, message: 'VPN not configured' }; } try { const bundle = await manager.createClient({ clientId: dataArg.clientId, serverDefinedClientTags: dataArg.serverDefinedClientTags, description: dataArg.description, }); return { success: true, client: { clientId: bundle.entry.clientId, enabled: bundle.entry.enabled ?? true, serverDefinedClientTags: bundle.entry.serverDefinedClientTags, description: bundle.entry.description, assignedIp: bundle.entry.assignedIp, createdAt: Date.now(), updatedAt: Date.now(), expiresAt: bundle.entry.expiresAt, }, wireguardConfig: bundle.wireguardConfig, }; } catch (err: unknown) { return { success: false, message: (err as Error).message }; } }, ), ); // Update a VPN client's metadata adminRouter.addTypedHandler( new plugins.typedrequest.TypedHandler( 'updateVpnClient', async (dataArg, toolsArg) => { const manager = this.opsServerRef.dcRouterRef.vpnManager; if (!manager) { return { success: false, message: 'VPN not configured' }; } try { await manager.updateClient(dataArg.clientId, { description: dataArg.description, serverDefinedClientTags: dataArg.serverDefinedClientTags, }); return { success: true }; } catch (err: unknown) { return { success: false, message: (err as Error).message }; } }, ), ); // Delete a VPN client adminRouter.addTypedHandler( new plugins.typedrequest.TypedHandler( 'deleteVpnClient', async (dataArg, toolsArg) => { const manager = this.opsServerRef.dcRouterRef.vpnManager; if (!manager) { return { success: false, message: 'VPN not configured' }; } try { await manager.removeClient(dataArg.clientId); return { success: true }; } catch (err: unknown) { return { success: false, message: (err as Error).message }; } }, ), ); // Enable a VPN client adminRouter.addTypedHandler( new plugins.typedrequest.TypedHandler( 'enableVpnClient', async (dataArg, toolsArg) => { const manager = this.opsServerRef.dcRouterRef.vpnManager; if (!manager) { return { success: false, message: 'VPN not configured' }; } try { await manager.enableClient(dataArg.clientId); return { success: true }; } catch (err: unknown) { return { success: false, message: (err as Error).message }; } }, ), ); // Disable a VPN client adminRouter.addTypedHandler( new plugins.typedrequest.TypedHandler( 'disableVpnClient', async (dataArg, toolsArg) => { const manager = this.opsServerRef.dcRouterRef.vpnManager; if (!manager) { return { success: false, message: 'VPN not configured' }; } try { await manager.disableClient(dataArg.clientId); return { success: true }; } catch (err: unknown) { return { success: false, message: (err as Error).message }; } }, ), ); // Rotate a VPN client's keys adminRouter.addTypedHandler( new plugins.typedrequest.TypedHandler( 'rotateVpnClientKey', async (dataArg, toolsArg) => { const manager = this.opsServerRef.dcRouterRef.vpnManager; if (!manager) { return { success: false, message: 'VPN not configured' }; } try { const bundle = await manager.rotateClientKey(dataArg.clientId); return { success: true, wireguardConfig: bundle.wireguardConfig, }; } catch (err: unknown) { return { success: false, message: (err as Error).message }; } }, ), ); // Export a VPN client config adminRouter.addTypedHandler( new plugins.typedrequest.TypedHandler( 'exportVpnClientConfig', async (dataArg, toolsArg) => { const manager = this.opsServerRef.dcRouterRef.vpnManager; if (!manager) { return { success: false, message: 'VPN not configured' }; } try { const config = await manager.exportClientConfig(dataArg.clientId, dataArg.format); return { success: true, config }; } catch (err: unknown) { return { success: false, message: (err as Error).message }; } }, ), ); // Get telemetry for a specific VPN client viewRouter.addTypedHandler( new plugins.typedrequest.TypedHandler( 'getVpnClientTelemetry', async (dataArg, toolsArg) => { const manager = this.opsServerRef.dcRouterRef.vpnManager; if (!manager) { return { success: false, message: 'VPN not configured' }; } try { const telemetry = await manager.getClientTelemetry(dataArg.clientId); if (!telemetry) { return { success: false, message: 'Client not found or not connected' }; } return { success: true, telemetry: { clientId: telemetry.clientId, assignedIp: telemetry.assignedIp, bytesSent: telemetry.bytesSent, bytesReceived: telemetry.bytesReceived, packetsDropped: telemetry.packetsDropped, bytesDropped: telemetry.bytesDropped, lastKeepaliveAt: telemetry.lastKeepaliveAt, keepalivesReceived: telemetry.keepalivesReceived, rateLimitBytesPerSec: telemetry.rateLimitBytesPerSec, burstBytes: telemetry.burstBytes, }, }; } catch (err: unknown) { return { success: false, message: (err as Error).message }; } }, ), ); } }