2.3 KiB
2.3 KiB
name, description, metadata
| name | description | metadata | ||||||
|---|---|---|---|---|---|---|---|---|
| project_2fa | Implémentation complète du 2FA (TOTP + email OTP) — DB, backend, frontend Login et MonCompte |
|
Fonctionnalité 2FA ajoutée en session juin 2026.
DB (db/index.js) — colonnes sur users : totp_secret TEXT, totp_enabled INTEGER DEFAULT 0. Tables : two_fa_sessions (session temporaire entre /login et /2fa/verify, 5 min), two_fa_email_codes (OTP email 6 chiffres, 5 min), two_fa_trusted_devices (appareils de confiance 30 jours, avec user_agent et ip_address).
Backend (auth.js) — routes :
POST /login: sitotp_enabled→ vérifiedeviceToken(headerX-Device-Token), sinon retourne{ requires2FA: true, sessionToken }GET /2fa/setup: génère secret TOTP + QR code base64 (libotplibAPI fonctionnelle)POST /2fa/confirm-setup: vérifie code, active 2FAPOST /2fa/disable: désactive (mot de passe requis), efface tous les appareils de confiancePOST /2fa/send-email-code: envoie OTP 6 chiffres par email (validité 5 min)POST /2fa/verify: vérifie code (TOTP ou email), émet JWT, créetwo_fa_trusted_devicessitrustDevice=trueGET /trusted-devices: liste appareils de confiance actifsDELETE /trusted-devices/:id: révoque un appareilDELETE /trusted-devices: révoque tous
Frontend :
AuthContext.jsx:login(email, password, deviceToken)retourne{ requires2FA, sessionToken }si 2FA actif ; nouvelle fonctioncompleteLogin(token, user)appelée après vérification du codeLogin.jsx: machine à 3 états (form→method→code) ; countdown 5 min pour OTP email ; checkbox "Faire confiance 30 jours" ;cl_device_tokenstocké dans localStorageMonCompte.jsx> Sécurité : composantTwoFASection(QR code setup, clé manuelle, confirmation code, désactivation) + composantTrustedDevicesSection(liste appareils, badge APPAREIL ACTUEL, déconnexion individuelle ou tout)api.js:authHeaders()envoie automatiquementX-Device-Tokensicl_device_tokenprésent
Why: Sécurité renforcée, demande utilisateur.
How to apply: Toujours envoyer X-Device-Token depuis authHeaders() (déjà en place). Ne pas exposer les tokens bruts dans les réponses API.