diff --git a/web/app.py b/web/app.py index ed2e217..b8dc355 100644 --- a/web/app.py +++ b/web/app.py @@ -3,6 +3,7 @@ MCLogger – Flask Web-Panel Multi-Tenant mit Gruppen, Rollen & verschlüsselten DB-Zugangsdaten. Coolify-kompatibel: alle Einstellungen via ENV. """ +import os import secrets from datetime import datetime from flask import Flask, abort, render_template, request, session, url_for @@ -20,6 +21,21 @@ from blueprints.panel import panel def create_app() -> Flask: app = Flask(__name__) + + # ── Datenschutz-Version automatisch aus Template-Hash berechnen ────────── + # Wenn PRIVACY_POLICY_VERSION nicht per ENV gesetzt ist, wird der SHA-256 + # des Template-Inhalts berechnet und die ersten 6 Zeichen als Version + # verwendet. Ändert sich der Seiteninhalt, ändert sich der Hash → + # alle Nutzer müssen beim nächsten Login erneut zustimmen. + if not os.getenv("PRIVACY_POLICY_VERSION"): + import hashlib + _policy_path = os.path.join(app.root_path, "templates", "privacy_policy.html") + try: + with open(_policy_path, "rb") as _f: + Config.PRIVACY_POLICY_VERSION = hashlib.sha256(_f.read()).hexdigest()[:6].upper() + except OSError: + pass # Fallback auf den Config-Default + app.secret_key = Config.SECRET_KEY app.config.update( SESSION_COOKIE_HTTPONLY=Config.SESSION_COOKIE_HTTPONLY, @@ -129,6 +145,7 @@ def create_app() -> Flask: last_updated="April 15, 2026", invite_expiry_hours=Config.INVITE_EXPIRY_HOURS, audit_retention_days=Config.AUDIT_LOG_RETENTION_DAYS, + policy_version=Config.PRIVACY_POLICY_VERSION, ) @app.errorhandler(400) diff --git a/web/config.py b/web/config.py index e1b6dea..17d27d6 100644 --- a/web/config.py +++ b/web/config.py @@ -60,10 +60,12 @@ class Config: PROXY_COUNT = int(os.getenv("PROXY_COUNT") or "1") # ── Datenschutz / DSGVO ─────────────────────────────────── - # Version der Datenschutzerklärung (ISO-Datum + Revision). Wenn sich dieser - # Wert ändert, werden alle Nutzer beim nächsten Login zur erneuten Zustimmung - # aufgefordert. ENV-Variable PRIVACY_POLICY_VERSION überschreibt den Default. - PRIVACY_POLICY_VERSION = os.getenv("PRIVACY_POLICY_VERSION") or "2026-04-15-r2" + # Version der Datenschutzerklärung. Wird in create_app() automatisch als + # SHA-256-Hash der privacy_policy.html berechnet (erste 6 Zeichen, Großbuchstaben). + # Ändert sich der Seiteninhalt, ändert sich der Hash → alle Nutzer müssen + # beim nächsten Login erneut zustimmen. + # Kann über die ENV-Variable PRIVACY_POLICY_VERSION manuell überschrieben werden. + PRIVACY_POLICY_VERSION = os.getenv("PRIVACY_POLICY_VERSION") or "INIT00" # ── Standard-Berechtigungen neuer Gruppenmitglieder ─────── INVITE_EXPIRY_HOURS = int(os.getenv("INVITE_EXPIRY_HOURS") or "72") diff --git a/web/templates/privacy_policy.html b/web/templates/privacy_policy.html index 87dbf13..805bd50 100644 --- a/web/templates/privacy_policy.html +++ b/web/templates/privacy_policy.html @@ -20,6 +20,12 @@
Last updated: {{ last_updated }}
++ Document ID: + {{ policy_version }} + — this ID changes automatically when the policy content changes. + Your consent is tied to this ID. +