app/totp.php implementiert RFC 6238 selbst statt per Bibliothek: der
Algorithmus ist ein HMAC plus eine Truncation, und ein zweiter Faktor ist
die letzte Stelle fuer ungepruefte Abhaengigkeiten. Der QR-Code entsteht
aus dem ohnehin vorhandenen TCPDF, damit kein externer Dienst das
Geheimnis sieht.
Beim Login wird die Anmeldung bei aktivem zweitem Faktor nicht
abgeschlossen; der Zwischenzustand gewaehrt keinerlei Zugriff und ist
byte-identisch zu einem unangemeldeten Aufruf. users.totp_last_step
verhindert die Wiederverwendung eines abgefangenen Codes innerhalb seines
Gueltigkeitsfensters. Abschalten verlangt Passwort und Code.
APP_REQUIRE_2FA_FOR_ADMINS macht den Faktor fuer Platform-Admins
verbindlich, per Weiterleitung auf die Einrichtung statt als harte Sperre
- sonst koennte der Schalter den einzigen Admin aussperren. Standard aus.
check-konto-und-mandantenwechsel erwartete beim Login noch das entfernte
Kundenkuerzel-Feld und damit einen direkten Sprung aufs Dashboard; der
Check bildet jetzt den tatsaechlichen Weg ueber die Mandantenauswahl ab.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Vier Luecken geschlossen, die im Alltag sofort aufgefallen waeren:
- Passwort aendern war im eingeloggten Zustand gar nicht moeglich; es gab
nur den Reset per Mail-Link. saas_change_password() prueft das aktuelle
Passwort, verlangt ein tatsaechlich anderes und erneuert danach die
Session-ID. Formular in konto.php.
- mandant-auswahl.php war nur direkt nach dem Login erreichbar. Wer bei
mehreren Mandanten Mitglied ist, musste sich zum Wechseln abmelden. Die
Seite bedient jetzt beide Wege, die Mandantenpruefung bleibt unveraendert
ueber saas_identity_for_user_tenant(). Menuepunkt ab zwei Mitgliedschaften.
- email_verified_at wurde nirgends geprueft, nur angezeigt - bei offener
Selbstregistrierung konnte sich jemand mit fremder Adresse anmelden und
alles nutzen. Erzwungen wird jetzt gezielt dort, wo eine Aktion nach
aussen wirkt: Einladung, Info-Mail, Jahresabschluss. Der Login selbst
bleibt bewusst frei, sonst waeren alle migrierten Bestandsnutzer mit
NULL-Verifikation ausgesperrt. Zusaetzlich setzt der Passwort-Reset die
Verifikation mit, weil der Mail-Link den Postfachzugriff nachweist -
sonst blieben eingeladene Mitglieder dauerhaft unbestaetigt.
- Login landete auf konto.php statt auf dem Dashboard.
Landingpage: die gruene Vertrauenszeile auf "DSGVO-konform" gekuerzt, die
Eintraege zu Paragraf 19 UStG und "Bestehende Ablaeufe bleiben" entfernt.
Geprueft: neues scripts/check-konto-und-mandantenwechsel.php mit 18
Assertions gruen, Passwortformular zusaetzlich manuell inkl. CSRF (419).
Bestehende Suiten unveraendert gruen: HTTP-Smoke 34 Seiten, Rollenmatrix
55, Mandanten-Isolation 12, M3-Auth 9, M3-Settings 15.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>