import express, { type Request, Response, NextFunction } from "express"; import { registerRoutes } from "./routes"; import { setupVite, serveStatic, log } from "./vite"; import { setupKeycloak } from "./keycloak"; import { config } from "./config"; import { storage } from "./storage"; import { CanvasExporter } from "./export"; const app = express(); app.use(express.json()); app.use(express.urlencoded({ extended: false })); // Keycloak Setup let keycloak: any = null; if (config.enableKeycloak) { // Set environment variables for Keycloak process.env.KEYCLOAK_REALM = config.keycloakRealm; process.env.KEYCLOAK_AUTH_URL = config.keycloakAuthUrl; process.env.KEYCLOAK_CLIENT_ID = config.keycloakClientId; keycloak = setupKeycloak(app); log("Keycloak authentication enabled"); } else { log("Keycloak authentication disabled"); } app.use((req, res, next) => { const start = Date.now(); const path = req.path; let capturedJsonResponse: Record | undefined = undefined; const originalResJson = res.json; res.json = function (bodyJson, ...args) { capturedJsonResponse = bodyJson; return originalResJson.apply(res, [bodyJson, ...args]); }; res.on("finish", () => { const duration = Date.now() - start; if (path.startsWith("/api")) { let logLine = `${req.method} ${path} ${res.statusCode} in ${duration}ms`; if (capturedJsonResponse) { logLine += ` :: ${JSON.stringify(capturedJsonResponse)}`; } if (logLine.length > 80) { logLine = logLine.slice(0, 79) + "…"; } log(logLine); } }); next(); }); (async () => { const server = await registerRoutes(app); app.use((err: any, _req: Request, res: Response, _next: NextFunction) => { const status = err.status || err.statusCode || 500; const message = err.message || "Internal Server Error"; res.status(status).json({ message }); throw err; }); // importantly only setup vite in development and after // setting up all the other routes so the catch-all route // doesn't interfere with the other routes if (app.get("env") === "development") { await setupVite(app, server); } else { serveStatic(app); } // Aktualisiere Canvas-Konfiguration beim Start falls sich config.cfg geändert hat try { const currentConfig = await storage.getCanvasConfig(); const configChanged = currentConfig.canvasWidth !== config.canvasWidth || currentConfig.canvasHeight !== config.canvasHeight || currentConfig.defaultCooldown !== config.defaultCooldown || currentConfig.enableAutomaticEvents !== config.enableAutomaticEvents || currentConfig.eventDuration !== config.eventDurationMinutes || currentConfig.eventInterval !== config.eventIntervalHours; if (configChanged) { console.log(`${formatTime()} [express] Aktualisiere Canvas-Konfiguration aus config.cfg`); // Für SQLite Storage: Verwende expandCanvas wenn Canvas vergrößert wird if ('expandCanvas' in storage && typeof storage.expandCanvas === 'function' && (config.canvasWidth > currentConfig.canvasWidth || config.canvasHeight > currentConfig.canvasHeight)) { await (storage as any).expandCanvas(config.canvasWidth, config.canvasHeight); } else { await storage.updateCanvasConfig({ canvasWidth: Math.max(currentConfig.canvasWidth, config.canvasWidth), // Erlaube nur Erweiterung canvasHeight: Math.max(currentConfig.canvasHeight, config.canvasHeight), // Erlaube nur Erweiterung defaultCooldown: config.defaultCooldown, enableAutomaticEvents: config.enableAutomaticEvents, eventDuration: config.eventDurationMinutes, eventInterval: config.eventIntervalHours }); } console.log(`${formatTime()} [express] Canvas-Konfiguration aktualisiert`); } } catch (error) { console.error(`${formatTime()} [express] Fehler beim Aktualisieren der Canvas-Konfiguration:`, error); } // Canvas exporter wird bereits in routes.ts initialisiert // ALWAYS serve the app on the port specified in the environment variable PORT // Other ports are firewalled. Default to 5000 if not specified. // this serves both the API and the client. // It is the only port that is not firewalled. const port = parseInt(process.env.PORT || '5001', 10); server.listen({ port, host: "0.0.0.0", reusePort: true, }, () => { log(`serving on port ${port}`); }); })(); function formatTime() { const now = new Date(); const hours = String(now.getHours()).padStart(2, '0'); const minutes = String(now.getMinutes()).padStart(2, '0'); const seconds = String(now.getSeconds()).padStart(2, '0'); return `[${hours}:${minutes}:${seconds}]`; }