# MYP Installer Control Center - Vollständige Windows-Installation # Zentrale Installationskonsole für die MYP-Plattform # Version 3.0 - Konsolidiert alle Setup-Funktionen # Farbdefinitionen für bessere Lesbarkeit $ColorTitle = "Cyan" $ColorSuccess = "Green" $ColorError = "Red" $ColorWarning = "Yellow" $ColorInfo = "Blue" $ColorCommand = "White" # Überprüfen, ob das Skript als Administrator ausgeführt wird $isAdmin = ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator) function Show-Header { param ([string]$Title) Clear-Host Write-Host "=============================================================" -ForegroundColor $ColorTitle Write-Host " MYP INSTALLER CONTROL CENTER" -ForegroundColor $ColorTitle Write-Host " Version 3.0" -ForegroundColor $ColorTitle Write-Host "=============================================================" -ForegroundColor $ColorTitle Write-Host " $Title" -ForegroundColor $ColorTitle Write-Host "=============================================================" -ForegroundColor $ColorTitle if (-not $isAdmin) { Write-Host "HINWEIS: Dieses Skript läuft ohne Administrator-Rechte." -ForegroundColor $ColorWarning Write-Host "Einige Funktionen sind möglicherweise eingeschränkt." -ForegroundColor $ColorWarning Write-Host "=============================================================" -ForegroundColor $ColorTitle } Write-Host "" } function Test-CommandExists { param ([string]$Command) try { Get-Command $Command -ErrorAction Stop | Out-Null return $true } catch { return $false } } function Exec-Command { param ( [string]$Command, [string]$Description ) Write-Host "> $Description..." -ForegroundColor $ColorInfo try { Invoke-Expression $Command | Out-Host if ($LASTEXITCODE -eq 0 -or $null -eq $LASTEXITCODE) { Write-Host "✓ Erfolgreich abgeschlossen!" -ForegroundColor $ColorSuccess return $true } else { Write-Host "✗ Fehler beim Ausführen des Befehls. Exit-Code: $LASTEXITCODE" -ForegroundColor $ColorError return $false } } catch { $errorMessage = $_.Exception.Message Write-Host "✗ Fehler: $errorMessage" -ForegroundColor $ColorError return $false } } function Get-LocalIPAddress { $localIP = (Get-NetIPAddress | Where-Object { $_.AddressFamily -eq "IPv4" -and $_.PrefixOrigin -ne "WellKnown" } | Select-Object -First 1).IPAddress if (-not $localIP) { $localIP = "127.0.0.1" } return $localIP } function Test-Dependencies { Show-Header "Systemvoraussetzungen prüfen" Write-Host "Prüfe Abhängigkeiten..." -ForegroundColor $ColorInfo $dependencies = @{ "python" = "Python (3.6+)" "pip" = "Python Package Manager" "docker" = "Docker" "docker-compose" = "Docker Compose" "node" = "Node.js" "npm" = "Node Package Manager" "git" = "Git" "curl" = "cURL" } $allInstalled = $true foreach ($dep in $dependencies.GetEnumerator()) { $installed = Test-CommandExists $dep.Key if ($installed) { Write-Host "✓ $($dep.Value) gefunden" -ForegroundColor $ColorSuccess } else { Write-Host "✗ $($dep.Value) nicht gefunden" -ForegroundColor $ColorError $allInstalled = $false } } # Zusätzliche Informationen anzeigen Write-Host "" Write-Host "Zusätzliche Systeminformationen:" -ForegroundColor $ColorInfo if (Test-CommandExists "python") { $pythonVersion = python --version 2>&1 Write-Host "Python Version: $pythonVersion" -ForegroundColor $ColorCommand } if (Test-CommandExists "node") { $nodeVersion = node --version 2>&1 Write-Host "Node.js Version: $nodeVersion" -ForegroundColor $ColorCommand } if (Test-CommandExists "docker") { $dockerVersion = docker --version 2>&1 Write-Host "Docker Version: $dockerVersion" -ForegroundColor $ColorCommand } Write-Host "" if ($allInstalled) { Write-Host "✓ Alle Abhängigkeiten sind installiert!" -ForegroundColor $ColorSuccess } else { Write-Host "⚠ Einige Abhängigkeiten fehlen. Bitte installieren Sie diese vor der Verwendung." -ForegroundColor $ColorWarning } Write-Host "" Write-Host "Drücken Sie eine beliebige Taste, um fortzufahren..." $null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown") } function Setup-Hosts { Show-Header "Host-Konfiguration" if (-not $isAdmin) { Write-Host "Diese Funktion erfordert Administrator-Rechte." -ForegroundColor $ColorError Write-Host "Bitte starten Sie das Skript als Administrator neu." -ForegroundColor $ColorWarning Write-Host "" Write-Host "Drücken Sie eine beliebige Taste, um fortzufahren..." $null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown") return } $localIP = Get-LocalIPAddress Write-Host "Lokale IP-Adresse: $localIP" -ForegroundColor $ColorSuccess $hostsFile = "$env:windir\System32\drivers\etc\hosts" Write-Host "Hosts-Datei: $hostsFile" -ForegroundColor $ColorInfo # Prüfen, ob die Einträge bereits existieren $frontendEntry = Select-String -Path $hostsFile -Pattern "m040tbaraspi001.de040.corpintra.net" -Quiet $backendEntry = Select-String -Path $hostsFile -Pattern "raspberrypi" -Quiet # Einträge in die Hosts-Datei schreiben Write-Host "Aktualisiere Hosts-Datei..." -ForegroundColor $ColorInfo $hostsContent = Get-Content -Path $hostsFile if (-not $frontendEntry) { $hostsContent += "" $hostsContent += "# MYP Frontend Host" $hostsContent += "$localIP m040tbaraspi001.de040.corpintra.net m040tbaraspi001" Write-Host "Frontend-Hostname hinzugefügt" -ForegroundColor $ColorSuccess } else { Write-Host "Frontend-Hostname ist bereits konfiguriert" -ForegroundColor $ColorWarning } if (-not $backendEntry) { $hostsContent += "" $hostsContent += "# MYP Backend Host" $hostsContent += "$localIP raspberrypi" Write-Host "Backend-Hostname hinzugefügt" -ForegroundColor $ColorSuccess } else { Write-Host "Backend-Hostname ist bereits konfiguriert" -ForegroundColor $ColorWarning } # Speichern der aktualisierten Hosts-Datei try { $hostsContent | Set-Content -Path $hostsFile -Force Write-Host "Konfiguration abgeschlossen!" -ForegroundColor $ColorSuccess } catch { $errorMessage = $_.Exception.Message Write-Host "Fehler beim Schreiben der Hosts-Datei: $errorMessage" -ForegroundColor $ColorError } Write-Host "" Write-Host "Folgende Hostnamen sind jetzt konfiguriert:" -ForegroundColor $ColorInfo Write-Host " - Frontend: m040tbaraspi001.de040.corpintra.net" -ForegroundColor $ColorCommand Write-Host " - Backend: raspberrypi" -ForegroundColor $ColorCommand Write-Host "" Write-Host "Drücken Sie eine beliebige Taste, um fortzufahren..." $null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown") } function Test-BackendConnection { Show-Header "Backend-Verbindung prüfen" Write-Host "Welches Backend möchten Sie testen?" -ForegroundColor $ColorInfo Write-Host "1. Lokales Backend (localhost:443)" -ForegroundColor $ColorCommand Write-Host "2. Raspberry Pi Backend (192.168.0.105:5000)" -ForegroundColor $ColorCommand Write-Host "3. Benutzerdefinierte URL" -ForegroundColor $ColorCommand $choice = Read-Host "Wählen Sie eine Option (1-3, Standard: 1)" $backendUrl = "https://localhost:443" $backendHost = "localhost" switch ($choice) { "2" { $backendUrl = "http://192.168.0.105:5000" $backendHost = "192.168.0.105" } "3" { $backendUrl = Read-Host "Backend-URL eingeben (z.B. https://raspberrypi:443)" $backendHost = ([System.Uri]$backendUrl).Host } default { $backendUrl = "https://localhost:443" $backendHost = "localhost" } } Write-Host "" Write-Host "Teste Backend: $backendUrl" -ForegroundColor $ColorInfo Write-Host "" # 1. Netzwerk-Konnektivität prüfen Write-Host "1. Prüfe Netzwerk-Konnektivität zu $backendHost..." -ForegroundColor $ColorInfo try { $ping = Test-Connection -ComputerName $backendHost -Count 1 -Quiet if ($ping) { Write-Host "✓ Ping zu $backendHost erfolgreich" -ForegroundColor $ColorSuccess } else { Write-Host "✗ Ping zu $backendHost fehlgeschlagen" -ForegroundColor $ColorError } } catch { Write-Host "✗ Ping-Test fehlgeschlagen: $($_.Exception.Message)" -ForegroundColor $ColorError } # 2. Backend-Service prüfen Write-Host "2. Prüfe Backend-Service..." -ForegroundColor $ColorInfo try { $healthUrl = "$backendUrl/health" $response = Invoke-WebRequest -Uri $healthUrl -TimeoutSec 5 -UseBasicParsing if ($response.StatusCode -eq 200) { Write-Host "✓ Backend-Health-Check erfolgreich" -ForegroundColor $ColorSuccess } else { Write-Host "⚠ Backend erreichbar, aber Health-Check fehlgeschlagen" -ForegroundColor $ColorWarning } } catch { try { $response = Invoke-WebRequest -Uri $backendUrl -TimeoutSec 5 -UseBasicParsing Write-Host "⚠ Backend erreichbar, aber kein Health-Endpoint" -ForegroundColor $ColorWarning } catch { Write-Host "✗ Backend-Service nicht erreichbar" -ForegroundColor $ColorError Write-Host " Fehler: $($_.Exception.Message)" -ForegroundColor $ColorError } } # 3. API-Endpunkte prüfen Write-Host "3. Prüfe Backend-API-Endpunkte..." -ForegroundColor $ColorInfo $endpoints = @("printers", "jobs", "users") foreach ($endpoint in $endpoints) { try { $apiUrl = "$backendUrl/api/$endpoint" $response = Invoke-WebRequest -Uri $apiUrl -TimeoutSec 5 -UseBasicParsing Write-Host "✓ API-Endpunkt /$endpoint erreichbar" -ForegroundColor $ColorSuccess } catch { Write-Host "⚠ API-Endpunkt /$endpoint nicht erreichbar" -ForegroundColor $ColorWarning } } # 4. Frontend-Konfiguration prüfen Write-Host "4. Prüfe Frontend-Konfigurationsdateien..." -ForegroundColor $ColorInfo $envLocalPath = "frontend\.env.local" if (Test-Path $envLocalPath) { $envContent = Get-Content $envLocalPath -Raw if ($envContent -match "NEXT_PUBLIC_API_URL") { Write-Host "✓ .env.local gefunden und konfiguriert" -ForegroundColor $ColorSuccess } else { Write-Host "⚠ .env.local existiert, aber Backend-URL fehlt" -ForegroundColor $ColorWarning } } else { Write-Host "⚠ .env.local nicht gefunden" -ForegroundColor $ColorWarning } Write-Host "" Write-Host "Möchten Sie die Frontend-Konfiguration für dieses Backend aktualisieren? (j/n)" -ForegroundColor $ColorInfo $updateConfig = Read-Host if ($updateConfig -eq "j") { Setup-BackendUrl -BackendUrl $backendUrl } Write-Host "" Write-Host "Drücken Sie eine beliebige Taste, um fortzufahren..." $null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown") } function Setup-BackendUrl { param ( [string]$BackendUrl = "" ) Show-Header "Backend-URL konfigurieren" if (-not $BackendUrl) { Write-Host "Verfügbare Backend-Konfigurationen:" -ForegroundColor $ColorInfo Write-Host "1. Lokale Entwicklung (https://localhost:443)" -ForegroundColor $ColorCommand Write-Host "2. Raspberry Pi (http://192.168.0.105:5000)" -ForegroundColor $ColorCommand Write-Host "3. Benutzerdefinierte URL" -ForegroundColor $ColorCommand $choice = Read-Host "Wählen Sie eine Option (1-3, Standard: 1)" switch ($choice) { "2" { $BackendUrl = "http://192.168.0.105:5000" } "3" { $BackendUrl = Read-Host "Backend-URL eingeben (z.B. https://raspberrypi:443)" } default { $BackendUrl = "https://localhost:443" } } } Write-Host "Konfiguriere Frontend für Backend: $BackendUrl" -ForegroundColor $ColorInfo # .env.local erstellen/aktualisieren $envLocalPath = "frontend\.env.local" $envContent = @" # Backend API Konfiguration NEXT_PUBLIC_API_URL=$BackendUrl # Frontend-URL für OAuth Callback NEXT_PUBLIC_FRONTEND_URL=http://localhost:3000 # OAuth Konfiguration NEXT_PUBLIC_OAUTH_CALLBACK_URL=http://localhost:3000/auth/login/callback # GitHub OAuth (hardcodiert) GITHUB_CLIENT_ID=7c5d8bef1a5519ec1fdc GITHUB_CLIENT_SECRET=5f1e586204358fbd53cf5fb7d418b3f06ccab8fd # Entwicklungsumgebung NODE_ENV=development DEBUG=true NEXT_DEBUG=true # Backend Host NEXT_PUBLIC_BACKEND_HOST=$((([System.Uri]$BackendUrl).Host)) NEXT_PUBLIC_BACKEND_PROTOCOL=$((([System.Uri]$BackendUrl).Scheme)) "@ try { $envContent | Out-File -FilePath $envLocalPath -Encoding utf8 Write-Host "✓ .env.local erfolgreich erstellt/aktualisiert" -ForegroundColor $ColorSuccess } catch { Write-Host "✗ Fehler beim Erstellen der .env.local: $($_.Exception.Message)" -ForegroundColor $ColorError } Write-Host "" Write-Host "Frontend-Konfiguration abgeschlossen!" -ForegroundColor $ColorSuccess Write-Host "Backend: $BackendUrl" -ForegroundColor $ColorCommand Write-Host "Frontend: http://localhost:3000" -ForegroundColor $ColorCommand Write-Host "" Write-Host "Drücken Sie eine beliebige Taste, um fortzufahren..." $null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown") } function Start-DebugServer { Show-Header "Debug-Server starten" Write-Host "Welchen Debug-Server möchten Sie starten?" -ForegroundColor $ColorInfo Write-Host "1. Frontend Debug-Server (Next.js)" -ForegroundColor $ColorCommand Write-Host "2. Backend Debug-Server (Flask)" -ForegroundColor $ColorCommand Write-Host "3. Beide Debug-Server" -ForegroundColor $ColorCommand Write-Host "4. Frontend Debug-Server (einfacher HTTP-Server)" -ForegroundColor $ColorCommand $choice = Read-Host "Wählen Sie eine Option (1-4, Standard: 1)" switch ($choice) { "1" { Write-Host "Starte Frontend Debug-Server..." -ForegroundColor $ColorInfo if (Test-Path "frontend") { if (Test-CommandExists "npm") { Start-Process -FilePath "cmd" -ArgumentList "/c", "cd frontend && npm run dev" -NoNewWindow Write-Host "✓ Frontend Debug-Server gestartet" -ForegroundColor $ColorSuccess } else { Write-Host "✗ npm nicht gefunden" -ForegroundColor $ColorError } } else { Write-Host "✗ Frontend-Verzeichnis nicht gefunden" -ForegroundColor $ColorError } } "2" { Write-Host "Starte Backend Debug-Server..." -ForegroundColor $ColorInfo if (Test-Path "backend\app\app.py") { if (Test-CommandExists "python") { Start-Process -FilePath "python" -ArgumentList "backend\app\app.py", "--debug" -NoNewWindow Write-Host "✓ Backend Debug-Server gestartet" -ForegroundColor $ColorSuccess } else { Write-Host "✗ Python nicht gefunden" -ForegroundColor $ColorError } } else { Write-Host "✗ Backend-Anwendung nicht gefunden" -ForegroundColor $ColorError } } "3" { Write-Host "Starte beide Debug-Server..." -ForegroundColor $ColorInfo # Backend starten if (Test-Path "backend\app\app.py" -and (Test-CommandExists "python")) { Start-Process -FilePath "python" -ArgumentList "backend\app\app.py", "--debug" -NoNewWindow Write-Host "✓ Backend Debug-Server gestartet" -ForegroundColor $ColorSuccess } # Frontend starten if (Test-Path "frontend" -and (Test-CommandExists "npm")) { Start-Process -FilePath "cmd" -ArgumentList "/c", "cd frontend && npm run dev" -NoNewWindow Write-Host "✓ Frontend Debug-Server gestartet" -ForegroundColor $ColorSuccess } } "4" { Write-Host "Starte einfachen HTTP Debug-Server..." -ForegroundColor $ColorInfo $debugServerDir = "frontend\debug-server" if (Test-Path $debugServerDir) { if (Test-CommandExists "node") { Start-Process -FilePath "node" -ArgumentList "$debugServerDir\src\app.js" -NoNewWindow Write-Host "✓ Einfacher Debug-Server gestartet" -ForegroundColor $ColorSuccess } else { Write-Host "✗ Node.js nicht gefunden" -ForegroundColor $ColorError } } else { Write-Host "✗ Debug-Server-Verzeichnis nicht gefunden" -ForegroundColor $ColorError } } default { Write-Host "Ungültige Option" -ForegroundColor $ColorError } } Write-Host "" Write-Host "Debug-Server-URLs:" -ForegroundColor $ColorInfo Write-Host "- Frontend: http://localhost:3000" -ForegroundColor $ColorCommand Write-Host "- Backend: https://localhost:443" -ForegroundColor $ColorCommand Write-Host "- Debug-Server: http://localhost:8080" -ForegroundColor $ColorCommand Write-Host "" Write-Host "Drücken Sie eine beliebige Taste, um fortzufahren..." $null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown") } function Show-SSLStatus { Show-Header "SSL-Zertifikat-Status" $certPaths = @( "backend\app\certs\myp.crt", "backend\app\certs\myp.key", "frontend\ssl\myp.crt", "frontend\ssl\myp.key" ) Write-Host "Prüfe SSL-Zertifikate..." -ForegroundColor $ColorInfo Write-Host "" foreach ($certPath in $certPaths) { if (Test-Path $certPath) { Write-Host "✓ Gefunden: $certPath" -ForegroundColor $ColorSuccess # Zertifikatsinformationen anzeigen (falls OpenSSL verfügbar) if (Test-CommandExists "openssl" -and $certPath.EndsWith(".crt")) { try { $certInfo = openssl x509 -in $certPath -noout -subject -dates 2>$null if ($certInfo) { Write-Host " $certInfo" -ForegroundColor $ColorCommand } } catch { # OpenSSL-Fehler ignorieren } } } else { Write-Host "✗ Fehlt: $certPath" -ForegroundColor $ColorError } } Write-Host "" Write-Host "SSL-Konfiguration in settings.py:" -ForegroundColor $ColorInfo $settingsPath = "backend\app\config\settings.py" if (Test-Path $settingsPath) { $settingsContent = Get-Content $settingsPath -Raw if ($settingsContent -match "SSL_ENABLED\s*=\s*True") { Write-Host "✓ SSL ist aktiviert" -ForegroundColor $ColorSuccess } else { Write-Host "⚠ SSL ist deaktiviert" -ForegroundColor $ColorWarning } } else { Write-Host "✗ settings.py nicht gefunden" -ForegroundColor $ColorError } Write-Host "" Write-Host "Drücken Sie eine beliebige Taste, um fortzufahren..." $null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown") } function Install-MYPComplete { Show-Header "Vollständige MYP-Installation" Write-Host "Diese Funktion führt eine vollständige MYP-Installation durch:" -ForegroundColor $ColorInfo Write-Host "1. Systemvoraussetzungen prüfen" -ForegroundColor $ColorCommand Write-Host "2. Python-Abhängigkeiten installieren" -ForegroundColor $ColorCommand Write-Host "3. Node.js-Abhängigkeiten installieren" -ForegroundColor $ColorCommand Write-Host "4. SSL-Zertifikate erstellen" -ForegroundColor $ColorCommand Write-Host "5. Datenbank initialisieren" -ForegroundColor $ColorCommand Write-Host "6. Konfigurationsdateien erstellen" -ForegroundColor $ColorCommand Write-Host "" $confirm = Read-Host "Möchten Sie fortfahren? (j/n, Standard: j)" if ($confirm -eq "n") { return } # 1. Systemvoraussetzungen prüfen Write-Host "1. Prüfe Systemvoraussetzungen..." -ForegroundColor $ColorInfo $pythonInstalled = Test-CommandExists "python" $pipInstalled = Test-CommandExists "pip" $nodeInstalled = Test-CommandExists "node" $npmInstalled = Test-CommandExists "npm" if (-not $pythonInstalled -or -not $pipInstalled) { Write-Host "✗ Python oder pip nicht gefunden. Bitte installieren Sie Python 3.6+ mit pip." -ForegroundColor $ColorError return } # 2. Python-Abhängigkeiten installieren Write-Host "2. Installiere Python-Abhängigkeiten..." -ForegroundColor $ColorInfo if (Test-Path "backend\requirements.txt") { Exec-Command "pip install -r backend\requirements.txt" "Installiere Backend-Abhängigkeiten" } else { Write-Host "⚠ requirements.txt nicht gefunden" -ForegroundColor $ColorWarning } # 3. Node.js-Abhängigkeiten installieren if ($nodeInstalled -and $npmInstalled) { Write-Host "3. Installiere Node.js-Abhängigkeiten..." -ForegroundColor $ColorInfo if (Test-Path "frontend\package.json") { Exec-Command "cd frontend && npm install" "Installiere Frontend-Abhängigkeiten" } else { Write-Host "⚠ package.json nicht gefunden" -ForegroundColor $ColorWarning } } else { Write-Host "3. Überspringe Node.js-Abhängigkeiten (Node.js/npm nicht gefunden)" -ForegroundColor $ColorWarning } # 4. SSL-Zertifikate erstellen Write-Host "4. Erstelle SSL-Zertifikate..." -ForegroundColor $ColorInfo Create-SSLCertificates # 5. Datenbank initialisieren Write-Host "5. Initialisiere Datenbank..." -ForegroundColor $ColorInfo if (Test-Path "backend\app\models.py") { try { Exec-Command "cd backend && python -c `"from app.models import init_db, create_initial_admin; init_db(); create_initial_admin()`"" "Initialisiere Datenbank" } catch { Write-Host "⚠ Datenbankinitialisierung fehlgeschlagen: $($_.Exception.Message)" -ForegroundColor $ColorWarning } } # 6. Konfigurationsdateien erstellen Write-Host "6. Erstelle Konfigurationsdateien..." -ForegroundColor $ColorInfo Setup-BackendUrl -BackendUrl "https://localhost:443" Write-Host "" Write-Host "✓ Vollständige MYP-Installation abgeschlossen!" -ForegroundColor $ColorSuccess Write-Host "" Write-Host "Nächste Schritte:" -ForegroundColor $ColorInfo Write-Host "1. Backend starten: python backend\app\app.py" -ForegroundColor $ColorCommand Write-Host "2. Frontend starten: cd frontend && npm run dev" -ForegroundColor $ColorCommand Write-Host "3. Anwendung öffnen: https://localhost:443" -ForegroundColor $ColorCommand Write-Host "" Write-Host "Drücken Sie eine beliebige Taste, um fortzufahren..." $null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown") } function Create-SSLCertificates { Show-Header "SSL-Zertifikat-Generator" # Parameter definieren $certDir = "./backend/app/certs" $backendCertFile = "$certDir/myp.crt" $backendKeyFile = "$certDir/myp.key" $frontendCertFile = "$certDir/frontend.crt" $frontendKeyFile = "$certDir/frontend.key" Write-Host "Zertifikate werden für folgende Hostnamen erstellt:" -ForegroundColor $ColorInfo # Hostname-Auswahl Write-Host "1. Für lokale Entwicklung (localhost)" -ForegroundColor $ColorCommand Write-Host "2. Für Raspberry Pi Deployment (raspberrypi)" -ForegroundColor $ColorCommand Write-Host "3. Für Unternehmens-Setup (m040tbaraspi001.de040.corpintra.net)" -ForegroundColor $ColorCommand $choice = Read-Host "Wählen Sie eine Option (1-3, Standard: 1)" $backendHostname = "localhost" $frontendHostname = "localhost" switch ($choice) { "2" { $backendHostname = "raspberrypi" $frontendHostname = "raspberrypi" } "3" { $backendHostname = "raspberrypi" $frontendHostname = "m040tbaraspi001.de040.corpintra.net" } default { $backendHostname = "localhost" $frontendHostname = "localhost" } } Write-Host "Backend-Hostname: $backendHostname" -ForegroundColor $ColorInfo Write-Host "Frontend-Hostname: $frontendHostname" -ForegroundColor $ColorInfo Write-Host "" # Verzeichnis erstellen, falls es nicht existiert if (!(Test-Path $certDir)) { Write-Host "Erstelle Verzeichnis $certDir..." -ForegroundColor $ColorInfo New-Item -ItemType Directory -Path $certDir -Force | Out-Null } # SSL-Zertifikate mit Python und cryptography erstellen Write-Host "Erstelle SSL-Zertifikate mit Python..." -ForegroundColor $ColorInfo $pythonInstalled = Test-CommandExists "python" if ($pythonInstalled) { # Überprüfen, ob cryptography installiert ist $cryptographyInstalled = python -c "try: import cryptography; print('True'); except ImportError: print('False')" 2>$null if ($cryptographyInstalled -ne "True") { Write-Host "Installiere Python-Abhängigkeit 'cryptography'..." -ForegroundColor $ColorWarning Exec-Command "pip install cryptography" "Installiere cryptography-Paket" } # Python-Skript zur Zertifikatserstellung $certScript = @" import os import datetime import sys from cryptography import x509 from cryptography.x509.oid import NameOID from cryptography.hazmat.primitives import hashes from cryptography.hazmat.primitives.asymmetric import rsa from cryptography.hazmat.primitives.serialization import Encoding, PrivateFormat, NoEncryption def create_self_signed_cert(cert_path, key_path, hostname="localhost"): # Verzeichnis erstellen, falls es nicht existiert cert_dir = os.path.dirname(cert_path) if cert_dir and not os.path.exists(cert_dir): os.makedirs(cert_dir, exist_ok=True) # Privaten Schlüssel generieren private_key = rsa.generate_private_key( public_exponent=65537, key_size=4096, ) # Schlüsseldatei schreiben with open(key_path, "wb") as key_file: key_file.write(private_key.private_bytes( encoding=Encoding.PEM, format=PrivateFormat.TraditionalOpenSSL, encryption_algorithm=NoEncryption() )) # Aktuelles Datum und Ablaufdatum berechnen now = datetime.datetime.now() valid_until = now + datetime.timedelta(days=3650) # 10 Jahre gültig # Name für das Zertifikat erstellen subject = issuer = x509.Name([ x509.NameAttribute(NameOID.COMMON_NAME, hostname), x509.NameAttribute(NameOID.ORGANIZATION_NAME, "Mercedes-Benz AG"), x509.NameAttribute(NameOID.ORGANIZATIONAL_UNIT_NAME, "Werk 040 Berlin"), x509.NameAttribute(NameOID.COUNTRY_NAME, "DE"), x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, "Berlin"), x509.NameAttribute(NameOID.LOCALITY_NAME, "Berlin") ]) # Zertifikat erstellen cert = x509.CertificateBuilder().subject_name( subject ).issuer_name( issuer ).public_key( private_key.public_key() ).serial_number( x509.random_serial_number() ).not_valid_before( now ).not_valid_after( valid_until ).add_extension( x509.SubjectAlternativeName([ x509.DNSName(hostname), x509.DNSName("localhost"), x509.IPAddress(ipaddress.IPv4Address("127.0.0.1")) ]), critical=False, ).add_extension( x509.BasicConstraints(ca=True, path_length=None), critical=True ).add_extension( x509.KeyUsage( digital_signature=True, content_commitment=False, key_encipherment=True, data_encipherment=False, key_agreement=False, key_cert_sign=True, crl_sign=True, encipher_only=False, decipher_only=False ), critical=True ).add_extension( x509.ExtendedKeyUsage([ x509.oid.ExtendedKeyUsageOID.SERVER_AUTH, x509.oid.ExtendedKeyUsageOID.CLIENT_AUTH ]), critical=False ).sign(private_key, hashes.SHA256()) # Zertifikatsdatei schreiben with open(cert_path, "wb") as cert_file: cert_file.write(cert.public_bytes(Encoding.PEM)) print(f"Selbstsigniertes SSL-Zertifikat für '{hostname}' erstellt:") print(f"Zertifikat: {cert_path}") print(f"Schlüssel: {key_path}") print(f"Gültig für 10 Jahre.") # Import für IP-Adressen import ipaddress # Backend-Zertifikat erstellen create_self_signed_cert('$backendCertFile', '$backendKeyFile', '$backendHostname') # Frontend-Zertifikat erstellen create_self_signed_cert('$frontendCertFile', '$frontendKeyFile', '$frontendHostname') "@ $tempScriptPath = ".\temp_cert_script.py" $certScript | Out-File -FilePath $tempScriptPath -Encoding utf8 # Python-Skript ausführen try { python $tempScriptPath Write-Host "SSL-Zertifikate erfolgreich erstellt!" -ForegroundColor $ColorSuccess } catch { $errorMessage = $_.Exception.Message Write-Host "Fehler beim Erstellen der SSL-Zertifikate: $errorMessage" -ForegroundColor $ColorError } finally { # Temporäres Skript löschen if (Test-Path $tempScriptPath) { Remove-Item -Path $tempScriptPath -Force } } } else { Write-Host "Python nicht gefunden. SSL-Zertifikate können nicht erstellt werden." -ForegroundColor $ColorError } # Zertifikate im System installieren (optional) if ($isAdmin) { $installCerts = Read-Host "Möchten Sie die Zertifikate im System installieren? (j/n, Standard: n)" if ($installCerts -eq "j") { if (Test-Path $backendCertFile) { Write-Host "Installiere Backend-Zertifikat im System..." -ForegroundColor $ColorInfo Exec-Command "certutil -addstore -f 'ROOT' '$backendCertFile'" "Installiere im Root-Zertifikatsspeicher" } if (Test-Path $frontendCertFile) { Write-Host "Installiere Frontend-Zertifikat im System..." -ForegroundColor $ColorInfo Exec-Command "certutil -addstore -f 'ROOT' '$frontendCertFile'" "Installiere im Root-Zertifikatsspeicher" } } } else { Write-Host "Hinweis: Um die Zertifikate im System zu installieren, starten Sie das Skript als Administrator." -ForegroundColor $ColorWarning } # Frontend für HTTPS konfigurieren Write-Host "" Write-Host "Möchten Sie das Frontend für HTTPS konfigurieren? (j/n, Standard: j)" -ForegroundColor $ColorInfo $configureFrontend = Read-Host if ($configureFrontend -ne "n") { Write-Host "Konfiguriere Frontend für HTTPS..." -ForegroundColor $ColorInfo # Kopiere Zertifikate ins Frontend-Verzeichnis $frontendSslDir = "./frontend/ssl" if (!(Test-Path $frontendSslDir)) { New-Item -ItemType Directory -Path $frontendSslDir -Force | Out-Null } if (Test-Path $backendCertFile) { Copy-Item -Path $backendCertFile -Destination "$frontendSslDir/myp.crt" -Force } if (Test-Path $backendKeyFile) { Copy-Item -Path $backendKeyFile -Destination "$frontendSslDir/myp.key" -Force } Write-Host "Zertifikate ins Frontend-Verzeichnis kopiert." -ForegroundColor $ColorSuccess # Prüfen, ob .env.local existiert und aktualisieren $envLocalPath = "./frontend/.env.local" $envContent = "" if (Test-Path $envLocalPath) { $envContent = Get-Content -Path $envLocalPath -Raw } else { $envContent = "# MYP Frontend Umgebungsvariablen`n" } # SSL-Konfigurationen $sslConfigs = @( "NODE_TLS_REJECT_UNAUTHORIZED=0", "HTTPS=true", "SSL_CRT_FILE=./ssl/myp.crt", "SSL_KEY_FILE=./ssl/myp.key", "NEXT_PUBLIC_API_URL=https://$backendHostname", "NEXT_PUBLIC_BACKEND_HOST=$backendHostname", "NEXT_PUBLIC_BACKEND_PROTOCOL=https" ) # Existierende Konfigurationen aktualisieren foreach ($config in $sslConfigs) { $key = $config.Split('=')[0] $regex = "(?m)^$key=.*$" if ($envContent -match $regex) { # Update existierende Konfiguration $envContent = $envContent -replace $regex, $config } else { # Neue Konfiguration hinzufügen $envContent += "`n$config" } } # Speichern der aktualisierten Umgebungsvariablen $envContent | Out-File -FilePath $envLocalPath -Encoding utf8 Write-Host ".env.local Datei mit SSL-Konfigurationen aktualisiert." -ForegroundColor $ColorSuccess } Write-Host "" Write-Host "SSL-Zertifikate wurden in folgenden Pfaden gespeichert:" -ForegroundColor $ColorInfo Write-Host "Backend: $backendCertFile" -ForegroundColor $ColorCommand Write-Host "Frontend: $frontendCertFile" -ForegroundColor $ColorCommand Write-Host "" Write-Host "Drücken Sie eine beliebige Taste, um fortzufahren..." $null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown") } function Setup-Environment { Show-Header "Umgebungs-Setup" # Prüfen, ob Python und pip installiert sind $pythonInstalled = Test-CommandExists "python" $pipInstalled = Test-CommandExists "pip" if (-not $pythonInstalled -or -not $pipInstalled) { Write-Host "Python oder pip ist nicht installiert. Bitte installieren Sie Python 3.6+ und versuchen Sie es erneut." -ForegroundColor $ColorError Write-Host "" Write-Host "Drücken Sie eine beliebige Taste, um fortzufahren..." $null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown") return } # Python-Abhängigkeiten installieren Write-Host "Installiere Backend-Abhängigkeiten..." -ForegroundColor $ColorInfo Exec-Command "pip install -r backend/requirements.txt" "Installiere Python-Abhängigkeiten" # Prüfen, ob Node.js und npm installiert sind $nodeInstalled = Test-CommandExists "node" $npmInstalled = Test-CommandExists "npm" if ($nodeInstalled -and $npmInstalled) { # Frontend-Abhängigkeiten installieren Write-Host "Installiere Frontend-Abhängigkeiten..." -ForegroundColor $ColorInfo Exec-Command "cd frontend && npm install" "Installiere Node.js-Abhängigkeiten" } else { Write-Host "Node.js oder npm ist nicht installiert. Frontend-Abhängigkeiten werden übersprungen." -ForegroundColor $ColorWarning } # Docker-Compose Datei aktualisieren $dockerComposeFile = "docker-compose.yml" if (Test-Path $dockerComposeFile) { $dockerCompose = Get-Content $dockerComposeFile -Raw # Sicherstellen, dass dual-protocol aktiv ist if (-not $dockerCompose.Contains("--dual-protocol")) { $dockerCompose = $dockerCompose -replace "command: python -m app\.app", "command: python -m app.app --dual-protocol" $dockerCompose | Set-Content $dockerComposeFile Write-Host "Docker-Compose-Datei wurde aktualisiert, um den dual-protocol-Modus zu aktivieren." -ForegroundColor $ColorSuccess } else { Write-Host "Docker-Compose-Datei ist bereits korrekt konfiguriert." -ForegroundColor $ColorSuccess } } # Datenbank initialisieren Write-Host "Initialisiere Datenbank..." -ForegroundColor $ColorInfo if (Test-Path "backend/app/models.py") { Exec-Command "cd backend && python -c 'from app.models import init_db, create_initial_admin; init_db(); create_initial_admin()'" "Initialisiere Datenbank und Admin-Benutzer" } Write-Host "" Write-Host "Umgebungs-Setup abgeschlossen!" -ForegroundColor $ColorSuccess Write-Host "" Write-Host "Drücken Sie eine beliebige Taste, um fortzufahren..." $null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown") } function Start-Application { Show-Header "Anwendung starten" Write-Host "Wie möchten Sie die Anwendung starten?" -ForegroundColor $ColorInfo Write-Host "1. Backend-Server starten (Python)" -ForegroundColor $ColorCommand Write-Host "2. Frontend-Server starten (Node.js)" -ForegroundColor $ColorCommand Write-Host "3. Beide Server starten (in separaten Fenstern)" -ForegroundColor $ColorCommand Write-Host "4. Mit Docker Compose starten" -ForegroundColor $ColorCommand Write-Host "5. Vollständige Installation und Start" -ForegroundColor $ColorCommand Write-Host "6. Debug-Server starten" -ForegroundColor $ColorCommand Write-Host "7. Zurück zum Hauptmenü" -ForegroundColor $ColorCommand $choice = Read-Host "Wählen Sie eine Option (1-7)" switch ($choice) { "1" { Write-Host "Starte Backend-Server..." -ForegroundColor $ColorInfo Start-Process -FilePath "python" -ArgumentList "backend/app/app.py" -NoNewWindow Write-Host "Backend-Server läuft jetzt im Hintergrund." -ForegroundColor $ColorSuccess } "2" { Write-Host "Starte Frontend-Server..." -ForegroundColor $ColorInfo Start-Process -FilePath "npm" -ArgumentList "run dev" -WorkingDirectory "frontend" -NoNewWindow Write-Host "Frontend-Server läuft jetzt im Hintergrund." -ForegroundColor $ColorSuccess } "3" { Write-Host "Starte Backend-Server..." -ForegroundColor $ColorInfo Start-Process -FilePath "python" -ArgumentList "backend/app/app.py" -NoNewWindow Write-Host "Starte Frontend-Server..." -ForegroundColor $ColorInfo Start-Process -FilePath "npm" -ArgumentList "run dev" -WorkingDirectory "frontend" -NoNewWindow Write-Host "Beide Server laufen jetzt im Hintergrund." -ForegroundColor $ColorSuccess } "4" { $dockerInstalled = Test-CommandExists "docker" $dockerComposeInstalled = Test-CommandExists "docker-compose" if ($dockerInstalled -and $dockerComposeInstalled) { Write-Host "Starte Anwendung mit Docker Compose..." -ForegroundColor $ColorInfo Exec-Command "docker-compose up -d" "Starte Docker Container" Write-Host "Docker Container wurden gestartet." -ForegroundColor $ColorSuccess } else { Write-Host "Docker oder Docker Compose ist nicht installiert." -ForegroundColor $ColorError } } "5" { Install-MYPComplete } "6" { Start-DebugServer } "7" { return } default { Write-Host "Ungültige Option." -ForegroundColor $ColorError } } Write-Host "" Write-Host "Drücken Sie eine beliebige Taste, um fortzufahren..." $null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown") } function Show-ProjectInfo { Show-Header "Projekt-Informationen" Write-Host "MYP (Mercedes-Benz Yard Printing) Platform" -ForegroundColor $ColorTitle Write-Host "Version 3.0" -ForegroundColor $ColorInfo Write-Host "" Write-Host "Beschreibung:" -ForegroundColor $ColorInfo Write-Host "Eine vollständige 3D-Drucker-Management-Plattform für Mercedes-Benz Werk 040 Berlin." -ForegroundColor $ColorCommand Write-Host "" Write-Host "Komponenten:" -ForegroundColor $ColorInfo Write-Host "- Backend: Flask-basierte REST API" -ForegroundColor $ColorCommand Write-Host "- Frontend: Next.js React-Anwendung" -ForegroundColor $ColorCommand Write-Host "- Datenbank: SQLite" -ForegroundColor $ColorCommand Write-Host "- Authentifizierung: GitHub OAuth + lokale Benutzer" -ForegroundColor $ColorCommand Write-Host "- SSL/TLS: Selbstsignierte Zertifikate" -ForegroundColor $ColorCommand Write-Host "" Write-Host "Standard-Zugangsdaten:" -ForegroundColor $ColorInfo Write-Host "- Admin E-Mail: admin@mercedes-benz.com" -ForegroundColor $ColorCommand Write-Host "- Admin Passwort: 744563017196A" -ForegroundColor $ColorCommand Write-Host "- Router Passwort: vT6Vsd^p" -ForegroundColor $ColorCommand Write-Host "" Write-Host "URLs:" -ForegroundColor $ColorInfo Write-Host "- Backend: https://localhost:443 oder https://raspberrypi:443" -ForegroundColor $ColorCommand Write-Host "- Frontend: https://localhost:3000" -ForegroundColor $ColorCommand Write-Host "" Write-Host "Weitere Informationen finden Sie in der CREDENTIALS.md Datei." -ForegroundColor $ColorWarning Write-Host "" Write-Host "Drücken Sie eine beliebige Taste, um fortzufahren..." $null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown") } function Clean-OldFiles { Show-Header "Alte Dateien bereinigen" Write-Host "Möchten Sie alte Skriptdateien und temporäre Dateien löschen? (j/n)" -ForegroundColor $ColorWarning $cleanFiles = Read-Host if ($cleanFiles -eq "j") { $filesToDelete = @( "setup_hosts.ps1", "setup_hosts_copy.ps1", "generate_ssl_certs.ps1", "generate_ssl_certs_copy.ps1", "setup_ssl.ps1", "temp_cert_script.py", "frontend\check-backend-connection.sh", "frontend\setup-backend-url.sh", "frontend\start-debug-server.bat", "backend\setup_myp.sh", "backend\install\create_ssl_cert.sh", "backend\install\ssl_check.sh" ) foreach ($file in $filesToDelete) { if (Test-Path $file) { Remove-Item -Path $file -Force Write-Host "✓ Gelöscht: $file" -ForegroundColor $ColorSuccess } } Write-Host "Bereinigung abgeschlossen!" -ForegroundColor $ColorSuccess } else { Write-Host "Bereinigung übersprungen." -ForegroundColor $ColorInfo } Write-Host "" Write-Host "Drücken Sie eine beliebige Taste, um fortzufahren..." $null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown") } # Hauptmenü anzeigen function Show-MainMenu { Show-Header "Hauptmenü" Write-Host "1. Systemvoraussetzungen prüfen" -ForegroundColor $ColorCommand Write-Host "2. Host-Konfiguration einrichten" -ForegroundColor $ColorCommand Write-Host "3. SSL-Zertifikate erstellen" -ForegroundColor $ColorCommand Write-Host "4. Umgebung einrichten (Abhängigkeiten installieren)" -ForegroundColor $ColorCommand Write-Host "5. Anwendung starten" -ForegroundColor $ColorCommand Write-Host "6. Backend-Verbindung testen" -ForegroundColor $ColorCommand Write-Host "7. Backend-URL konfigurieren" -ForegroundColor $ColorCommand Write-Host "8. SSL-Zertifikat-Status anzeigen" -ForegroundColor $ColorCommand Write-Host "9. Vollständige MYP-Installation" -ForegroundColor $ColorCommand Write-Host "10. Projekt-Informationen anzeigen" -ForegroundColor $ColorCommand Write-Host "11. Alte Dateien bereinigen" -ForegroundColor $ColorCommand Write-Host "12. Beenden" -ForegroundColor $ColorCommand Write-Host "" $choice = Read-Host "Wählen Sie eine Option (1-12)" switch ($choice) { "1" { Test-Dependencies Show-MainMenu } "2" { Setup-Hosts Show-MainMenu } "3" { Create-SSLCertificates Show-MainMenu } "4" { Setup-Environment Show-MainMenu } "5" { Start-Application Show-MainMenu } "6" { Test-BackendConnection Show-MainMenu } "7" { Setup-BackendUrl Show-MainMenu } "8" { Show-SSLStatus Show-MainMenu } "9" { Install-MYPComplete Show-MainMenu } "10" { Show-ProjectInfo Show-MainMenu } "11" { Clean-OldFiles Show-MainMenu } "12" { Write-Host "Auf Wiedersehen!" -ForegroundColor $ColorSuccess exit } default { Write-Host "Ungültige Option. Bitte versuchen Sie es erneut." -ForegroundColor $ColorError Start-Sleep -Seconds 2 Show-MainMenu } } } # Skript starten Show-MainMenu