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:
+59
-9
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user