diff --git a/backend/app/config/settings.py b/backend/app/config/settings.py index f13a5d8a0..250227d6d 100644 --- a/backend/app/config/settings.py +++ b/backend/app/config/settings.py @@ -1,12 +1,27 @@ import os import json +import secrets from datetime import timedelta +from pathlib import Path -# Hardcodierte Konfiguration -SECRET_KEY = "7445630171969DFAC92C53CEC92E67A9CB2E00B3CB2F" -DATABASE_PATH = "../database/myp.db" -TAPO_USERNAME = "till.tomczak@mercedes-benz.com" -TAPO_PASSWORD = "744563017196A" +# Basisverzeichnis der Anwendung für relative Pfade +BASE_DIR = Path(__file__).resolve().parent.parent +PROJECT_ROOT = BASE_DIR.parent + +# Laden von Umgebungsvariablen, falls vorhanden +def get_env_variable(var_name, default=None): + """Umgebungsvariablen abrufen mit Fallback auf Default-Werte""" + return os.environ.get(var_name, default) + +# Sichere Konfiguration - Verwende Umgebungsvariablen oder generiere Secret Key +SECRET_KEY = get_env_variable("MYP_SECRET_KEY", secrets.token_hex(24)) + +# Datenbankpfad mit korrekter relativer Pfadauflösung +DATABASE_PATH = os.path.join(PROJECT_ROOT, "database", "myp.db") + +# Tapo-Zugangsdaten aus Umgebungsvariablen laden +TAPO_USERNAME = get_env_variable("MYP_TAPO_USERNAME", "") +TAPO_PASSWORD = get_env_variable("MYP_TAPO_PASSWORD", "") # Drucker-Konfiguration PRINTERS = { @@ -19,28 +34,28 @@ PRINTERS = { } # Logging-Konfiguration -LOG_DIR = "logs" +LOG_DIR = os.path.join(PROJECT_ROOT, "logs") LOG_SUBDIRS = ["app", "scheduler", "auth", "jobs", "printers", "errors"] -LOG_LEVEL = "INFO" +LOG_LEVEL = get_env_variable("MYP_LOG_LEVEL", "INFO") LOG_FORMAT = "%(asctime)s - %(name)s - %(levelname)s - %(message)s" LOG_DATE_FORMAT = "%Y-%m-%d %H:%M:%S" # Flask-Konfiguration -FLASK_HOST = "0.0.0.0" -FLASK_PORT = 443 -FLASK_FALLBACK_PORT = 80 -FLASK_DEBUG = True -SESSION_LIFETIME = timedelta(days=7) +FLASK_HOST = get_env_variable("MYP_FLASK_HOST", "0.0.0.0") +FLASK_PORT = int(get_env_variable("MYP_FLASK_PORT", 443)) +FLASK_FALLBACK_PORT = int(get_env_variable("MYP_FLASK_FALLBACK_PORT", 80)) +FLASK_DEBUG = get_env_variable("MYP_FLASK_DEBUG", "True").lower() in ("true", "1", "yes") +SESSION_LIFETIME = timedelta(days=int(get_env_variable("MYP_SESSION_DAYS", 7))) # SSL-Konfiguration -SSL_ENABLED = True -SSL_CERT_PATH = "../certs/myp.crt" -SSL_KEY_PATH = "../certs/myp.key" -SSL_HOSTNAME = "raspberrypi" +SSL_ENABLED = get_env_variable("MYP_SSL_ENABLED", "True").lower() in ("true", "1", "yes") +SSL_CERT_PATH = os.path.join(PROJECT_ROOT, "certs", "myp.crt") +SSL_KEY_PATH = os.path.join(PROJECT_ROOT, "certs", "myp.key") +SSL_HOSTNAME = get_env_variable("MYP_SSL_HOSTNAME", "raspberrypi") # Scheduler-Konfiguration -SCHEDULER_INTERVAL = 60 # Sekunden -SCHEDULER_ENABLED = True +SCHEDULER_INTERVAL = int(get_env_variable("MYP_SCHEDULER_INTERVAL", 60)) # Sekunden +SCHEDULER_ENABLED = get_env_variable("MYP_SCHEDULER_ENABLED", "True").lower() in ("true", "1", "yes") # Datenbank-Konfiguration DB_ENGINE = f"sqlite:///{DATABASE_PATH}" diff --git a/backend/generate_mercedes_cert.py b/backend/generate_mercedes_cert.py new file mode 100644 index 000000000..4bbde3d68 --- /dev/null +++ b/backend/generate_mercedes_cert.py @@ -0,0 +1,172 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +import os +import datetime +import shutil +from pathlib import Path +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 +import ipaddress + +def generate_mercedes_certificate(): + """ + Generiert ein vollständiges Mercedes-Benz-Zertifikat + mit korrekten Metadaten und alternativen Namen. + """ + print("Generiere Mercedes-Benz SSL-Zertifikat...") + + # Verzeichnispfade definieren und alte Zertifikate löschen + old_ssl_dir = "app/instance/ssl" + if os.path.exists(old_ssl_dir): + print(f"Lösche alten SSL-Ordner: {old_ssl_dir}") + try: + shutil.rmtree(old_ssl_dir) + except Exception as e: + print(f"Warnung: Konnte alten SSL-Ordner nicht löschen: {e}") + + # Neues Zielverzeichnis + certs_dir = "app/certs" + os.makedirs(certs_dir, exist_ok=True) + + # Pfade zu Zertifikat und Schlüssel + cert_path = os.path.join(certs_dir, "myp.crt") + key_path = os.path.join(certs_dir, "myp.key") + + # Entferne alte Zertifikate, falls vorhanden + for path in [cert_path, key_path]: + if os.path.exists(path): + os.remove(path) + + try: + # Privaten Schlüssel mit 4096 Bit generieren (sicherer) + private_key = rsa.generate_private_key( + public_exponent=65537, + key_size=4096, + ) + + # Aktuelles Datum und Ablaufdatum (1 Jahr gültig) + now = datetime.datetime.now() + valid_until = now + datetime.timedelta(days=365) + + # Liste aller möglichen Hostnamen/IPs + hostnames = [ + "localhost", + "raspberrypi", + "m040tbaraspi001", + "m040tbaraspi001.de040.corpintra.net", + "mbag.corpintra.net", + "mbag.mb.corpintra.net" + ] + + # IP-Adressen (als String, werden später konvertiert) + ip_addresses = [ + "127.0.0.1", + "192.168.0.101", + "192.168.0.102", + "192.168.0.103", + "192.168.0.104", + "192.168.0.105", + "192.168.0.106" + ] + + # Erweiterte Zertifikatsattribute für Mercedes-Benz + subject = issuer = x509.Name([ + x509.NameAttribute(NameOID.COMMON_NAME, "raspberrypi"), + x509.NameAttribute(NameOID.ORGANIZATION_NAME, "Mercedes-Benz AG"), + x509.NameAttribute(NameOID.ORGANIZATIONAL_UNIT_NAME, "Werk 040 Berlin"), + x509.NameAttribute(NameOID.LOCALITY_NAME, "Berlin"), + x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, "Berlin"), + x509.NameAttribute(NameOID.COUNTRY_NAME, "DE"), + x509.NameAttribute(NameOID.EMAIL_ADDRESS, "admin@mercedes-benz.com"), + ]) + + # Subject Alternative Names (SAN) erstellen + san_list = [] + for hostname in hostnames: + san_list.append(x509.DNSName(hostname)) + + # IP-Adressen hinzufügen + for ip in ip_addresses: + san_list.append(x509.IPAddress(ipaddress.IPv4Address(ip))) + + # 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(san_list), + 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, + x509.oid.ExtendedKeyUsageOID.CODE_SIGNING + ]), critical=False + ).sign(private_key, hashes.SHA256()) + + # Zertifikat und Schlüssel speichern + with open(key_path, "wb") as f: + f.write(private_key.private_bytes( + encoding=Encoding.PEM, + format=PrivateFormat.TraditionalOpenSSL, + encryption_algorithm=NoEncryption() + )) + + with open(cert_path, "wb") as f: + f.write(cert.public_bytes(Encoding.PEM)) + + print(f"Mercedes-Benz SSL-Zertifikat wurde erfolgreich erstellt:") + print(f"- Zertifikat: {os.path.abspath(cert_path)}") + print(f"- Schlüssel: {os.path.abspath(key_path)}") + print(f"- Gültig bis: {valid_until.strftime('%d.%m.%Y')}") + print(f"- Hostnamen: {', '.join(hostnames)}") + print(f"- IP-Adressen: {', '.join(ip_addresses)}") + + # Kopieren des Zertifikats in das Frontend-Verzeichnis + frontend_ssl_dir = "../frontend/ssl" + os.makedirs(frontend_ssl_dir, exist_ok=True) + + import shutil + shutil.copy2(cert_path, os.path.join(frontend_ssl_dir, "myp.crt")) + shutil.copy2(key_path, os.path.join(frontend_ssl_dir, "myp.key")) + print(f"Zertifikate wurden in das Frontend-Verzeichnis kopiert: {os.path.abspath(frontend_ssl_dir)}") + + return True + except Exception as e: + print(f"Fehler beim Erstellen des Mercedes-Benz SSL-Zertifikats: {e}") + return False + +if __name__ == "__main__": + success = generate_mercedes_certificate() + if success: + print("Mercedes-Benz SSL-Zertifikatserstellung erfolgreich abgeschlossen.") + else: + print("Fehler bei der Zertifikatserstellung!") + exit(1) \ No newline at end of file diff --git a/myp_installer.ps1 b/myp_installer.ps1 index bdf6bce35..886ea7ab0 100644 --- a/myp_installer.ps1 +++ b/myp_installer.ps1 @@ -1,8 +1,8 @@ # MYP Installer Control Center -# Zentrale Installationskonsole für die MYP-Plattform +# Zentrale Installationskonsole fuer die MYP-Plattform # Version 2.0 -# Farbdefinitionen für bessere Lesbarkeit +# Farbdefinitionen fuer bessere Lesbarkeit $ColorTitle = "Cyan" $ColorSuccess = "Green" $ColorError = "Red" @@ -10,7 +10,7 @@ $ColorWarning = "Yellow" $ColorInfo = "Blue" $ColorCommand = "White" -# Überprüfen, ob das Skript als Administrator ausgeführt wird +# Ueberpruefen, ob das Skript als Administrator ausgefuehrt wird $isAdmin = ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator) function Show-Header { @@ -24,8 +24,8 @@ function Show-Header { 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 "HINWEIS: Dieses Skript laeuft ohne Administrator-Rechte." -ForegroundColor $ColorWarning + Write-Host "Einige Funktionen sind moeglicherweise eingeschraenkt." -ForegroundColor $ColorWarning Write-Host "=============================================================" -ForegroundColor $ColorTitle } @@ -55,16 +55,16 @@ function Exec-Command { try { Invoke-Expression $Command | Out-Host if ($LASTEXITCODE -eq 0 -or $null -eq $LASTEXITCODE) { - Write-Host "✓ Erfolgreich abgeschlossen!" -ForegroundColor $ColorSuccess + Write-Host "Erfolgreich abgeschlossen!" -ForegroundColor $ColorSuccess return $true } else { - Write-Host "✗ Fehler beim Ausführen des Befehls. Exit-Code: $LASTEXITCODE" -ForegroundColor $ColorError + Write-Host "Fehler beim Ausfuehren des Befehls. Exit-Code: $LASTEXITCODE" -ForegroundColor $ColorError return $false } } catch { $errorMessage = $_.Exception.Message - Write-Host "✗ Fehler: $errorMessage" -ForegroundColor $ColorError + Write-Host "Fehler: $errorMessage" -ForegroundColor $ColorError return $false } } @@ -78,54 +78,54 @@ function Get-LocalIPAddress { } function Test-Dependencies { - Show-Header "Systemvoraussetzungen prüfen" + Show-Header "Systemvoraussetzungen pruefen" - Write-Host "Prüfe Abhängigkeiten..." -ForegroundColor $ColorInfo + Write-Host "Pruefe Abhaengigkeiten..." -ForegroundColor $ColorInfo $pythonInstalled = Test-CommandExists "python" if ($pythonInstalled) { - Write-Host "✓ Python gefunden" -ForegroundColor $ColorSuccess + Write-Host "Python gefunden" -ForegroundColor $ColorSuccess } else { - Write-Host "✗ Python nicht gefunden" -ForegroundColor $ColorError + Write-Host "Python nicht gefunden" -ForegroundColor $ColorError } $pipInstalled = Test-CommandExists "pip" if ($pipInstalled) { - Write-Host "✓ Pip gefunden" -ForegroundColor $ColorSuccess + Write-Host "Pip gefunden" -ForegroundColor $ColorSuccess } else { - Write-Host "✗ Pip nicht gefunden" -ForegroundColor $ColorError + Write-Host "Pip nicht gefunden" -ForegroundColor $ColorError } $dockerInstalled = Test-CommandExists "docker" if ($dockerInstalled) { - Write-Host "✓ Docker gefunden" -ForegroundColor $ColorSuccess + Write-Host "Docker gefunden" -ForegroundColor $ColorSuccess } else { - Write-Host "✗ Docker nicht gefunden" -ForegroundColor $ColorError + Write-Host "Docker nicht gefunden" -ForegroundColor $ColorError } $dockerComposeInstalled = Test-CommandExists "docker-compose" if ($dockerComposeInstalled) { - Write-Host "✓ Docker Compose gefunden" -ForegroundColor $ColorSuccess + Write-Host "Docker Compose gefunden" -ForegroundColor $ColorSuccess } else { - Write-Host "✗ Docker Compose nicht gefunden" -ForegroundColor $ColorError + Write-Host "Docker Compose nicht gefunden" -ForegroundColor $ColorError } $nodeInstalled = Test-CommandExists "node" if ($nodeInstalled) { - Write-Host "✓ Node.js gefunden" -ForegroundColor $ColorSuccess + Write-Host "Node.js gefunden" -ForegroundColor $ColorSuccess } else { - Write-Host "✗ Node.js nicht gefunden" -ForegroundColor $ColorError + Write-Host "Node.js nicht gefunden" -ForegroundColor $ColorError } $npmInstalled = Test-CommandExists "npm" if ($npmInstalled) { - Write-Host "✓ NPM gefunden" -ForegroundColor $ColorSuccess + Write-Host "NPM gefunden" -ForegroundColor $ColorSuccess } else { - Write-Host "✗ NPM nicht gefunden" -ForegroundColor $ColorError + Write-Host "NPM nicht gefunden" -ForegroundColor $ColorError } Write-Host "" - Write-Host "Drücken Sie eine beliebige Taste, um fortzufahren..." + Write-Host "Druecken Sie eine beliebige Taste, um fortzufahren..." $null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown") } @@ -137,7 +137,7 @@ function Setup-Hosts { Write-Host "Bitte starten Sie das Skript als Administrator neu." -ForegroundColor $ColorWarning Write-Host "" - Write-Host "Drücken Sie eine beliebige Taste, um fortzufahren..." + Write-Host "Druecken Sie eine beliebige Taste, um fortzufahren..." $null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown") return } @@ -148,11 +148,11 @@ function Setup-Hosts { $hostsFile = "$env:windir\System32\drivers\etc\hosts" Write-Host "Hosts-Datei: $hostsFile" -ForegroundColor $ColorInfo - # Prüfen, ob die Einträge bereits existieren + # Pruefen, ob die Eintraege 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 + # Eintraege in die Hosts-Datei schreiben Write-Host "Aktualisiere Hosts-Datei..." -ForegroundColor $ColorInfo $hostsContent = Get-Content -Path $hostsFile @@ -161,7 +161,7 @@ function Setup-Hosts { $hostsContent += "" $hostsContent += "# MYP Frontend Host" $hostsContent += "$localIP m040tbaraspi001.de040.corpintra.net m040tbaraspi001" - Write-Host "Frontend-Hostname hinzugefügt" -ForegroundColor $ColorSuccess + Write-Host "Frontend-Hostname hinzugefuegt" -ForegroundColor $ColorSuccess } else { Write-Host "Frontend-Hostname ist bereits konfiguriert" -ForegroundColor $ColorWarning } @@ -170,7 +170,7 @@ function Setup-Hosts { $hostsContent += "" $hostsContent += "# MYP Backend Host" $hostsContent += "$localIP raspberrypi" - Write-Host "Backend-Hostname hinzugefügt" -ForegroundColor $ColorSuccess + Write-Host "Backend-Hostname hinzugefuegt" -ForegroundColor $ColorSuccess } else { Write-Host "Backend-Hostname ist bereits konfiguriert" -ForegroundColor $ColorWarning } @@ -191,7 +191,7 @@ function Setup-Hosts { Write-Host " - Backend: raspberrypi" -ForegroundColor $ColorCommand Write-Host "" - Write-Host "Drücken Sie eine beliebige Taste, um fortzufahren..." + Write-Host "Druecken Sie eine beliebige Taste, um fortzufahren..." $null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown") } @@ -205,14 +205,15 @@ function Create-SSLCertificates { $frontendCertFile = "$certDir/frontend.crt" $frontendKeyFile = "$certDir/frontend.key" - Write-Host "Zertifikate werden für folgende Hostnamen erstellt:" -ForegroundColor $ColorInfo + Write-Host "Zertifikate werden fuer 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 + Write-Host "1. Fuer lokale Entwicklung (localhost)" -ForegroundColor $ColorCommand + Write-Host "2. Fuer Raspberry Pi Deployment (raspberrypi)" -ForegroundColor $ColorCommand + Write-Host "3. Fuer Unternehmens-Setup (m040tbaraspi001.de040.corpintra.net)" -ForegroundColor $ColorCommand - $choice = Read-Host "Wählen Sie eine Option (1-3, Standard: 1)" + $inputText = "Waehlen Sie eine Option (1-3)" + $choice = Read-Host $inputText $backendHostname = "localhost" $frontendHostname = "localhost" @@ -241,11 +242,11 @@ function Create-SSLCertificates { $pythonInstalled = Test-CommandExists "python" if ($pythonInstalled) { - # Überprüfen, ob cryptography installiert ist + # Ueberpruefen, 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 + Write-Host "Installiere Python-Abhaengigkeit 'cryptography'..." -ForegroundColor $ColorWarning Exec-Command "pip install cryptography" "Installiere cryptography-Paket" } @@ -266,13 +267,13 @@ def create_self_signed_cert(cert_path, key_path, hostname="localhost"): if cert_dir and not os.path.exists(cert_dir): os.makedirs(cert_dir, exist_ok=True) - # Privaten Schlüssel generieren + # Privaten Schluessel generieren private_key = rsa.generate_private_key( public_exponent=65537, key_size=4096, ) - # Schlüsseldatei schreiben + # Schluesseldatei schreiben with open(key_path, "wb") as key_file: key_file.write(private_key.private_bytes( encoding=Encoding.PEM, @@ -282,9 +283,9 @@ def create_self_signed_cert(cert_path, key_path, hostname="localhost"): # Aktuelles Datum und Ablaufdatum berechnen now = datetime.datetime.now() - valid_until = now + datetime.timedelta(days=3650) # 10 Jahre gültig + valid_until = now + datetime.timedelta(days=3650) # 10 Jahre gueltig - # Name für das Zertifikat erstellen + # Name fuer das Zertifikat erstellen subject = issuer = x509.Name([ x509.NameAttribute(NameOID.COMMON_NAME, hostname), x509.NameAttribute(NameOID.ORGANIZATION_NAME, "Mercedes-Benz AG"), @@ -338,10 +339,10 @@ def create_self_signed_cert(cert_path, key_path, hostname="localhost"): 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"Selbstsigniertes SSL-Zertifikat fuer '{hostname}' erstellt:") print(f"Zertifikat: {cert_path}") - print(f"Schlüssel: {key_path}") - print(f"Gültig für 10 Jahre.") + print(f"Schluessel: {key_path}") + print(f"Gueltig fuer 10 Jahre.") # Backend-Zertifikat erstellen create_self_signed_cert('$backendCertFile', '$backendKeyFile', '$backendHostname') @@ -353,7 +354,7 @@ create_self_signed_cert('$frontendCertFile', '$frontendKeyFile', '$frontendHostn $tempScriptPath = ".\temp_cert_script.py" $certScript | Out-File -FilePath $tempScriptPath -Encoding utf8 - # Python-Skript ausführen + # Python-Skript ausfuehren try { python $tempScriptPath Write-Host "SSL-Zertifikate erfolgreich erstellt!" -ForegroundColor $ColorSuccess @@ -363,18 +364,18 @@ create_self_signed_cert('$frontendCertFile', '$frontendKeyFile', '$frontendHostn Write-Host "Fehler beim Erstellen der SSL-Zertifikate: $errorMessage" -ForegroundColor $ColorError } finally { - # Temporäres Skript löschen + # Temporaeres Skript loeschen if (Test-Path $tempScriptPath) { Remove-Item -Path $tempScriptPath -Force } } } else { - Write-Host "Python nicht gefunden. SSL-Zertifikate können nicht erstellt werden." -ForegroundColor $ColorError + Write-Host "Python nicht gefunden. SSL-Zertifikate koennen 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)" + $installCerts = Read-Host "Moechten Sie die Zertifikate im System installieren? (j/n)" if ($installCerts -eq "j") { if (Test-Path $backendCertFile) { @@ -391,13 +392,13 @@ create_self_signed_cert('$frontendCertFile', '$frontendKeyFile', '$frontendHostn Write-Host "Hinweis: Um die Zertifikate im System zu installieren, starten Sie das Skript als Administrator." -ForegroundColor $ColorWarning } - # Frontend für HTTPS konfigurieren + # Frontend fuer HTTPS konfigurieren Write-Host "" - Write-Host "Möchten Sie das Frontend für HTTPS konfigurieren? (j/n, Standard: j)" -ForegroundColor $ColorInfo + Write-Host "Moechten Sie das Frontend fuer HTTPS konfigurieren? (j/n)" -ForegroundColor $ColorInfo $configureFrontend = Read-Host if ($configureFrontend -ne "n") { - Write-Host "Konfiguriere Frontend für HTTPS..." -ForegroundColor $ColorInfo + Write-Host "Konfiguriere Frontend fuer HTTPS..." -ForegroundColor $ColorInfo # Kopiere Zertifikate ins Frontend-Verzeichnis $frontendSslDir = "./frontend/ssl" @@ -415,7 +416,7 @@ create_self_signed_cert('$frontendCertFile', '$frontendKeyFile', '$frontendHostn Write-Host "Zertifikate ins Frontend-Verzeichnis kopiert." -ForegroundColor $ColorSuccess - # Prüfen, ob .env.local existiert und aktualisieren + # Pruefen, ob .env.local existiert und aktualisieren $envLocalPath = "./frontend/.env.local" $envContent = "" @@ -445,7 +446,7 @@ create_self_signed_cert('$frontendCertFile', '$frontendKeyFile', '$frontendHostn # Update existierende Konfiguration $envContent = $envContent -replace $regex, $config } else { - # Neue Konfiguration hinzufügen + # Neue Konfiguration hinzufuegen $envContent += "`n$config" } } @@ -461,14 +462,14 @@ create_self_signed_cert('$frontendCertFile', '$frontendKeyFile', '$frontendHostn Write-Host "Frontend: $frontendCertFile" -ForegroundColor $ColorCommand Write-Host "" - Write-Host "Drücken Sie eine beliebige Taste, um fortzufahren..." + Write-Host "Druecken 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 + # Pruefen, ob Python und pip installiert sind $pythonInstalled = Test-CommandExists "python" $pipInstalled = Test-CommandExists "pip" @@ -476,25 +477,25 @@ function Setup-Environment { 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..." + Write-Host "Druecken 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" + # Python-Abhaengigkeiten installieren + Write-Host "Installiere Backend-Abhaengigkeiten..." -ForegroundColor $ColorInfo + Exec-Command "pip install -r backend/requirements.txt" "Installiere Python-Abhaengigkeiten" - # Prüfen, ob Node.js und npm installiert sind + # Pruefen, 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" + # Frontend-Abhaengigkeiten installieren + Write-Host "Installiere Frontend-Abhaengigkeiten..." -ForegroundColor $ColorInfo + Exec-Command "cd frontend && npm install" "Installiere Node.js-Abhaengigkeiten" } else { - Write-Host "Node.js oder npm ist nicht installiert. Frontend-Abhängigkeiten werden übersprungen." -ForegroundColor $ColorWarning + Write-Host "Node.js oder npm ist nicht installiert. Frontend-Abhaengigkeiten werden uebersprungen." -ForegroundColor $ColorWarning } # Docker-Compose Datei aktualisieren @@ -516,31 +517,31 @@ function Setup-Environment { Write-Host "Umgebungs-Setup abgeschlossen!" -ForegroundColor $ColorSuccess Write-Host "" - Write-Host "Drücken Sie eine beliebige Taste, um fortzufahren..." + Write-Host "Druecken 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 "Wie moechten 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. Zurück zum Hauptmenü" -ForegroundColor $ColorCommand + Write-Host "5. Zurueck zum Hauptmenue" -ForegroundColor $ColorCommand - $choice = Read-Host "Wählen Sie eine Option (1-5)" + $choice = Read-Host "Waehlen Sie eine Option (1-5)" if ($choice -eq "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 + Write-Host "Backend-Server laeuft jetzt im Hintergrund." -ForegroundColor $ColorSuccess } elseif ($choice -eq "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 + Write-Host "Frontend-Server laeuft jetzt im Hintergrund." -ForegroundColor $ColorSuccess } elseif ($choice -eq "3") { Write-Host "Starte Backend-Server..." -ForegroundColor $ColorInfo @@ -567,27 +568,27 @@ function Start-Application { return } else { - Write-Host "Ungültige Option." -ForegroundColor $ColorError + Write-Host "Ungueltige Option." -ForegroundColor $ColorError } Write-Host "" - Write-Host "Drücken Sie eine beliebige Taste, um fortzufahren..." + Write-Host "Druecken Sie eine beliebige Taste, um fortzufahren..." $null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown") } -# Hauptmenü anzeigen +# Hauptmenue anzeigen function Show-MainMenu { - Show-Header "Hauptmenü" + Show-Header "Hauptmenue" - Write-Host "1. Systemvoraussetzungen prüfen" -ForegroundColor $ColorCommand + Write-Host "1. Systemvoraussetzungen pruefen" -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 "4. Umgebung einrichten (Abhaengigkeiten installieren)" -ForegroundColor $ColorCommand Write-Host "5. Anwendung starten" -ForegroundColor $ColorCommand Write-Host "6. Beenden" -ForegroundColor $ColorCommand Write-Host "" - $choice = Read-Host "Wählen Sie eine Option (1-6)" + $choice = Read-Host "Waehlen Sie eine Option (1-6)" if ($choice -eq "1") { Test-Dependencies @@ -613,7 +614,7 @@ function Show-MainMenu { exit } else { - Write-Host "Ungültige Option. Bitte versuchen Sie es erneut." -ForegroundColor $ColorError + Write-Host "Ungueltige Option. Bitte versuchen Sie es erneut." -ForegroundColor $ColorError Start-Sleep -Seconds 2 Show-MainMenu }