fix: Trusted Device bei MFA zuverlaessig speichern und pruefen
- Dropdown fuer die Merk-Dauer aktiviert jetzt die Checkbox mit; bisher wurde die Auswahl ohne gesetzten Haken verworfen und trotzdem nach jedem Login ein Code verlangt. - Abgelaufene oder defekte Trusted-Device-Eintraege fuehrten beim Login zu einem NameError (users_data war nicht geladen); Bereinigung neu geschrieben. - Cookie erhaelt das Secure-Flag, wenn die Verbindung HTTPS ist. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
44
app.py
44
app.py
@@ -51,7 +51,7 @@ CONFIG_FILE = os.path.join(BASE_DIR, "config.json") # Persistente Konfiguration
|
|||||||
USERS_FILE = os.path.join(BASE_DIR, "users.json") # User-Datenbank
|
USERS_FILE = os.path.join(BASE_DIR, "users.json") # User-Datenbank
|
||||||
HISTORY_FILE = os.path.join(BASE_DIR, "history.json") # Aktivitätsverlauf
|
HISTORY_FILE = os.path.join(BASE_DIR, "history.json") # Aktivitätsverlauf
|
||||||
|
|
||||||
APP_VERSION = "6.2.3"
|
APP_VERSION = "6.2.4"
|
||||||
UPLOAD_EXTENSIONS = {".jpg", ".jpeg", ".png", ".mp4"}
|
UPLOAD_EXTENSIONS = {".jpg", ".jpeg", ".png", ".mp4"}
|
||||||
|
|
||||||
app = Flask(__name__)
|
app = Flask(__name__)
|
||||||
@@ -731,29 +731,29 @@ def login():
|
|||||||
trust_token = request.cookies.get("mfa_trust")
|
trust_token = request.cookies.get("mfa_trust")
|
||||||
if trust_token:
|
if trust_token:
|
||||||
now = datetime.now()
|
now = datetime.now()
|
||||||
# Abgelaufene Einträge bereinigen
|
treffer = None
|
||||||
active = [d for d in user.trusted_devices
|
aktiv = []
|
||||||
if d.get("token") != trust_token or
|
|
||||||
datetime.fromisoformat(d["expires"]) > now]
|
|
||||||
changed = len(active) != len(user.trusted_devices)
|
|
||||||
for d in user.trusted_devices:
|
for d in user.trusted_devices:
|
||||||
|
try:
|
||||||
|
expires = datetime.fromisoformat(d["expires"])
|
||||||
|
except (ValueError, KeyError, TypeError):
|
||||||
|
continue # kaputter Eintrag fliegt raus
|
||||||
|
if expires <= now:
|
||||||
|
continue # abgelaufener Eintrag fliegt raus
|
||||||
|
aktiv.append(d)
|
||||||
if d.get("token") == trust_token:
|
if d.get("token") == trust_token:
|
||||||
try:
|
treffer = d
|
||||||
expires = datetime.fromisoformat(d["expires"])
|
if len(aktiv) != len(user.trusted_devices):
|
||||||
if expires > now:
|
users_data = load_users()
|
||||||
# Trusted Device gültig → MFA überspringen
|
users_data.setdefault(email, {})["trusted_devices"] = aktiv
|
||||||
login_user(user)
|
|
||||||
add_history_entry("user_login", f"User '{email}' angemeldet (Trusted Device)", email)
|
|
||||||
if user.must_change_password:
|
|
||||||
return redirect("/change-password")
|
|
||||||
return redirect("/admin")
|
|
||||||
else:
|
|
||||||
pass
|
|
||||||
except (ValueError, KeyError):
|
|
||||||
pass
|
|
||||||
if changed:
|
|
||||||
users_data[email]["trusted_devices"] = active
|
|
||||||
save_users(users_data)
|
save_users(users_data)
|
||||||
|
if treffer:
|
||||||
|
# Trusted Device gültig → MFA überspringen
|
||||||
|
login_user(user)
|
||||||
|
add_history_entry("user_login", f"User '{email}' angemeldet (Trusted Device)", email)
|
||||||
|
if user.must_change_password:
|
||||||
|
return redirect("/change-password")
|
||||||
|
return redirect("/admin")
|
||||||
session["mfa_user"] = email
|
session["mfa_user"] = email
|
||||||
session["mfa_password_ok"] = True
|
session["mfa_password_ok"] = True
|
||||||
return redirect("/mfa/verify")
|
return redirect("/mfa/verify")
|
||||||
@@ -828,7 +828,7 @@ def mfa_verify():
|
|||||||
resp.set_cookie("mfa_trust", token, max_age=days * 86400,
|
resp.set_cookie("mfa_trust", token, max_age=days * 86400,
|
||||||
path="/",
|
path="/",
|
||||||
httponly=True, samesite="Lax",
|
httponly=True, samesite="Lax",
|
||||||
secure=False)
|
secure=request.is_secure)
|
||||||
return resp
|
return resp
|
||||||
except (ValueError, TypeError):
|
except (ValueError, TypeError):
|
||||||
pass
|
pass
|
||||||
|
|||||||
@@ -46,7 +46,7 @@
|
|||||||
<input class="form-check-input" type="checkbox" id="remember" name="remember" value="7">
|
<input class="form-check-input" type="checkbox" id="remember" name="remember" value="7">
|
||||||
<label class="form-check-label" for="remember">
|
<label class="form-check-label" for="remember">
|
||||||
Gerät für
|
Gerät für
|
||||||
<select class="form-select form-select-sm d-inline-block w-auto" id="remember_days" onchange="document.getElementById('remember').value=this.value">
|
<select class="form-select form-select-sm d-inline-block w-auto" id="remember_days">
|
||||||
<option value="1">1 Tag</option>
|
<option value="1">1 Tag</option>
|
||||||
<option value="3">3 Tage</option>
|
<option value="3">3 Tage</option>
|
||||||
<option value="7" selected>7 Tage</option>
|
<option value="7" selected>7 Tage</option>
|
||||||
@@ -61,10 +61,13 @@
|
|||||||
var cb = document.getElementById('remember');
|
var cb = document.getElementById('remember');
|
||||||
var sel = document.getElementById('remember_days');
|
var sel = document.getElementById('remember_days');
|
||||||
cb.addEventListener('change', function() {
|
cb.addEventListener('change', function() {
|
||||||
if (this.checked) this.value = sel.value;
|
this.value = sel.value;
|
||||||
});
|
});
|
||||||
|
// Wer im Dropdown eine Dauer waehlt, will das Geraet merken:
|
||||||
|
// Checkbox automatisch mit aktivieren.
|
||||||
sel.addEventListener('change', function() {
|
sel.addEventListener('change', function() {
|
||||||
if (cb.checked) cb.value = this.value;
|
cb.checked = true;
|
||||||
|
cb.value = this.value;
|
||||||
});
|
});
|
||||||
})();
|
})();
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
Reference in New Issue
Block a user