docs: test scenarios for the auth / recovery / memory series

Section E (E1-E7) covers the fixes that had none: reauth inline retry,
recovery setup + redeem on argon2id-v2, recovery commit-after-save, the
sessionStorage key removal, and a slideover regression guard after deleting
the dead entry modal. Dropped the now-done "legacy entry modal" item from the
remaining list.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
r-zakarya
2026-07-25 14:38:16 +01:00
parent 0434eec85e
commit f45b96d147
+59 -9
View File
@@ -178,17 +178,67 @@ Symptôme du bug : après relance, lignes au nom vide / `(no name)`.
--- ---
## E — Auth / recovery / mémoire (série 2026-07-25)
Ces flux touchent la dérivation de clé et l'anti-lockout : tester sur un compte
**argon2id-v2** (défaut courant). Rebuild **Delphi** requis (fixes serveur) +
BuildAssets pour le JS.
### E1 · reauth — mauvais master pw reste inline (les 4 flux)
- **ACTION** : sur chacun de *Set/Change PIN*, *Enable Quick Unlock*,
*Generate recovery code*, *Export* → taper un **mauvais** master pw.
- **ATTENDU** : le modal **reste ouvert** avec « Wrong master password. Attempt
N / 5. » ; au 5ᵉ échec ou 429 → toast lockout + fermeture. **Annuler** à tout
moment = action abandonnée, rien fait.
- **Historique** : PIN / Quick Unlock / recovery fermaient + toast au 1ᵉʳ essai.
### E2 · recovery setup sur compte argon2id-v2
- **ACTION** : *Generate recovery code* → bon master pw.
- **ATTENDU** : code généré, **pas** de « invalid password ».
- **Historique** : `/recovery-key/setup` rejetait tout compte -v2 / argon2id
(vérif serveur ne connaissait que pbkdf2 / pbkdf2-sha256).
### E3 · recovery generate → annuler n'écrit rien
- **PRÉ** : un code de recovery **existe déjà**.
- **ACTION** : *Regenerate code* → bon master pw → à l'affichage du code,
**Cancel** (ou Esc).
- **ATTENDU** : toast « Cancelled — no recovery code was set » ; l'**ancien**
code fonctionne toujours au redeem. Refaire avec **I saved it** → nouveau
code actif, ancien invalidé.
- **Historique** : le setup était POSTé avant l'affichage → annuler écrasait
quand même l'ancien code (chemin silencieux vers le lockout).
### E4 · recovery redeem sur compte argon2id-v2
- **ACTION** : générer un code, se déconnecter, *Use a recovery code* →
username + code.
- **ATTENDU** : déverrouillage OK, redirection vers *Change master password*.
Le coffre se déchiffre (clé dérivée avec les **bons** params Argon2 renvoyés
par le serveur).
- **Historique** : la réponse redeem n'echoait pas `argon2` → params par
défaut (correct aujourd'hui, lockout latent si params non-défaut).
### E5 · la clé du coffre n'est plus en clair dans le web storage
- **ACTION** : coffre déverrouillé → console WebView2 :
`sessionStorage.getItem('cryptoKey')`.
- **ATTENDU** : `null`. (Avant : une string base64 de 44 car = la clé AES.)
- **Bonus** : dump mémoire du renderer → `this_is_password` peut persister
(strings V8, non corrigeable) ; c'est la **clé** qu'on a retirée du storage.
### E6 · non-régression — les 4 exporteurs de clé marchent toujours
Après le retrait du cache sessionStorage, re-tester que ces flux (qui
`exportKey` la clé) fonctionnent : **login**, **Quick Unlock**, **PIN**,
**recovery redeem**, **change master password**.
### E7 · non-régression — éditeur slideover après suppression du modal mort
Le générateur, les tags et la barre de force étaient partagés. Vérifier dans
l'éditeur slideover : créer + éditer une entrée, ajouter/retirer des tags,
**Generate → Use** insère le mot de passe, la barre de force réagit.
---
## Reste à traiter (constaté pendant l'audit, non corrigé) ## Reste à traiter (constaté pendant l'audit, non corrigé)
1. **Modale d'entrée héritée = code mort.** `openEntryModal` n'a **aucun 1. **Attachments hors garde A11.** Le contrôle « changed elsewhere » couvre le
appelant** ; `saveEntry`, `closeEntryModal`, le markup `#entryModal` et
leurs listeners ne sont plus atteignables. Danger : `saveEntry` fait un PUT
**partiel** (ni `kind`, ni `totp_secret`, ni `custom_fields`, ni
`template`) — exactement le bug que `moveEntryToFolder` documente comme
à ne jamais refaire. À supprimer (JS + HTML) tant qu'il n'est pas recâblé
par erreur.
2. **Attachments hors garde A11.** Le contrôle « changed elsewhere » couvre le
payload de l'entrée, pas ses pièces jointes (table séparée, écrites par payload de l'entrée, pas ses pièces jointes (table séparée, écrites par
leurs propres endpoints). Un sync qui remplace une pièce jointe pendant leurs propres endpoints). Un sync qui remplace une pièce jointe pendant
l'édition n'est pas signalé. Faible risque : l'éditeur ne re-ship jamais l'édition n'est pas signalé. Faible risque : l'éditeur ne re-ship jamais