import type DcRouter from '../classes.dcrouter.js'; import * as plugins from '../plugins.js'; import * as paths from '../paths.js'; import * as handlers from './handlers/index.js'; import * as interfaces from '../../ts_interfaces/index.js'; import { requireValidIdentity, requireAdminIdentity } from './helpers/guards.js'; export class OpsServer { public dcRouterRef: DcRouter; public server: plugins.typedserver.utilityservers.UtilityWebsiteServer; // Main TypedRouter — unauthenticated endpoints (login/logout/verify) and own-auth handlers public typedrouter = new plugins.typedrequest.TypedRouter(); // Auth-enforced routers — middleware validates identity before any handler runs public viewRouter = new plugins.typedrequest.TypedRouter<{ request: { identity: interfaces.data.IIdentity } }>(); public adminRouter = new plugins.typedrequest.TypedRouter<{ request: { identity: interfaces.data.IIdentity } }>(); // Handler instances public adminHandler: handlers.AdminHandler; private configHandler: handlers.ConfigHandler; private logsHandler: handlers.LogsHandler; private securityHandler: handlers.SecurityHandler; private statsHandler: handlers.StatsHandler; private radiusHandler: handlers.RadiusHandler; private emailOpsHandler: handlers.EmailOpsHandler; private certificateHandler: handlers.CertificateHandler; private remoteIngressHandler: handlers.RemoteIngressHandler; private routeManagementHandler: handlers.RouteManagementHandler; private apiTokenHandler: handlers.ApiTokenHandler; constructor(dcRouterRefArg: DcRouter) { this.dcRouterRef = dcRouterRefArg; // Add our typedrouter to the dcRouter's main typedrouter this.dcRouterRef.typedrouter.addTypedRouter(this.typedrouter); } public async start() { this.server = new plugins.typedserver.utilityservers.UtilityWebsiteServer({ domain: 'localhost', feedMetadata: null, serveDir: paths.distServe, }); // The server has a built-in typedrouter at /typedrequest // Add the main dcRouter typedrouter to the server's typedrouter this.server.typedrouter.addTypedRouter(this.dcRouterRef.typedrouter); // Set up handlers await this.setupHandlers(); await this.server.start(3000); } /** * Set up all TypedRequest handlers */ private async setupHandlers(): Promise { // AdminHandler must be initialized first (JWT setup needed for guards) this.adminHandler = new handlers.AdminHandler(this); await this.adminHandler.initialize(); // viewRouter middleware: requires valid identity (any logged-in user) this.viewRouter.addMiddleware(async (typedRequest) => { await requireValidIdentity(this.adminHandler, typedRequest.request); }); // adminRouter middleware: requires admin identity this.adminRouter.addMiddleware(async (typedRequest) => { await requireAdminIdentity(this.adminHandler, typedRequest.request); }); // Connect auth routers to the main typedrouter this.typedrouter.addTypedRouter(this.viewRouter); this.typedrouter.addTypedRouter(this.adminRouter); // Instantiate all handlers — they self-register with the appropriate router this.configHandler = new handlers.ConfigHandler(this); this.logsHandler = new handlers.LogsHandler(this); this.securityHandler = new handlers.SecurityHandler(this); this.statsHandler = new handlers.StatsHandler(this); this.radiusHandler = new handlers.RadiusHandler(this); this.emailOpsHandler = new handlers.EmailOpsHandler(this); this.certificateHandler = new handlers.CertificateHandler(this); this.remoteIngressHandler = new handlers.RemoteIngressHandler(this); this.routeManagementHandler = new handlers.RouteManagementHandler(this); this.apiTokenHandler = new handlers.ApiTokenHandler(this); console.log('✅ OpsServer TypedRequest handlers initialized'); } public async stop() { // Clean up log handler streams and push destination before stopping the server if (this.logsHandler) { this.logsHandler.cleanup(); } if (this.server) { await this.server.stop(); } } }