import type { Request, Response, Router } from "express"; import { SystemCrypto } from "../../utils/system-crypto.js"; import { sshLogger } from "../../utils/logger.js"; import { createCurrentHostResolutionRepository } from "../repositories/factory.js"; export function registerHostInternalRoutes(router: Router): void { /** * @openapi * /host/db/host/internal: * get: * summary: Get internal SSH host data * description: Returns internal SSH host data for autostart tunnels. Requires internal auth token. * tags: * - SSH * responses: * 200: * description: A list of autostart hosts. * 403: * description: Forbidden. * 500: * description: Failed to fetch autostart SSH data. */ router.get("/db/host/internal", async (req: Request, res: Response) => { try { const internalToken = req.headers["x-internal-auth-token"]; const systemCrypto = SystemCrypto.getInstance(); const expectedToken = await systemCrypto.getInternalAuthToken(); if (internalToken !== expectedToken) { sshLogger.warn( "Unauthorized attempt to access internal SSH host endpoint", { source: req.ip, userAgent: req.headers["user-agent"], providedToken: internalToken ? "present" : "missing", }, ); return res.status(403).json({ error: "Forbidden" }); } } catch (error) { sshLogger.error("Failed to validate internal auth token", error); return res.status(500).json({ error: "Internal server error" }); } try { const autostartHosts = await createCurrentHostResolutionRepository().listHostsWithTunnelConnections(); const result = autostartHosts .map((host) => { const tunnelConnections = host.tunnelConnections ? JSON.parse(host.tunnelConnections) : []; const hasAutoStartTunnels = tunnelConnections.some( (tunnel: Record) => tunnel.autoStart, ); if (!hasAutoStartTunnels) { return null; } return { id: host.id, userId: host.userId, name: host.name || `autostart-${host.id}`, ip: host.ip, port: host.port, username: host.username, authType: host.authType, keyType: host.keyType, credentialId: host.credentialId, enableTunnel: true, tunnelConnections: tunnelConnections.filter( (tunnel: Record) => tunnel.autoStart, ), pin: !!host.pin, enableTerminal: !!host.enableTerminal, enableFileManager: host.enableFileManager !== false, showTerminalInSidebar: !!host.showTerminalInSidebar, showFileManagerInSidebar: !!host.showFileManagerInSidebar, showTunnelInSidebar: !!host.showTunnelInSidebar, showDockerInSidebar: !!host.showDockerInSidebar, showServerStatsInSidebar: !!host.showServerStatsInSidebar, tags: ["autostart"], }; }) .filter(Boolean); res.json(result); } catch (err) { sshLogger.error("Failed to fetch autostart SSH data", err); res.status(500).json({ error: "Failed to fetch autostart SSH data" }); } }); /** * @openapi * /host/db/host/internal/all: * get: * summary: Get all internal SSH host data * description: Returns all internal SSH host data. Requires internal auth token. * tags: * - SSH * responses: * 200: * description: A list of all hosts. * 401: * description: Invalid or missing internal authentication token. * 500: * description: Failed to fetch all hosts. */ router.get("/db/host/internal/all", async (req: Request, res: Response) => { try { const internalToken = req.headers["x-internal-auth-token"]; if (!internalToken) { return res .status(401) .json({ error: "Internal authentication token required" }); } const systemCrypto = SystemCrypto.getInstance(); const expectedToken = await systemCrypto.getInternalAuthToken(); if (internalToken !== expectedToken) { return res .status(401) .json({ error: "Invalid internal authentication token" }); } const allHosts = await createCurrentHostResolutionRepository().listAllHosts(); const result = allHosts.map((host) => { const tunnelConnections = host.tunnelConnections ? JSON.parse(host.tunnelConnections) : []; return { id: host.id, userId: host.userId, name: host.name || `${host.username}@${host.ip}`, ip: host.ip, port: host.port, username: host.username, authType: host.authType, keyType: host.keyType, credentialId: host.credentialId, enableTunnel: !!host.enableTunnel, tunnelConnections: tunnelConnections, pin: !!host.pin, enableTerminal: !!host.enableTerminal, enableFileManager: host.enableFileManager !== false, showTerminalInSidebar: !!host.showTerminalInSidebar, showFileManagerInSidebar: !!host.showFileManagerInSidebar, showTunnelInSidebar: !!host.showTunnelInSidebar, showDockerInSidebar: !!host.showDockerInSidebar, showServerStatsInSidebar: !!host.showServerStatsInSidebar, defaultPath: host.defaultPath, createdAt: host.createdAt, updatedAt: host.updatedAt, }; }); res.json(result); } catch (err) { sshLogger.error("Failed to fetch all hosts for internal use", err); res.status(500).json({ error: "Failed to fetch all hosts" }); } }); }