Migration Plan: Servergenerierte Device-IDs (fingerprint+token) mit E-Mail-Bestätigung und harter Neuanmeldung
Ziel
- Keine parallele Nutzung derselben E-Mail auf baugleichen Geräten.
- Device-ID wird vom Server definiert/validiert, nicht vom Client erfunden.
- E-Mail-Bestätigung (Magic-Link) erzwingt, dass der Nutzer die Adresse besitzt, bevor ein neuer Token/Device-ID ausgehändigt wird.
- Minimaler Bruch: Nutzer einmalig abmelden (forceNeuanmeldung), Magic-Link anklicken, danach neue ID verwenden.
Prämissen
- user.token ist pro Account eindeutig (Duplikate vorher bereinigen/Unique-Index setzen).
- Übergangsphase: alte IDs werden kurz akzeptiert, bis alle neu eingeloggt sind.
Schritte (Reihenfolge)
- Vorbereitung
- Backend-Config prüfen: JWT_SECRET, MONGO_URI_ONLINE/MONGO_URI.
- DB-Backup erstellen.
- Token-Eindeutigkeit sicherstellen: Duplikate via Aggregation finden und bereinigen; optional Partial-Unique-Index auf token (token exists && not empty).
- Datenmodell/Server-Logik anpassen
- models/muc4taxiUserModel.js:
- Felder verwenden: UUidVersion (3 = migriert), UUid, UUidList (keine Parallel-Listen).
- Optional: deviceSecret/deviceTokens falls HMAC/HOTP gewünscht.
- auth/authController.js:
- Login: Bei UUidVersion!=3 trigger: sende Magic-Mail wie bei Registrierung (sendMagicMailController), setze forceNeuanmeldung=true, antworte mit Hinweis.
- Magic-Link (magicAuthController): Verifiziert E-Mail, erzeugt neuen accountgebundenen token, berechnet neueDeviceId serverseitig (Fingerprint/HMAC/UUID), speichert in UUid/UUidList[0], setzt UUidVersion=3, forceNeuanmeldung=false; invalidiert alte token/Device-IDs.
- checkDeviceLimit/Session-Handling: keine Dual-Akzeptanz nach Migration; UUidVersion>=3 => nur neue UUid/UUidList.
- middleware/deviceAuthMiddleware.js (& weitere Checks): nach Migration nur neue UUid/UUidList akzeptieren (kein Dual-Support).
- Online/Sperrlisten (UserOnlineListe, SperrDevice): Alte Einträge entfernen, neue mit aktueller Device-ID anlegen.
- Frontend anpassen
- Login.svelte: Keine eigene Device-ID-Bildung; Server generiert Device-ID. Bei UUidVersion!=3: Anzeige „E-Mail-Bestätigung erforderlich“, Magic-Link anfordern. Nach Klick/Bestätigung neues Login mit vom Server gelieferten Daten (UUid/UUidList, token).
- authHeaders.js: x-device-id aus aktueller UUid/UUidList[0] (Serverwert); kein Fallback auf alte Werte.
- userDataStore: forceNeuanmeldung-Flow beibehalten; nach Re-Login nur neue ID speichern, alte verwerfen.
- Fingerprint-Utils: Falls nötig nur Rohdaten sammeln, keine eigenständige Hash-Logik; Server berechnet Device-ID.
- Migrationsskript
- Neues Script (z.B. server/scripts/migrateDeviceIds.js):
- Filter auf gültige User (validBis >= now, !userEmailBlocked). Ungültige/abgelaufene bleiben unberührt (manuell).
- Setze forceNeuanmeldung=true und markiere „Magic-Link erforderlich“ (z.B. Flag im User).
- Keine Pre-Generation: neuer token/deviceId erst nach Klick des Magic-Links.
- Online/Sperrlisten aufräumen (alte UUid-Einträge entfernen, neue anlegen), sobald Magic-Link eingelöst.
- Log Ausgabe: markiert/übersprungen/Fehler.
- Rollout-Übergang
- Deploy Backend/Frontend mit Dual-Support (alt+neu).
- Führe Migrationsskript einmal aus (setzt forceNeuanmeldung + Magic-Link erforderlich) – harter Wechsel, kein Dual-Support.
- Nutzer sehen „Neu anmelden per E-Mail-Link“; LocalStorage wird gelöscht; nach Klick auf Link und erfolgreichem Login erhalten sie neue token/Device-ID.
- Monitoring: Login-Fehler, 403-Anteile, Anzahl migrierter User (UUidVersion==3).
- Cleanup (nach ausreichender Quote migrierter User)
- Kein Dual-Support: Alte UUid/UUidList sofort nicht mehr akzeptieren; Code-Pfade entfernen.
- Alte UUid-Daten aufräumen (optional Felder leeren).
- Unique-Index auf UUid/UUidList[0] (partial: exists && not empty), falls gewünscht.
- forceNeuanmeldung-Flags zurücksetzen, wenn nicht mehr benötigt.
- Sicherheit/Validierung
- Bei jedem Request Lizenz/Status serverseitig prüfen (validBis, userEmailBlocked, forceNeuanmeldung).
- Device-ID muss in UUidList liegen (nur neue Werte).
- Optional: Access-Tokens ohne Refresh-Token verwenden (oder Refresh an user+deviceId binden).
Rückfall
- Falls Probleme: Per Backup/Restore der UUid-Felder zurückrollen; forceNeuanmeldung für betroffene Accounts aufheben.