refactor(backend): reorganize top-level layout

- ssh/ renamed to hosts/ (it covers SSH, RDP, VNC, Telnet, Docker, metrics)
- serial/serial.ts and guacamole/ moved inside hosts/
- dashboard.ts and homepage.ts moved to services/
- swagger.ts moved to utils/ with adjusted scan globs

Import paths and the generate:openapi script updated; ports and endpoints
unchanged.
This commit is contained in:
LukeGus
2026-07-16 04:29:26 -05:00
parent 5e7090542d
commit 8b6037b7ff
121 changed files with 66 additions and 58 deletions
+1 -1
View File
@@ -29,7 +29,7 @@
"dev:backend": "tsc -p tsconfig.node.json && node -e \"require('fs').copyFileSync('src/backend/package.json','dist/backend/package.json')\" && node ./dist/backend/backend/starter.js", "dev:backend": "tsc -p tsconfig.node.json && node -e \"require('fs').copyFileSync('src/backend/package.json','dist/backend/package.json')\" && node ./dist/backend/backend/starter.js",
"dev:docker": "docker stop termix-dev 2>nul & docker rm termix-dev 2>nul & docker build -f docker/Dockerfile -t termix:dev --no-cache . && docker run -d --name termix-dev -p 3000:3000 -p 8080:8080 -p 30001-30006:30001-30006 -v \"%cd%\\db\\data:/app/data\" termix:dev", "dev:docker": "docker stop termix-dev 2>nul & docker rm termix-dev 2>nul & docker build -f docker/Dockerfile -t termix:dev --no-cache . && docker run -d --name termix-dev -p 3000:3000 -p 8080:8080 -p 30001-30006:30001-30006 -v \"%cd%\\db\\data:/app/data\" termix:dev",
"dev:docker:restart": "docker stop termix-dev 2>nul & docker rm termix-dev 2>nul & docker run -d --name termix-dev -p 8080:8080 -p 30001-30006:30001-30006 -v \"%cd%\\db\\data:/app/data\" termix:dev", "dev:docker:restart": "docker stop termix-dev 2>nul & docker rm termix-dev 2>nul & docker run -d --name termix-dev -p 8080:8080 -p 30001-30006:30001-30006 -v \"%cd%\\db\\data:/app/data\" termix:dev",
"generate:openapi": "tsc -p tsconfig.node.json && node -e \"require('fs').copyFileSync('src/backend/package.json','dist/backend/package.json')\" && node ./dist/backend/backend/swagger.js", "generate:openapi": "tsc -p tsconfig.node.json && node -e \"require('fs').copyFileSync('src/backend/package.json','dist/backend/package.json')\" && node ./dist/backend/backend/utils/swagger.js",
"preview": "vite preview", "preview": "vite preview",
"electron:dev": "concurrently \"npm run dev\" \"powershell -c \\\"Start-Sleep -Seconds 5\\\" && electron .\"", "electron:dev": "concurrently \"npm run dev\" \"powershell -c \\\"Start-Sleep -Seconds 5\\\" && electron .\"",
"electron:patch-builder": "node scripts/patch-app-builder-lib.cjs", "electron:patch-builder": "node scripts/patch-app-builder-lib.cjs",
+1 -1
View File
@@ -11,7 +11,7 @@ import snippetsRoutes from "./routes/snippets.js";
import c2sTunnelPresetRoutes from "./routes/c2s-tunnel-presets.js"; import c2sTunnelPresetRoutes from "./routes/c2s-tunnel-presets.js";
import terminalRoutes from "./routes/terminal.js"; import terminalRoutes from "./routes/terminal.js";
import sessionLogRoutes from "./routes/session-log-routes.js"; import sessionLogRoutes from "./routes/session-log-routes.js";
import guacamoleRoutes from "../guacamole/routes.js"; import guacamoleRoutes from "../hosts/guacamole/routes.js";
import networkTopologyRoutes from "./routes/network-topology.js"; import networkTopologyRoutes from "./routes/network-topology.js";
import rbacRoutes from "./routes/rbac.js"; import rbacRoutes from "./routes/rbac.js";
import openTabsRoutes from "./routes/open-tabs.js"; import openTabsRoutes from "./routes/open-tabs.js";
@@ -52,7 +52,7 @@ export function registerHostOpksshRoutes(router: Router): void {
try { try {
const { getActiveAuthSession, registerOAuthState } = const { getActiveAuthSession, registerOAuthState } =
await import("../../ssh/opkssh-auth.js"); await import("../../hosts/opkssh-auth.js");
const session = getActiveAuthSession(requestId); const session = getActiveAuthSession(requestId);
if (!session) { if (!session) {
@@ -562,7 +562,7 @@ export function registerHostOpksshRoutes(router: Router): void {
getActiveAuthSession, getActiveAuthSession,
getRequestIdByOAuthState, getRequestIdByOAuthState,
clearOAuthState, clearOAuthState,
} = await import("../../ssh/opkssh-auth.js"); } = await import("../../hosts/opkssh-auth.js");
const userId = await getUserIdFromRequest({ const userId = await getUserIdFromRequest({
cookies: req.cookies, cookies: req.cookies,
@@ -729,7 +729,7 @@ export function registerHostOpksshRoutes(router: Router): void {
try { try {
const { getActiveAuthSession } = const { getActiveAuthSession } =
await import("../../ssh/opkssh-auth.js"); await import("../../hosts/opkssh-auth.js");
const session = getActiveAuthSession(requestId); const session = getActiveAuthSession(requestId);
if (!session) { if (!session) {
+2 -2
View File
@@ -11,7 +11,7 @@ import { parseSSHKey } from "../../utils/ssh-key-utils.js";
import { import {
pickResolvedPassword, pickResolvedPassword,
pickResolvedUsername, pickResolvedUsername,
} from "../../ssh/credential-username.js"; } from "../../hosts/credential-username.js";
import { import {
createCurrentCommandHistoryRepository, createCurrentCommandHistoryRepository,
createCurrentFileManagerBookmarkRepository, createCurrentFileManagerBookmarkRepository,
@@ -2252,7 +2252,7 @@ router.delete(
} }
try { try {
const { deleteOPKSSHToken } = await import("../../ssh/opkssh-auth.js"); const { deleteOPKSSHToken } = await import("../../hosts/opkssh-auth.js");
await deleteOPKSSHToken(userId, hostId); await deleteOPKSSHToken(userId, hostId);
res.json({ success: true }); res.json({ success: true });
} catch (error) { } catch (error) {
+1 -1
View File
@@ -3,7 +3,7 @@ import express from "express";
import type { Request, Response } from "express"; import type { Request, Response } from "express";
import { databaseLogger } from "../../utils/logger.js"; import { databaseLogger } from "../../utils/logger.js";
import { AuthManager } from "../../utils/auth-manager.js"; import { AuthManager } from "../../utils/auth-manager.js";
import { sessionManager } from "../../ssh/terminal-session-manager.js"; import { sessionManager } from "../../hosts/terminal-session-manager.js";
import { import {
getCurrentSettingValue, getCurrentSettingValue,
createCurrentOpenTabRepository, createCurrentOpenTabRepository,
+2 -2
View File
@@ -9,7 +9,7 @@ import {
import { AuthManager } from "../../utils/auth-manager.js"; import { AuthManager } from "../../utils/auth-manager.js";
import type { AuthenticatedRequest } from "../../../types/index.js"; import type { AuthenticatedRequest } from "../../../types/index.js";
import type { SSHHost } from "../../../types/index.js"; import type { SSHHost } from "../../../types/index.js";
import { SSHHostKeyVerifier } from "../../ssh/host-key-verifier.js"; import { SSHHostKeyVerifier } from "../../hosts/host-key-verifier.js";
const router = express.Router(); const router = express.Router();
const proxmoxLogger = logger; const proxmoxLogger = logger;
@@ -402,7 +402,7 @@ async function discoverProxmoxGuestsForHost(
sshConfig.passphrase = resolvedCredentials.keyPassword; sshConfig.passphrase = resolvedCredentials.keyPassword;
} else if (authType === "agent") { } else if (authType === "agent") {
const { applyAgentAuth } = const { applyAgentAuth } =
await import("../../ssh/terminal-auth-helpers.js"); await import("../../hosts/terminal-auth-helpers.js");
const result = await applyAgentAuth( const result = await applyAgentAuth(
sshConfig, sshConfig,
host.terminalConfig as unknown as Record<string, unknown> | undefined, host.terminalConfig as unknown as Record<string, unknown> | undefined,
@@ -1,6 +1,6 @@
import type { AuthenticatedRequest } from "../../../types/index.js"; import type { AuthenticatedRequest } from "../../../types/index.js";
import type { RequestHandler, Router } from "express"; import type { RequestHandler, Router } from "express";
import { restartGuacServer } from "../../guacamole/guacamole-server.js"; import { restartGuacServer } from "../../hosts/guacamole/guacamole-server.js";
import { import {
authLogger, authLogger,
getGlobalLogLevel, getGlobalLogLevel,
+1 -1
View File
@@ -8,7 +8,7 @@ import type { VaultProfileUpdateInput } from "../repositories/vault-profile-repo
import type { AuthenticatedRequest } from "../../../types/index.js"; import type { AuthenticatedRequest } from "../../../types/index.js";
import { authLogger } from "../../utils/logger.js"; import { authLogger } from "../../utils/logger.js";
import { AuthManager } from "../../utils/auth-manager.js"; import { AuthManager } from "../../utils/auth-manager.js";
import { completeVaultAuth } from "../../ssh/vault-oidc-auth.js"; import { completeVaultAuth } from "../../hosts/vault-oidc-auth.js";
const router = express.Router(); const router = express.Router();
@@ -1,11 +1,11 @@
import GuacamoleLite from "guacamole-lite"; import GuacamoleLite from "guacamole-lite";
import { guacLogger } from "../utils/logger.js"; import { guacLogger } from "../../utils/logger.js";
import { GuacamoleTokenService } from "./token-service.js"; import { GuacamoleTokenService } from "./token-service.js";
import { getCurrentSettingValue } from "../database/repositories/factory.js"; import { getCurrentSettingValue } from "../../database/repositories/factory.js";
import { resolveGuacdOptions } from "../utils/guacd-config.js"; import { resolveGuacdOptions } from "../../utils/guacd-config.js";
import fs from "fs"; import fs from "fs";
import path from "path"; import path from "path";
import { createCurrentSessionRecordingRepository } from "../database/repositories/factory.js"; import { createCurrentSessionRecordingRepository } from "../../database/repositories/factory.js";
import type { GuacamoleRecordingMetadata } from "./token-service.js"; import type { GuacamoleRecordingMetadata } from "./token-service.js";
const tokenService = GuacamoleTokenService.getInstance(); const tokenService = GuacamoleTokenService.getInstance();
@@ -1,18 +1,18 @@
import express from "express"; import express from "express";
import { GuacamoleTokenService } from "./token-service.js"; import { GuacamoleTokenService } from "./token-service.js";
import { guacLogger } from "../utils/logger.js"; import { guacLogger } from "../../utils/logger.js";
import { AuthManager } from "../utils/auth-manager.js"; import { AuthManager } from "../../utils/auth-manager.js";
import { PermissionManager } from "../utils/permission-manager.js"; import { PermissionManager } from "../../utils/permission-manager.js";
import { Client } from "ssh2"; import { Client } from "ssh2";
import net from "net"; import net from "net";
import crypto from "crypto"; import crypto from "crypto";
import path from "path"; import path from "path";
import type { AuthenticatedRequest } from "../../types/index.js"; import type { AuthenticatedRequest } from "../../../types/index.js";
import { import {
createCurrentHostResolutionRepository, createCurrentHostResolutionRepository,
createCurrentSettingsRepository, createCurrentSettingsRepository,
} from "../database/repositories/factory.js"; } from "../../database/repositories/factory.js";
import { resolveGuacdOptions } from "../utils/guacd-config.js"; import { resolveGuacdOptions } from "../../utils/guacd-config.js";
const router = express.Router(); const router = express.Router();
const tokenService = GuacamoleTokenService.getInstance(); const tokenService = GuacamoleTokenService.getInstance();
@@ -422,7 +422,7 @@ router.post(
if (jumpHosts.length > 0) { if (jumpHosts.length > 0) {
try { try {
const { resolveHostById } = await import("../ssh/host-resolver.js"); const { resolveHostById } = await import("../host-resolver.js");
const jumpHost = await resolveHostById(jumpHosts[0].hostId, userId); const jumpHost = await resolveHostById(jumpHosts[0].hostId, userId);
if (jumpHost) { if (jumpHost) {
const tunnelPort = await new Promise<number>((resolve, reject) => { const tunnelPort = await new Promise<number>((resolve, reject) => {
@@ -1,6 +1,6 @@
import { describe, expect, it, vi } from "vitest"; import { describe, expect, it, vi } from "vitest";
vi.mock("../utils/logger.js", () => ({ vi.mock("../../utils/logger.js", () => ({
guacLogger: { guacLogger: {
debug: vi.fn(), debug: vi.fn(),
info: vi.fn(), info: vi.fn(),
@@ -1,5 +1,5 @@
import crypto from "crypto"; import crypto from "crypto";
import { guacLogger } from "../utils/logger.js"; import { guacLogger } from "../../utils/logger.js";
export interface GuacamoleConnectionSettings { export interface GuacamoleConnectionSettings {
type: "rdp" | "vnc" | "telnet"; type: "rdp" | "vnc" | "telnet";

Some files were not shown because too many files have changed in this diff Show More