import * as plugins from '../../plugins.js'; import type { OpsServer } from '../classes.opsserver.js'; import * as interfaces from '../../../ts_interfaces/index.js'; export class RemoteIngressHandler { public typedrouter = new plugins.typedrequest.TypedRouter(); constructor(private opsServerRef: OpsServer) { this.opsServerRef.typedrouter.addTypedRouter(this.typedrouter); this.registerHandlers(); } private registerHandlers(): void { // Get all remote ingress edges this.typedrouter.addTypedHandler( new plugins.typedrequest.TypedHandler( 'getRemoteIngresses', async (dataArg, toolsArg) => { const manager = this.opsServerRef.dcRouterRef.remoteIngressManager; if (!manager) { return { edges: [] }; } // Return edges without secrets, enriched with effective listen ports const edges = manager.getAllEdges().map((e) => ({ ...e, secret: '********', // Never expose secrets via API effectiveListenPorts: manager.getEffectiveListenPorts(e), })); return { edges }; }, ), ); // Create a new remote ingress edge this.typedrouter.addTypedHandler( new plugins.typedrequest.TypedHandler( 'createRemoteIngress', async (dataArg, toolsArg) => { const manager = this.opsServerRef.dcRouterRef.remoteIngressManager; const tunnelManager = this.opsServerRef.dcRouterRef.tunnelManager; if (!manager) { return { success: false, edge: null as any, }; } const edge = await manager.createEdge( dataArg.name, dataArg.listenPorts || [], dataArg.tags, ); // Sync allowed edges with the hub if (tunnelManager) { await tunnelManager.syncAllowedEdges(); } return { success: true, edge }; }, ), ); // Delete a remote ingress edge this.typedrouter.addTypedHandler( new plugins.typedrequest.TypedHandler( 'deleteRemoteIngress', async (dataArg, toolsArg) => { const manager = this.opsServerRef.dcRouterRef.remoteIngressManager; const tunnelManager = this.opsServerRef.dcRouterRef.tunnelManager; if (!manager) { return { success: false, message: 'RemoteIngress not configured' }; } const deleted = await manager.deleteEdge(dataArg.id); if (deleted && tunnelManager) { await tunnelManager.syncAllowedEdges(); } return { success: deleted, message: deleted ? undefined : 'Edge not found', }; }, ), ); // Update a remote ingress edge this.typedrouter.addTypedHandler( new plugins.typedrequest.TypedHandler( 'updateRemoteIngress', async (dataArg, toolsArg) => { const manager = this.opsServerRef.dcRouterRef.remoteIngressManager; const tunnelManager = this.opsServerRef.dcRouterRef.tunnelManager; if (!manager) { return { success: false, edge: null as any }; } const edge = await manager.updateEdge(dataArg.id, { name: dataArg.name, listenPorts: dataArg.listenPorts, enabled: dataArg.enabled, tags: dataArg.tags, }); if (!edge) { return { success: false, edge: null as any }; } // Sync allowed edges if enabled status changed if (tunnelManager && dataArg.enabled !== undefined) { await tunnelManager.syncAllowedEdges(); } return { success: true, edge: { ...edge, secret: '********' } }; }, ), ); // Regenerate secret for an edge this.typedrouter.addTypedHandler( new plugins.typedrequest.TypedHandler( 'regenerateRemoteIngressSecret', async (dataArg, toolsArg) => { const manager = this.opsServerRef.dcRouterRef.remoteIngressManager; const tunnelManager = this.opsServerRef.dcRouterRef.tunnelManager; if (!manager) { return { success: false, secret: '' }; } const secret = await manager.regenerateSecret(dataArg.id); if (!secret) { return { success: false, secret: '' }; } // Sync allowed edges since secret changed if (tunnelManager) { await tunnelManager.syncAllowedEdges(); } return { success: true, secret }; }, ), ); // Get runtime status of all edges this.typedrouter.addTypedHandler( new plugins.typedrequest.TypedHandler( 'getRemoteIngressStatus', async (dataArg, toolsArg) => { const tunnelManager = this.opsServerRef.dcRouterRef.tunnelManager; if (!tunnelManager) { return { statuses: [] }; } return { statuses: tunnelManager.getEdgeStatuses() }; }, ), ); } }