feat: Implement SSL support and kiosk mode enhancements
- Added SSL configuration to the backend, including self-signed certificate generation and management. - Updated `setup_myp.sh` to create SSL certificates during installation. - Enhanced `app.py` to support SSL context for secure communication. - Introduced a new SSL management menu in the setup script for easier certificate handling. - Updated frontend API calls to use HTTPS for secure data transmission. - Implemented kiosk mode features, including automatic browser launch with SSL support. - Improved documentation in `SUMMARY.md` to reflect new features and network topology changes.
This commit is contained in:
@@ -18,7 +18,7 @@ from flask_wtf.csrf import CSRFProtect
|
||||
from config.settings import (
|
||||
SECRET_KEY, TAPO_USERNAME, TAPO_PASSWORD, PRINTERS,
|
||||
FLASK_HOST, FLASK_PORT, FLASK_DEBUG, SESSION_LIFETIME,
|
||||
SCHEDULER_INTERVAL, SCHEDULER_ENABLED
|
||||
SCHEDULER_INTERVAL, SCHEDULER_ENABLED, get_ssl_context
|
||||
)
|
||||
from utils.logging_config import setup_logging, get_logger, log_startup_info
|
||||
from models import User, Printer, Job, Stats, get_db_session, init_database, create_initial_admin
|
||||
@@ -1265,16 +1265,19 @@ def tailwind_watch():
|
||||
|
||||
# Auto-Kompilierung beim Serverstart im Debug-Modus
|
||||
def compile_tailwind_if_debug():
|
||||
if app.debug:
|
||||
"""Kompiliert Tailwind CSS im Debug-Modus, falls notwendig."""
|
||||
if FLASK_DEBUG:
|
||||
try:
|
||||
subprocess.run(["npx", "tailwindcss", "-i", "./static/css/input.css",
|
||||
"-o", "./static/css/tailwind-dark-consolidated.min.css"],
|
||||
check=True, capture_output=True)
|
||||
print("Tailwind CSS für Debug-Modus kompiliert.")
|
||||
except subprocess.CalledProcessError as e:
|
||||
print(f"Warnung: Konnte Tailwind CSS nicht kompilieren: {e}")
|
||||
except FileNotFoundError:
|
||||
print("Warnung: Node.js/npm nicht gefunden. Tailwind CSS wurde nicht kompiliert.")
|
||||
app_logger.info("Kompiliere Tailwind CSS...")
|
||||
subprocess.run([
|
||||
"npx", "tailwindcss", "-i", "static/css/input.css",
|
||||
"-o", "static/css/tailwind.min.css", "--minify"
|
||||
], check=True)
|
||||
app_logger.info("Tailwind CSS erfolgreich kompiliert.")
|
||||
except subprocess.CalledProcessError:
|
||||
app_logger.warning("Tailwind konnte nicht kompiliert werden. Möglicherweise ist npx/Node.js nicht installiert.")
|
||||
except Exception as e:
|
||||
app_logger.error(f"Fehler beim Kompilieren von Tailwind CSS: {str(e)}")
|
||||
|
||||
# Tailwind CSS kompilieren, wenn im Debug-Modus
|
||||
if FLASK_DEBUG:
|
||||
@@ -1282,34 +1285,65 @@ if FLASK_DEBUG:
|
||||
|
||||
# Initialisierung der Datenbank beim Start
|
||||
def init_app():
|
||||
"""Initialisiert die App-Komponenten und startet den Scheduler."""
|
||||
# Datenbank initialisieren
|
||||
try:
|
||||
# Datenbank initialisieren
|
||||
init_database()
|
||||
# Admin-Benutzer erstellen oder zurücksetzen
|
||||
create_initial_admin()
|
||||
|
||||
# Template-Helper registrieren
|
||||
register_template_helpers(app)
|
||||
app_logger.info("Template-Helper registriert")
|
||||
|
||||
# Scheduler starten, wenn aktiviert
|
||||
if SCHEDULER_ENABLED:
|
||||
scheduler.start()
|
||||
app_logger.info("Job-Scheduler gestartet")
|
||||
except Exception as e:
|
||||
app_logger.error(f"Fehler bei der Initialisierung: {str(e)}")
|
||||
app_logger.error(f"Fehler bei der Datenbank-Initialisierung: {str(e)}")
|
||||
|
||||
# Jinja2-Helfer registrieren
|
||||
register_template_helpers(app)
|
||||
|
||||
# Tailwind im Debug-Modus kompilieren
|
||||
compile_tailwind_if_debug()
|
||||
|
||||
# Scheduler starten, wenn aktiviert
|
||||
if SCHEDULER_ENABLED:
|
||||
try:
|
||||
# Scheduler-Task für Druckauftrags-Prüfung registrieren
|
||||
scheduler.register_task(
|
||||
"check_jobs",
|
||||
check_jobs,
|
||||
interval=SCHEDULER_INTERVAL
|
||||
)
|
||||
|
||||
# Scheduler starten
|
||||
scheduler.start()
|
||||
app_logger.info(f"Scheduler gestartet mit Intervall {SCHEDULER_INTERVAL} Sekunden.")
|
||||
except Exception as e:
|
||||
app_logger.error(f"Fehler beim Starten des Schedulers: {str(e)}")
|
||||
|
||||
# SSL-Kontext protokollieren
|
||||
ssl_context = get_ssl_context()
|
||||
if ssl_context:
|
||||
app_logger.info(f"SSL aktiviert mit Zertifikat {ssl_context[0]}")
|
||||
else:
|
||||
app_logger.warning("SSL ist deaktiviert. Die Verbindung ist unverschlüsselt!")
|
||||
|
||||
# App starten
|
||||
if __name__ == "__main__":
|
||||
# Initialisierung ausführen
|
||||
init_app()
|
||||
|
||||
# Flask-Server starten
|
||||
app.run(
|
||||
host=FLASK_HOST,
|
||||
port=FLASK_PORT,
|
||||
debug=FLASK_DEBUG
|
||||
)
|
||||
try:
|
||||
# App initialisieren
|
||||
init_app()
|
||||
|
||||
# SSL-Kontext ermitteln
|
||||
ssl_context = get_ssl_context()
|
||||
|
||||
# Konsolen-Ausgabe für HTTPS
|
||||
protocol = "HTTPS" if ssl_context else "HTTP"
|
||||
app_logger.info(f"MYP startet auf {protocol}://{FLASK_HOST}:{FLASK_PORT} (Debug: {FLASK_DEBUG})")
|
||||
|
||||
# App starten
|
||||
app.run(
|
||||
host=FLASK_HOST,
|
||||
port=FLASK_PORT,
|
||||
debug=FLASK_DEBUG,
|
||||
ssl_context=ssl_context
|
||||
)
|
||||
except Exception as e:
|
||||
app_logger.critical(f"Kritischer Fehler beim Starten der Anwendung: {str(e)}")
|
||||
|
||||
# Content Security Policy anpassen
|
||||
@app.after_request
|
||||
|
@@ -31,6 +31,11 @@ FLASK_PORT = 5000
|
||||
FLASK_DEBUG = True
|
||||
SESSION_LIFETIME = timedelta(days=7)
|
||||
|
||||
# SSL-Konfiguration
|
||||
SSL_ENABLED = True
|
||||
SSL_CERT_PATH = "/opt/myp/ssl/myp.crt"
|
||||
SSL_KEY_PATH = "/opt/myp/ssl/myp.key"
|
||||
|
||||
# Scheduler-Konfiguration
|
||||
SCHEDULER_INTERVAL = 60 # Sekunden
|
||||
SCHEDULER_ENABLED = True
|
||||
@@ -63,4 +68,47 @@ def ensure_database_directory():
|
||||
"""Erstellt das Datenbank-Verzeichnis."""
|
||||
db_dir = os.path.dirname(DATABASE_PATH)
|
||||
if db_dir:
|
||||
os.makedirs(db_dir, exist_ok=True)
|
||||
os.makedirs(db_dir, exist_ok=True)
|
||||
|
||||
def ensure_ssl_directory():
|
||||
"""Erstellt das SSL-Verzeichnis, falls es nicht existiert."""
|
||||
ssl_dir = os.path.dirname(SSL_CERT_PATH)
|
||||
if ssl_dir and not os.path.exists(ssl_dir):
|
||||
os.makedirs(ssl_dir, exist_ok=True)
|
||||
|
||||
def get_ssl_context():
|
||||
"""
|
||||
Gibt den SSL-Kontext für Flask zurück, wenn SSL aktiviert ist.
|
||||
|
||||
Returns:
|
||||
tuple oder None: Tuple mit Zertifikat- und Schlüsselpfad, wenn SSL aktiviert ist, sonst None
|
||||
"""
|
||||
if not SSL_ENABLED:
|
||||
return None
|
||||
|
||||
# Wenn Zertifikate nicht existieren, diese automatisch erstellen
|
||||
if not os.path.exists(SSL_CERT_PATH) or not os.path.exists(SSL_KEY_PATH):
|
||||
ensure_ssl_directory()
|
||||
|
||||
# Prüfen, ob wir uns im Entwicklungsmodus befinden
|
||||
if FLASK_DEBUG:
|
||||
print("SSL-Zertifikate nicht gefunden. Erstelle selbstsignierte Zertifikate...")
|
||||
|
||||
# Pfad zum create_ssl_cert.sh-Skript ermitteln
|
||||
script_path = os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(__file__))),
|
||||
"install", "create_ssl_cert.sh")
|
||||
|
||||
# Ausführungsrechte setzen
|
||||
if os.path.exists(script_path):
|
||||
os.system(f"chmod +x {script_path}")
|
||||
|
||||
# Zertifikate erstellen
|
||||
os.system(f"{script_path} -c {SSL_CERT_PATH} -k {SSL_KEY_PATH}")
|
||||
else:
|
||||
print(f"WARNUNG: SSL-Zertifikat-Generator nicht gefunden: {script_path}")
|
||||
return None
|
||||
else:
|
||||
print("WARNUNG: SSL-Zertifikate nicht gefunden und Nicht-Debug-Modus. SSL wird deaktiviert.")
|
||||
return None
|
||||
|
||||
return (SSL_CERT_PATH, SSL_KEY_PATH)
|
@@ -87,7 +87,7 @@ self.addEventListener('fetch', (event) => {
|
||||
const { request } = event;
|
||||
const url = new URL(request.url);
|
||||
|
||||
// Skip non-GET requests and unsupported schemes for caching
|
||||
// Unterstütze sowohl HTTP als auch HTTPS
|
||||
if (request.method !== 'GET' ||
|
||||
(url.protocol !== 'http:' && url.protocol !== 'https:')) {
|
||||
return;
|
||||
|
Reference in New Issue
Block a user