feat(android): TOTP codes and custom fields in the detail screen
The detail screen showed site, username and password and silently dropped everything else - custom fields, notes, 2FA. It is now built per entry rather than from a fixed template: every row is a caption, a value, and whether it is secret, so reveal and copy exist once instead of once per kind of field. Two rows stay special on purpose. A note's body is stored in the password column, so it gets its own caption and no mask. The 2FA code is the only live row - refreshed every second, placed first, since it is what you pull a phone out for. PMA.Totp takes bare base32 or an otpauth:// URI; both travel in snapshots depending on how the entry was created. Checked against all six RFC 6238 vectors, including T=20000000000, which overflows 32 bits. The rows hold plaintext, so clearing them is part of locking, not of navigating away. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -65,6 +65,19 @@ téléchargement peut en produire un. La liste filtre à la frappe sur le nom, l
|
||||
site, l'identifiant et les étiquettes — **pas** sur le mot de passe : personne
|
||||
ne cherche par mot de passe, et le comparer allongerait son séjour en mémoire.
|
||||
|
||||
Le détail est construit **par entrée**, pas d'après un gabarit fixe : site,
|
||||
identifiant, mot de passe et champs personnalisés se ramènent tous à un
|
||||
intitulé, une valeur, et le fait qu'elle soit secrète. Les traiter séparément
|
||||
aurait dupliqué révélation et copie autant de fois qu'il y a de sortes de
|
||||
champ. Deux exceptions assumées : le corps d'une **note**, qui est stocké dans
|
||||
le champ mot de passe et s'affiche donc sous un autre intitulé, sans masque ;
|
||||
et le **code 2FA**, seule ligne vivante, rafraîchie chaque seconde et placée en
|
||||
tête — c'est ce qu'on vient chercher sur un téléphone.
|
||||
|
||||
Le TOTP ([PMA.Totp.pas](PMA.Totp.pas)) accepte le base32 nu comme l'URI
|
||||
`otpauth://`, les deux circulant dans les instantanés selon la façon dont
|
||||
l'entrée a été créée. Vérifié contre les six vecteurs de la RFC 6238.
|
||||
|
||||
Deux règles tenues dans l'interface, pas ailleurs :
|
||||
|
||||
- **Le clair est jeté quand l'application passe en arrière-plan.** L'écran est
|
||||
@@ -127,6 +140,8 @@ Node ouvre le fichier et pas le client, le défaut est dans le client.
|
||||
| `PMA.Store.pas` | coffre local chiffré sous une clé du Keystore |
|
||||
| `PMA.Biometric.pas` | authentification via `FMX.BiometricAuth` |
|
||||
| `PMA.Vault.pas` | l'instantané en mémoire : lecture et recherche |
|
||||
| `PMA.Totp.pas` | codes TOTP (RFC 6238), base32 ou `otpauth://` |
|
||||
| `selftest.dpr` | vérification console : conteneur + TOTP |
|
||||
| `PMA.TestVector.pas` | le vecteur embarqué, plus référencé par l'interface |
|
||||
| `make-testvector.js` | régénère le vecteur avec WebCrypto |
|
||||
| `testvector.md` | valeurs attendues, étage par étage |
|
||||
|
||||
Reference in New Issue
Block a user