diff --git a/packages/reservation-platform/debug-server/package.json b/packages/reservation-platform/debug-server/package.json
index 0519ecba..648a9f83 100644
--- a/packages/reservation-platform/debug-server/package.json
+++ b/packages/reservation-platform/debug-server/package.json
@@ -1 +1,21 @@
-
\ No newline at end of file
+{
+ "name": "myp-frontend-debug-server",
+ "version": "1.0.0",
+ "description": "Debug-Server für das MYP Frontend",
+ "main": "src/index.js",
+ "scripts": {
+ "start": "node src/index.js",
+ "dev": "nodemon src/index.js"
+ },
+ "dependencies": {
+ "express": "^4.18.2",
+ "systeminformation": "^5.18.15",
+ "ejs": "^3.1.9",
+ "os-utils": "^0.0.14",
+ "node-fetch": "^2.6.7",
+ "socket.io": "^4.7.2"
+ },
+ "devDependencies": {
+ "nodemon": "^3.0.2"
+ }
+}
\ No newline at end of file
diff --git a/packages/reservation-platform/debug-server/public/css/style.css b/packages/reservation-platform/debug-server/public/css/style.css
new file mode 100644
index 00000000..0519ecba
--- /dev/null
+++ b/packages/reservation-platform/debug-server/public/css/style.css
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/packages/reservation-platform/debug-server/public/views/index.ejs b/packages/reservation-platform/debug-server/public/views/index.ejs
new file mode 100644
index 00000000..a9a1da96
--- /dev/null
+++ b/packages/reservation-platform/debug-server/public/views/index.ejs
@@ -0,0 +1,186 @@
+
+
+
+
+
+ MYP Frontend Debug-Server
+
+
+
+
+
+
+
+
+
+
+
+
+ Systeminformationen
+ Lade Daten...
+
+
+
+
+
+ Netzwerkinformationen
+ Lade Daten...
+
+
+
Netzwerkschnittstellen
+
+
+
+
+
+
Netzwerkstatistiken
+
+
+
+
+
+
+
+ Dienststatus
+ Lade Daten...
+
+
+
+
+
+
+
+
+ Echtzeit-Monitoring
+
+
+
+
+
+
+
Netzwerkdurchsatz
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/packages/reservation-platform/debug-server/src/index.js b/packages/reservation-platform/debug-server/src/index.js
new file mode 100644
index 00000000..f3bf3f20
--- /dev/null
+++ b/packages/reservation-platform/debug-server/src/index.js
@@ -0,0 +1,471 @@
+// Frontend Debug-Server für MYP
+const express = require('express');
+const path = require('path');
+const http = require('http');
+const si = require('systeminformation');
+const os = require('os');
+const osUtils = require('os-utils');
+const { exec } = require('child_process');
+const fetch = require('node-fetch');
+const socketIo = require('socket.io');
+
+// Konfiguration
+const app = express();
+const server = http.createServer(app);
+const io = socketIo(server);
+const PORT = 6666;
+const FRONTEND_PORT = 3000;
+const FRONTEND_HOST = 'localhost';
+const BACKEND_HOST = 'localhost';
+const BACKEND_PORT = 5000;
+
+// View Engine einrichten
+app.set('view engine', 'ejs');
+app.set('views', path.join(__dirname, '../public/views'));
+app.use(express.static(path.join(__dirname, '../public')));
+app.use(express.json());
+
+// Hauptseite rendern
+app.get('/', async (req, res) => {
+ const hostname = os.hostname();
+ const networkInterfaces = os.networkInterfaces();
+ const ipAddresses = {};
+
+ // IP-Adressen sammeln
+ Object.keys(networkInterfaces).forEach(interfaceName => {
+ const interfaceInfo = networkInterfaces[interfaceName];
+ const ipv4Addresses = interfaceInfo.filter(info => info.family === 'IPv4');
+ if (ipv4Addresses.length > 0) {
+ ipAddresses[interfaceName] = ipv4Addresses[0].address;
+ }
+ });
+
+ // Rendere die Hauptseite mit Basisdaten
+ res.render('index', {
+ hostname: hostname,
+ ipAddresses: ipAddresses,
+ timestamp: new Date().toLocaleString('de-DE'),
+ });
+});
+
+// API-Endpunkte
+
+// Systeminformationen
+app.get('/api/system', async (req, res) => {
+ try {
+ const [cpu, mem, osInfo, diskLayout, fsSize] = await Promise.all([
+ si.cpu(),
+ si.mem(),
+ si.osInfo(),
+ si.diskLayout(),
+ si.fsSize()
+ ]);
+
+ const data = {
+ cpu: {
+ manufacturer: cpu.manufacturer,
+ brand: cpu.brand,
+ speed: cpu.speed,
+ cores: cpu.cores,
+ physicalCores: cpu.physicalCores
+ },
+ memory: {
+ total: formatBytes(mem.total),
+ free: formatBytes(mem.free),
+ used: formatBytes(mem.used),
+ usedPercent: Math.round(mem.used / mem.total * 100)
+ },
+ os: {
+ platform: osInfo.platform,
+ distro: osInfo.distro,
+ release: osInfo.release,
+ arch: osInfo.arch,
+ uptime: formatUptime(os.uptime())
+ },
+ filesystem: fsSize.map(fs => ({
+ fs: fs.fs,
+ type: fs.type,
+ size: formatBytes(fs.size),
+ used: formatBytes(fs.used),
+ available: formatBytes(fs.available),
+ mount: fs.mount,
+ usePercent: Math.round(fs.use)
+ })),
+ disks: diskLayout.map(disk => ({
+ device: disk.device,
+ type: disk.type,
+ name: disk.name,
+ size: formatBytes(disk.size)
+ }))
+ };
+
+ res.json(data);
+ } catch (error) {
+ console.error('Fehler beim Abrufen der Systemdaten:', error);
+ res.status(500).json({ error: 'Fehler beim Abrufen der Systemdaten' });
+ }
+});
+
+// Netzwerkinformationen
+app.get('/api/network', async (req, res) => {
+ try {
+ const [netInterfaces, netStats] = await Promise.all([
+ si.networkInterfaces(),
+ si.networkStats()
+ ]);
+
+ const dns = await getDnsServers();
+ const gateway = await getDefaultGateway();
+
+ const data = {
+ interfaces: netInterfaces.map(iface => ({
+ iface: iface.iface,
+ ip4: iface.ip4,
+ ip6: iface.ip6,
+ mac: iface.mac,
+ internal: iface.internal,
+ operstate: iface.operstate,
+ type: iface.type,
+ speed: iface.speed,
+ dhcp: iface.dhcp
+ })),
+ stats: netStats.map(stat => ({
+ iface: stat.iface,
+ rx_bytes: formatBytes(stat.rx_bytes),
+ tx_bytes: formatBytes(stat.tx_bytes),
+ rx_sec: formatBytes(stat.rx_sec),
+ tx_sec: formatBytes(stat.tx_sec)
+ })),
+ dns: dns,
+ gateway: gateway
+ };
+
+ res.json(data);
+ } catch (error) {
+ console.error('Fehler beim Abrufen der Netzwerkdaten:', error);
+ res.status(500).json({ error: 'Fehler beim Abrufen der Netzwerkdaten' });
+ }
+});
+
+// Dienststatus
+app.get('/api/services', async (req, res) => {
+ try {
+ // Prüfen ob Frontend (Next.js) läuft
+ const frontendStatus = await checkServiceStatus(FRONTEND_HOST, FRONTEND_PORT);
+
+ // Prüfen ob Backend (Flask) läuft
+ const backendStatus = await checkServiceStatus(BACKEND_HOST, BACKEND_PORT);
+
+ // Docker-Container Status abrufen
+ const containers = await getDockerContainers();
+
+ const data = {
+ frontend: {
+ name: 'Next.js Frontend',
+ status: frontendStatus ? 'online' : 'offline',
+ port: FRONTEND_PORT,
+ host: FRONTEND_HOST
+ },
+ backend: {
+ name: 'Flask Backend',
+ status: backendStatus ? 'online' : 'offline',
+ port: BACKEND_PORT,
+ host: BACKEND_HOST
+ },
+ docker: {
+ containers: containers
+ }
+ };
+
+ res.json(data);
+ } catch (error) {
+ console.error('Fehler beim Abrufen der Dienststatus:', error);
+ res.status(500).json({ error: 'Fehler beim Abrufen der Dienststatus' });
+ }
+});
+
+// Ping-Endpunkt für Netzwerkdiagnose
+app.get('/api/ping/:host', (req, res) => {
+ const host = req.params.host;
+
+ // Sicherheitscheck für den Hostnamen
+ if (!isValidHostname(host)) {
+ return res.status(400).json({ error: 'Ungültiger Hostname oder IP-Adresse' });
+ }
+
+ // Ping-Befehl ausführen
+ exec(`ping -n 4 ${host}`, (error, stdout, stderr) => {
+ if (error) {
+ return res.json({
+ success: false,
+ output: stderr || stdout,
+ error: error.message
+ });
+ }
+
+ res.json({
+ success: true,
+ output: stdout
+ });
+ });
+});
+
+// Traceroute-Endpunkt für Netzwerkdiagnose
+app.get('/api/traceroute/:host', (req, res) => {
+ const host = req.params.host;
+
+ // Sicherheitscheck für den Hostnamen
+ if (!isValidHostname(host)) {
+ return res.status(400).json({ error: 'Ungültiger Hostname oder IP-Adresse' });
+ }
+
+ // Traceroute-Befehl ausführen (Windows: tracert, Unix: traceroute)
+ const command = process.platform === 'win32' ? 'tracert' : 'traceroute';
+ exec(`${command} ${host}`, (error, stdout, stderr) => {
+ // Traceroute kann einen Nicht-Null-Exit-Code zurückgeben, selbst wenn es teilweise erfolgreich ist
+ res.json({
+ success: true,
+ output: stdout,
+ error: stderr
+ });
+ });
+});
+
+// DNS-Lookup-Endpunkt für Netzwerkdiagnose
+app.get('/api/nslookup/:host', (req, res) => {
+ const host = req.params.host;
+
+ // Sicherheitscheck für den Hostnamen
+ if (!isValidHostname(host)) {
+ return res.status(400).json({ error: 'Ungültiger Hostname oder IP-Adresse' });
+ }
+
+ // NSLookup-Befehl ausführen
+ exec(`nslookup ${host}`, (error, stdout, stderr) => {
+ if (error) {
+ return res.json({
+ success: false,
+ output: stderr || stdout,
+ error: error.message
+ });
+ }
+
+ res.json({
+ success: true,
+ output: stdout
+ });
+ });
+});
+
+// Echtzeit-Updates über WebSockets
+io.on('connection', (socket) => {
+ console.log('Neue WebSocket-Verbindung');
+
+ // CPU- und Arbeitsspeichernutzung im Intervall senden
+ const systemMonitorInterval = setInterval(async () => {
+ try {
+ const [cpu, mem] = await Promise.all([
+ si.currentLoad(),
+ si.mem()
+ ]);
+
+ socket.emit('system-stats', {
+ cpu: {
+ load: Math.round(cpu.currentLoad),
+ cores: cpu.cpus.map(core => Math.round(core.load))
+ },
+ memory: {
+ total: mem.total,
+ used: mem.used,
+ free: mem.free,
+ usedPercent: Math.round(mem.used / mem.total * 100)
+ }
+ });
+ } catch (error) {
+ console.error('Fehler beim Senden der Systemstatistiken:', error);
+ }
+ }, 2000);
+
+ // Netzwerkstatistiken im Intervall senden
+ const networkMonitorInterval = setInterval(async () => {
+ try {
+ const netStats = await si.networkStats();
+
+ socket.emit('network-stats', {
+ stats: netStats.map(stat => ({
+ iface: stat.iface,
+ rx_bytes: stat.rx_bytes,
+ tx_bytes: stat.tx_bytes,
+ rx_sec: stat.rx_sec,
+ tx_sec: stat.tx_sec
+ }))
+ });
+ } catch (error) {
+ console.error('Fehler beim Senden der Netzwerkstatistiken:', error);
+ }
+ }, 2000);
+
+ // Aufräumen, wenn die Verbindung getrennt wird
+ socket.on('disconnect', () => {
+ console.log('WebSocket-Verbindung getrennt');
+ clearInterval(systemMonitorInterval);
+ clearInterval(networkMonitorInterval);
+ });
+});
+
+// Hilfsfunktionen
+
+// Bytes in lesbare Größen formatieren
+function formatBytes(bytes, decimals = 2) {
+ if (bytes === 0) return '0 B';
+
+ const k = 1024;
+ const sizes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB'];
+
+ const i = Math.floor(Math.log(bytes) / Math.log(k));
+ return parseFloat((bytes / Math.pow(k, i)).toFixed(decimals)) + ' ' + sizes[i];
+}
+
+// Uptime in lesbare Zeit formatieren
+function formatUptime(seconds) {
+ const days = Math.floor(seconds / 86400);
+ const hours = Math.floor((seconds % 86400) / 3600);
+ const minutes = Math.floor((seconds % 3600) / 60);
+ const secs = Math.floor(seconds % 60);
+
+ return `${days} Tage, ${hours} Stunden, ${minutes} Minuten, ${secs} Sekunden`;
+}
+
+// Service-Status überprüfen
+async function checkServiceStatus(host, port) {
+ return new Promise(resolve => {
+ const socket = new (require('net').Socket)();
+
+ socket.setTimeout(1000);
+
+ socket.on('connect', () => {
+ socket.destroy();
+ resolve(true);
+ });
+
+ socket.on('timeout', () => {
+ socket.destroy();
+ resolve(false);
+ });
+
+ socket.on('error', () => {
+ socket.destroy();
+ resolve(false);
+ });
+
+ socket.connect(port, host);
+ });
+}
+
+// Docker-Container abfragen
+async function getDockerContainers() {
+ return new Promise((resolve) => {
+ exec('docker ps --format "{{.ID}},{{.Image}},{{.Status}},{{.Ports}},{{.Names}}"', (error, stdout) => {
+ if (error) {
+ resolve([]);
+ return;
+ }
+
+ const containers = [];
+ const lines = stdout.trim().split('\n');
+
+ for (const line of lines) {
+ if (line) {
+ const [id, image, status, ports, name] = line.split(',');
+ containers.push({ id, image, status, ports, name });
+ }
+ }
+
+ resolve(containers);
+ });
+ });
+}
+
+// DNS-Server abfragen
+async function getDnsServers() {
+ return new Promise((resolve) => {
+ if (process.platform === 'win32') {
+ // Windows: DNS-Server über PowerShell abfragen
+ exec('powershell.exe -Command "Get-DnsClientServerAddress -AddressFamily IPv4 | Select-Object -ExpandProperty ServerAddresses"', (error, stdout) => {
+ if (error) {
+ resolve(['DNS-Server konnten nicht ermittelt werden']);
+ return;
+ }
+
+ const servers = stdout.trim().split('\r\n').filter(Boolean);
+ resolve(servers);
+ });
+ } else {
+ // Unix: DNS-Server aus /etc/resolv.conf lesen
+ exec('cat /etc/resolv.conf | grep nameserver | cut -d " " -f 2', (error, stdout) => {
+ if (error) {
+ resolve(['DNS-Server konnten nicht ermittelt werden']);
+ return;
+ }
+
+ const servers = stdout.trim().split('\n').filter(Boolean);
+ resolve(servers);
+ });
+ }
+ });
+}
+
+// Standard-Gateway abfragen
+async function getDefaultGateway() {
+ return new Promise((resolve) => {
+ if (process.platform === 'win32') {
+ // Windows: Gateway über PowerShell abfragen
+ exec('powershell.exe -Command "Get-NetRoute -DestinationPrefix 0.0.0.0/0 | Select-Object -ExpandProperty NextHop"', (error, stdout) => {
+ if (error) {
+ resolve('Gateway konnte nicht ermittelt werden');
+ return;
+ }
+
+ resolve(stdout.trim());
+ });
+ } else {
+ // Unix: Gateway aus den Routentabellen lesen
+ exec("ip route | grep default | awk '{print $3}'", (error, stdout) => {
+ if (error) {
+ resolve('Gateway konnte nicht ermittelt werden');
+ return;
+ }
+
+ resolve(stdout.trim());
+ });
+ }
+ });
+}
+
+// Validierung des Hostnamens für Sicherheit
+function isValidHostname(hostname) {
+ // Längenprüfung
+ if (!hostname || hostname.length > 255) {
+ return false;
+ }
+
+ // Erlaubte Hostnamen
+ if (hostname === 'localhost' || hostname === '127.0.0.1') {
+ return true;
+ }
+
+ // IPv4-Prüfung
+ const ipv4Regex = /^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/;
+ if (ipv4Regex.test(hostname)) {
+ return true;
+ }
+
+ // Hostname-Prüfung
+ const hostnameRegex = /^[a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?(\.[a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?)*$/;
+ return hostnameRegex.test(hostname);
+}
+
+// Server starten
+server.listen(PORT, () => {
+ console.log(`MYP Frontend Debug-Server läuft auf http://localhost:${PORT}`);
+});
\ No newline at end of file