Depuis /profile :
- "Codes de récupération 2FA" : régénère les 10 codes (invalide les 10
précédents d'un coup, voir auth.generate_recovery_codes) et les affiche
une seule fois via le même modal qu'à l'inscription (session flash,
core/recovery_codes_flash.py) — mot de passe actuel requis.
- "Adresse email" : change l'adresse (mêmes règles qu'à l'inscription —
format valide, unicité — voir auth/email_validation.py, désormais
partagé avec create_user.py au lieu d'être dupliqué). Pour un compte
"user", le dossier de son unique projet porte le nom de son adresse
(project_slug = slugify(email)) : il est renommé pour suivre le
changement (db/games/move_game.py, même logique d'unicité par suffixe
que create_game()), sans quoi project_slug ne correspondrait plus à
aucun dossier réel. Un "admin" n'a pas de project_slug dédié : rien
n'est renommé pour ce rôle.
18 nouveaux tests (tests/test_profile.py) : mauvais mot de passe refusé
pour les deux actions, mauvais format/email déjà pris refusés, dossier
bien renommé et project_slug mis à jour, connexion possible avec la
nouvelle adresse, anciens codes de récupération bien invalidés après
régénération, modal jamais réaffiché deux fois.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Première des deux grandes fonctionnalités demandées (authentification
d'abord, export HTML/CSS/JS autonome ensuite) :
- Inscription (nom, prénom, email UNIQUE, mot de passe) avec schéma
visuel du mot de passe (jauge + liste de critères qui passent au vert
en direct — auth/password_strength.py, mêmes règles vérifiées côté
serveur qu'affichées côté client).
- Double authentification (TOTP, compatible Google Authenticator/Authy)
OBLIGATOIRE dès l'inscription : QR code (SVG, sans dépendance Pillow)
à scanner puis code à confirmer avant que le compte soit utilisable —
voir auth/create_user.py (totp_confirmed) et routes/auth/register_2fa.py.
- Connexion en 2 temps (mot de passe puis code TOTP), déconnexion.
- Isolation par utilisateur : un compte "user" est limité à un SEUL
projet, dont le dossier est nommé d'après son adresse email (slugifiée)
et créé automatiquement dès la 2FA confirmée — aucune page de gestion
multi-jeux pour lui (redirigé directement vers son propre tableau de
bord). Le rôle "admin" reste illimité, comme le moteur l'a toujours été
(le TOUT PREMIER compte jamais créé sur une base de comptes vide devient
automatiquement admin — voir auth/is_first_user.py — pas de mot de
passe par défaut à faire circuler : s'inscrire en premier suffit).
Un compte "user" ne peut pas non plus supprimer son unique projet
(aucune façon d'en recréer un ensuite).
- Garde d'accès globale (core/auth_guard.py, un seul before_request) :
toute page exige une connexion, sans avoir touché individuellement aux
~80 routes déjà existantes du moteur.
tests/conftest.py isole complètement les tests de la vraie base de
comptes (FORGE_USERS_DB_PATH/FORGE_SECRET_KEY_PATH vers un dossier
temporaire propre à la session de tests) et authentifie automatiquement
la fixture `client` partagée en tant que compte admin de test — les 155
tests déjà existants continuent de passer SANS AUCUNE modification de
leur côté, exactement comme avant l'authentification. 10 nouveaux tests
dédiés (tests/test_auth.py) : inscription/mots de passe/2FA/connexion/
isolation par projet/blocage de suppression, vérifiés en conditions
réelles (vrai client de test Flask, vraie base SQLite, vrais codes TOTP
calculés avec pyotp). 165 tests au total, tous au vert.
Nouvelles dépendances : pyotp, qrcode (requirements.txt).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>