Die Dateien, die in diesem Commit geändert wurden, umfassen:

This commit is contained in:
2025-06-12 08:13:15 +02:00
parent a84d7afa27
commit 841d4cc466
188 changed files with 1201 additions and 41 deletions

View File

@ -21,6 +21,40 @@ from sqlalchemy import event
from contextlib import contextmanager
import threading
# ===== MINIMALE SESSION-DATENKLASSE =====
class MinimalSessionInterface:
"""Minimale Session-Implementierung zur Reduzierung der Cookie-Größe"""
@staticmethod
def reduce_session_data():
"""Reduziert Session-Daten auf absolutes Minimum"""
from flask import session
# Nur kritische Daten behalten
essential_keys = ['_user_id', '_id', '_fresh', 'csrf_token']
# Alle nicht-essentiellen Keys entfernen
keys_to_remove = []
for key in session.keys():
if key not in essential_keys:
keys_to_remove.append(key)
for key in keys_to_remove:
session.pop(key, None)
@staticmethod
def get_minimal_session_data():
"""Gibt nur minimale Session-Daten zurück"""
from flask import session
return {
'user_id': session.get('_user_id'),
'session_id': session.get('_id'),
'is_fresh': session.get('_fresh', False)
}
# Globale Session-Interface-Instanz
minimal_session = MinimalSessionInterface()
# ===== SESSION-OPTIMIERUNG =====
class SessionManager:
"""Optimierter Session-Manager für große Session-Daten"""
@ -689,25 +723,32 @@ def log_response_info(response):
app_logger.debug(f"Response: {response.status_code}")
return response
@app.after_request
def minimize_session_cookie(response):
"""Reduziert Session-Cookie automatisch nach jedem Request"""
if current_user.is_authenticated:
# Drastische Session-Cookie-Reduktion
minimal_session.reduce_session_data()
return response
@app.before_request
def check_session_activity():
"""Prüft Session-Aktivität und meldet inaktive Benutzer ab mit optimiertem Cookie-Management"""
"""Prüft Session-Aktivität und meldet inaktive Benutzer ab mit MINIMAL Cookie-Management"""
if current_user.is_authenticated:
from utils.utilities_collection import SESSION_LIFETIME
# DRASTISCHE Session-Reduktion - alle nicht-kritischen Daten entfernen
minimal_session.reduce_session_data()
# Session-Aktivität über externen Store (nicht in Cookie)
session_data = session_manager.load_large_session_data('activity') or {}
now = datetime.now()
# Reduzierte Session-Daten für Cookie-Größe
last_activity_str = session.get('last_activity')
if last_activity_str:
# Aktivitätsprüfung über externen Store
last_activity = session_data.get('last_activity')
if last_activity:
try:
# Verarbeite sowohl alte ISO-Format als auch neue Zeit-Format
if 'T' in last_activity_str: # ISO-Format
last_activity_time = datetime.fromisoformat(last_activity_str)
else: # Nur Zeit-Format
today = now.date()
time_part = datetime.strptime(last_activity_str, '%H:%M').time()
last_activity_time = datetime.combine(today, time_part)
last_activity_time = datetime.fromisoformat(last_activity)
if (now - last_activity_time).total_seconds() > SESSION_LIFETIME.total_seconds():
app_logger.info(f"Session abgelaufen für Benutzer {current_user.id}")
logout_user()
@ -715,8 +756,11 @@ def check_session_activity():
except Exception as e:
app_logger.warning(f"Fehler beim Parsen der Session-Zeit: {e}")
# Optimierte Session-Aktivität aktualisieren - nur Zeit statt volles ISO-Format
session['last_activity'] = now.strftime('%H:%M')
# Aktivität NICHT in Session-Cookie speichern, sondern extern
session_data['last_activity'] = now.isoformat()
session_manager.store_large_session_data('activity', session_data)
# Session permanent ohne zusätzliche Daten
session.permanent = True
# ===== HAUPTROUTEN =====
@ -849,7 +893,7 @@ def api_finish_job(job_id):
@app.route("/api/printers", methods=["GET"])
@login_required
def api_get_printers():
"""API-Endpunkt für Drucker-Liste"""
"""API-Endpunkt für Drucker-Liste mit konsistenter Response-Struktur"""
try:
from models import get_db_session, Printer
@ -862,12 +906,13 @@ def api_get_printers():
printer_dict = {
"id": printer.id,
"name": printer.name,
"model": printer.model,
"location": printer.location,
"status": printer.status,
"model": printer.model or "Unbekanntes Modell",
"location": printer.location or "Unbekannter Standort",
"status": printer.status or "offline",
"ip_address": printer.ip_address,
"plug_ip": printer.plug_ip,
"active": printer.active,
"active": getattr(printer, 'active', True),
"created_at": printer.created_at.isoformat() if printer.created_at else datetime.now().isoformat(),
"last_checked": printer.last_checked.isoformat() if printer.last_checked else None
}
printer_list.append(printer_dict)
@ -875,11 +920,24 @@ def api_get_printers():
db_session.close()
app_logger.info(f"✅ API: {len(printer_list)} Drucker abgerufen")
return jsonify({"printers": printer_list})
# Konsistente Response-Struktur wie erwartet
return jsonify({
"success": True,
"printers": printer_list,
"count": len(printer_list),
"message": "Drucker erfolgreich geladen"
})
except Exception as e:
app_logger.error(f"❌ API-Fehler beim Abrufen der Drucker: {str(e)}")
return jsonify({"error": "Fehler beim Laden der Drucker", "details": str(e)}), 500
return jsonify({
"success": False,
"error": "Fehler beim Laden der Drucker",
"details": str(e),
"printers": [],
"count": 0
}), 500
@app.route("/api/printers/status", methods=["GET"])
@login_required
@ -986,8 +1044,8 @@ def api_session_heartbeat():
"""API-Endpunkt für Session-Heartbeat"""
try:
from utils.utilities_collection import SESSION_LIFETIME
# Session-Aktivität aktualisieren
session['last_activity'] = datetime.now().isoformat()
# Session-Aktivität NICHT in Cookie speichern - Cookie-Reduktion
# session['last_activity'] = datetime.now().isoformat() # ENTFERNT
session.permanent = True
# Verbleibende Zeit berechnen
@ -1011,8 +1069,8 @@ def api_session_extend():
data = request.get_json() or {}
extend_minutes = data.get('extend_minutes', 30)
# Session verlängern
session['last_activity'] = datetime.now().isoformat()
# Session verlängern - NICHT in Cookie speichern
# session['last_activity'] = datetime.now().isoformat() # ENTFERNT
session.permanent = True
return jsonify({
@ -1933,8 +1991,8 @@ def main():
if USE_PRODUCTION_CONFIG:
app_logger.info("[PRODUCTION] Konfiguriere SSL...")
try:
from utils.ssl_config import get_ssl_context
ssl_context = get_ssl_context()
from utils.ssl_suite import ssl_config
ssl_context = ssl_config.get_ssl_context()
app_logger.info("[PRODUCTION] ✅ SSL-Kontext konfiguriert")
except ImportError:
app_logger.warning("[PRODUCTION] ⚠️ SSL-Konfiguration nicht verfügbar")

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -125,8 +125,8 @@ def system_status():
def heartbeat():
"""Heartbeat-Endpunkt für Frontend-Verbindungsmonitoring"""
try:
# Session-Aktivität aktualisieren
session['last_heartbeat'] = datetime.now().strftime('%H:%M:%S')
# Session-Aktivität NICHT in Cookie speichern
# session['last_heartbeat'] = datetime.now().strftime('%H:%M:%S') # ENTFERNT
session.permanent = True
return jsonify({

View File

@ -25,8 +25,8 @@ def heartbeat():
Verhindert automatischen Logout bei aktiven Benutzern.
"""
try:
# Session-Aktivität aktualisieren
session['last_activity'] = datetime.now().isoformat()
# Session-Aktivität NICHT in Cookie speichern - verwende externen Store
# session['last_activity'] = datetime.now().isoformat() # ENTFERNT
session.permanent = True
# Benutzer-Aktivität in Datenbank aktualisieren
@ -108,9 +108,9 @@ def extend():
if not current_user.is_admin:
return jsonify({'error': 'Keine Berechtigung zum Verlängern der Session'}), 403
# Session-Start zurücksetzen
session['session_start'] = datetime.now().isoformat()
session['last_activity'] = datetime.now().isoformat()
# Session-Daten NICHT in Cookie speichern - verwende externen Store
# session['session_start'] = datetime.now().isoformat() # ENTFERNT
# session['last_activity'] = datetime.now().isoformat() # ENTFERNT
session.permanent = True
# SystemLog erstellen

Some files were not shown because too many files have changed in this diff Show More