feat: migrate from static config to database and add authentication

- Replaced static hosts.json and staticConfig.ts with SQLite database (Prisma)

- Implemented JWT authentication and Login UI

- Added dynamic API routes for hosts, topology, and settings

- Updated UI components to fetch and manage state dynamically

- Added Settings interface for managing hosts and topology nodes
This commit is contained in:
2026-02-25 14:07:11 -08:00
parent df02542c26
commit 0910c966a5
37 changed files with 1884 additions and 645 deletions

View File

@@ -9,6 +9,10 @@ import configRouter from './routes/config';
import statsRouter from './routes/stats';
import filesRouter from './routes/files';
import terminalRouter from './routes/terminal';
import authRouter from './routes/auth';
import topologyRouter from './routes/topology';
import hostsRouter from './routes/hosts';
import { requireAuth } from './middleware/auth';
import { getHostConfigs } from './config';
import { requestLogger, logger } from './middleware/requestLogger';
import { errorHandler } from './middleware/errorHandler';
@@ -17,10 +21,13 @@ const app = express();
const httpServer = createServer(app);
const PORT = 3001;
const allowedOrigins = ['http://localhost:3000', 'http://localhost:4173'];
const corsOrigin = process.env.CORS_ORIGIN ? [process.env.CORS_ORIGIN, ...allowedOrigins] : allowedOrigins;
// --- Socket.IO setup (websocket-engineer skill) ---
const io = new Server(httpServer, {
cors: {
origin: process.env.CORS_ORIGIN || 'http://localhost:3000',
origin: corsOrigin,
credentials: true,
},
pingInterval: 25000,
@@ -45,7 +52,7 @@ app.use(helmet({
// CORS — restrict to configured origins
app.use(cors({
origin: process.env.CORS_ORIGIN || 'http://localhost:3000',
origin: corsOrigin,
credentials: true,
}));
@@ -85,18 +92,23 @@ app.get('/api/health', (_req, res) => {
// --- Debug endpoint (dev only) ---
if (process.env.NODE_ENV !== 'production') {
app.get('/api/debug-config', (_req, res) => {
const hosts = getHostConfigs();
app.get('/api/debug-config', async (_req, res) => {
const hosts = await getHostConfigs();
res.json({ hosts });
});
}
// --- Routes ---
app.use('/api', discoverRouter);
app.use('/api', configRouter);
app.use('/api', statsRouter);
app.use('/api', filesRouter);
app.use('/api', terminalRouter);
// --- Public Routes ---
app.use('/api', authRouter);
// --- Protected Routes ---
app.use('/api', requireAuth, discoverRouter);
app.use('/api', requireAuth, configRouter);
app.use('/api', requireAuth, statsRouter);
app.use('/api', requireAuth, filesRouter);
app.use('/api', requireAuth, terminalRouter);
app.use('/api', requireAuth, topologyRouter);
app.use('/api', requireAuth, hostsRouter);
// --- Global error handler (must be last) ---
app.use(errorHandler);