Commit Graph

150 Commits

Author SHA1 Message Date
r-zakarya 255d685e73 fix(apk): 2 min de grace apres une copie, retour automatique decoche par defaut
Android ne laisse pas choisir l'app qui passe devant : moveTaskToBack
ramenait souvent l'ecran d'accueil. Le coffre se reverrouillait aussi
apres 30 s, avant qu'on revienne chercher le mot de passe.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-18 14:48:23 +01:00
r-zakarya f99fb90ed8 fix(apk): compilation des reglages Copy and search (declarations et TPath de System.IOUtils)
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-18 14:35:45 +01:00
r-zakarya f7ad65c02d feat(apk): Settings -> Copy and search, deux cases pour le retour apres copie et le clavier sur la recherche
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-18 14:33:18 +01:00
r-zakarya 946880ecf4 feat(apk): copier renvoie a l'app d'avant, recherche prete a l'ouverture et au retour
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-18 14:28:52 +01:00
r-zakarya 95c308107c fix(apk): Save enregistre l'URL et le jeton tout de suite, sans attendre un telechargement
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-18 12:36:22 +01:00
r-zakarya a9640ab48f fix(apk): la release ne preremplit plus l'adresse du depot de l'auteur
Verifie : ni la bibliotheque release ni l'exe PC ne contiennent plus
ai-agents4you.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-18 12:29:27 +01:00
r-zakarya 4555a791b5 fix(apk): plus d'ecran bleu apres le premier scan (la vue web reste masquee apres l'autorisation camera)
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-18 12:22:13 +01:00
r-zakarya 05fc75e8f8 fix(apk): un faux mot de passe de synchro n'ouvre plus le depot, et il se verifie a l'enregistrement
- OpenContainer reutilisait la cle de l'ancien mot de passe : jamais tant
  qu'un nouveau n'est pas verifie
- un essai rate vidait FKey (parametres out TBytes) : derivation dans des
  locales, rangee seulement apres succes
- Save coffre ouvert : verification immediate (DoSync), le bon mot de passe
  est range dans le coffre scelle ; coffre ferme, le champ est grise

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-18 11:51:02 +01:00
r-zakarya 395d7a70d4 fix(apk): un mot de passe de synchro change est verifie contre le depot avant toute publication
Le sha inchange faisait repondre 'rien n'a change' sans dechiffrer : un
mot de passe faux passait pour bon. Tant qu'il n'est pas verifie, le depot
est retelecharge en entier ; la synchro reprend ensuite si rien n'echoue.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-18 11:38:30 +01:00
r-zakarya c809f4e4c5 fix(apk): le mot de passe de synchro enregistre dans les reglages n'est plus ecrase par celui du cache
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-18 11:13:24 +01:00
r-zakarya 3c16b41714 feat(sync): GitHub en plus de Gitea, et refus d'un depot public
GitHub parle la meme API des contenus (base64, sha, corps du PUT) : meme
chemin, reconnu a api.github.com/repos/. User-Agent pose partout (GitHub
refuse sans). Un depot public est refuse avant toute lecture ou ecriture,
Gitea comme GitHub : l'historique garde tous les instantanes chiffres.
Telephone : github.com/O/R se convertit en URL d'API et inversement.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-18 10:36:18 +01:00
r-zakarya ba8c4205f9 feat(apk): generateur de mot de passe, erreurs du depot affichees dans les reglages
- de sur le champ mot de passe (nouvelle entree et modification), tirage
  crypto.getRandomValues avec rejet
- Download vault sans reglages ouvre les reglages
- 404/401 tranches (jeton refuse, utilisateur ou depot inexistant, fichier
  absent) et mauvais mot de passe de synchro : les reglages s'ouvrent avec
  le message en rouge

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-18 10:18:47 +01:00
r-zakarya 137fa24d19 fix(apk): le libelle du mode d'ouverture suit le scellement apres un telechargement
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-17 21:56:39 +01:00
r-zakarya 451574394e feat(apk): l'app s'appelle Vault, et la release n'est plus debuggable
Delphi ecrivait android:debuggable=true meme en Release : sur un telephone
avec le debogage USB actif, adb run-as ouvrait le dossier prive de l'app.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-17 21:50:26 +01:00
r-zakarya 1d2ea55bec feat(apk): creer un coffre local seulement en debogage (AllowCreateLocal)
En release le telephone ne sait que reprendre le coffre du depot : l'ecran
d'accueil n'offre plus que Download vault, et RegisterLocal refuse aussi.
Depot vide (404) ou conteneur illisible : rien n'est cree.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-17 21:14:16 +01:00
r-zakarya 22b1120228 fix(apk): la camera s'affiche des le premier scan apres l'autorisation
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-17 19:05:51 +01:00
r-zakarya c53b3b0b8b chore(apk): retire le diagnostic temporaire du scan QR
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-17 19:01:25 +01:00
r-zakarya fb5d2f35a2 fix(apk): le lien du QR est accepte meme precede d'un caractere invisible
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-17 18:53:14 +01:00
r-zakarya 23967ddfca fix(sync): QR plus court (adresse du depot, sans sur-echappement) + TRY_HARDER au decodage
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-17 18:48:04 +01:00
r-zakarya dd9fd62dcb feat(apk): scanner le QR du poste depuis l'app (ZXing.Delphi, Apache 2.0)
Le scanner du systeme demandait avec quoi ouvrir le lien. L'app ouvre la
camera arriere, decode une image sur quatre et remplit URL + jeton des
qu'un lien pmserver://sync est lu. Rien n'est enregistre avant Save.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-17 18:38:41 +01:00
r-zakarya 780eecc11b feat(sync): le QR porte un lien pmserver://sync ouvert directement par l'app
Le scanner du telephone envoyait le texte a une recherche web (Google,
Chrome) : le jeton serait parti a un appui pres. Le lien a schema propre
n'a qu'une application pour l'ouvrir. Rien n'est enregistre avant Save.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-17 18:29:37 +01:00
r-zakarya f817a6df43 feat(sync): QR des reglages sur le PC, Paste settings sur le telephone
Le poste genere le QR (DelphiZXingQRCode, Apache 2.0) depuis ses prefs :
URL + jeton, jamais le mot de passe de synchro. Le telephone lit le texte
copie par l'appareil photo et remplit les champs ; Save valide.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-17 18:03:00 +01:00
r-zakarya 826b0809aa feat(apk): URL du depot affichee en forme courte + sync password quand le coffre vient de la synchro
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-17 17:38:47 +01:00
r-zakarya 8269d99b5b feat(apk): copie de secours au mot de passe, le coffre survit au retrait du schema
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-17 15:13:13 +01:00
r-zakarya d6bf06b6a7 feat(apk): coche sur la facon d'ouvrir en place + journal du mode detecte
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-17 15:02:22 +01:00
r-zakarya 799f75d53d feat(apk): choisir d'ouvrir avec le verrouillage d'ecran, un code ou le mot de passe du coffre
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-17 14:44:08 +01:00
r-zakarya 23568049da feat(android): saisir le secret 2FA des la creation d'une entree
Le formulaire New entry n'avait pas le champ et AddEntry ecrivait
totp_secret = '' en dur : il fallait enregistrer l'entree puis la rouvrir
pour poser un second facteur, alors que l'editeur portait deja le champ.

Meme intitule que l'editeur ("2FA secret"), masque pour une note comme
site et identifiant, et achemine par &o= — t, s, u, p, k, d etaient
pris.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-06 19:18:39 +01:00
r-zakarya cbcdb3f593 fix(android): le temoin bleu sait enfin s'eteindre
FRemoteAhead etait remis a faux a trois endroits - publication,
publication differee, rafraichissement - et aucun ne le disait a la page.
Seul l'allumage etait pousse. Le point bleu restait donc affiche apres la
synchronisation qui venait de le rendre caduc, jusqu'au retour suivant
sur l'accueil.

Un temoin qui reste allume apres qu'on a fait ce qu'il demandait ne
demande plus rien : il decore, et on apprend a ne plus le regarder.

Le drapeau et son affichage passent maintenant par SetRemoteAhead, dans
les deux sens. Meme asymetrie, meme correction que pour le point orange.

PROBE_EVERY_TICKS revient a 40 : la bascule a 8 n'etait que pour rendre
la serie E observable en deux minutes.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-29 00:27:40 +01:00
r-zakarya b2c677997e fix(android): un faux echec de synchronisation, et des boutons colles
Le chien de garde mesurait la duree TOTALE, alors que son message dit
"no reply from the server". Sur un coffre devenu gros - 286 Ko - la
reponse arrivait en 841 ms et les vingt secondes suivantes partaient dans
la derivation de la cle puis l'affichage : il criait donc a l'absence de
reponse alors que tout avait reussi, cache ecrit compris. Un faux echec
est pire qu'un vrai, il apprend a se mefier de ce que l'application dit.

Il est desarme des que le statut HTTP est connu, quel qu'il soit : ce qui
suit ne depend plus du reseau, et le voile est leve par le finally.

Au passage, les boutons des reglages n'avaient pas de margin-top : le
champ du code et ses deux boutons se touchaient et se lisaient comme un
seul bloc. Les piles de l'accueil ont leur gap ; ici les elements se
suivent en flux normal, donc c'est au bouton de reserver sa place.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-29 00:22:45 +01:00
r-zakarya 363b934e8a fix(android): le temoin d'attente parait des l'accueil, sans ouvrir le coffre
FPending est relu au demarrage, mais PM.setPending n'etait pousse que par
OpenLocalNow : la page n'apprenait donc l'attente qu'en OUVRANT le
coffre. Un demarrage a froid montrait Sync sans point orange - l'ecran ou
l'on decide de synchroniser, et le seul moment ou ce drapeau relu au
demarrage sert a quelque chose. Il fallait ouvrir puis reverrouiller pour
qu'il paraisse.

Les deux temoins se reposent maintenant dans ShowUnlock, donc a chaque
retour sur l'accueil.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-28 22:31:27 +01:00
r-zakarya 85691bb2f1 feat(android): un bouton pour jeter le coffre local, en debogage seulement
Il vit en bas des reglages, apres tout le reste, et demande deux appuis :
un effacement sans retour ne se declenche pas sur un doigt qui glisse.

Absent en release, et pas seulement cache : la commande du pont n'est pas
compilee et Delphi ne devoile la section que dans une version de
debogage. Le bouton ne peut donc pas reapparaitre par accident. Verifie -
Release compte 8060 lignes contre 8072 en debug, soit exactement ce bloc.

DropLocalVault efface le cache, le conteneur local et le drapeau
d'attente, chacun sous son propre try : un fichier absent ou verrouille
ne doit pas empecher les deux autres de partir. Les reglages du depot
restent - c'est le coffre qu'on jette, pas la facon d'aller le rechercher.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-28 21:47:53 +01:00
r-zakarya d428a6fc7f feat(android): un coffre telecharge n'est plus lisible sans rien demander
Sans biometrie utilisable et sans code pose, le cache s'ouvrait sans rien
demander - or il CONTIENT le mot de passe de sync. Qui tenait le
telephone deverrouille obtenait donc le coffre ET le secret du depot.

Il est desormais scelle sous le mot de passe qui vient de le rapporter :
celui-ci est deja dans ce fichier, donc rien de neuf n'est expose, et
l'utilisateur le connait puisqu'il vient de le taper. C'est aussi la
seule forme de cache qui survive a une reinitialisation du verrouillage
d'ecran.

Pas quand l'appareil sait authentifier : VER_PIN et VER_WRAP s'excluent,
et imposer une frappe a qui a une empreinte serait un recul.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-28 17:25:16 +01:00
r-zakarya 5cc80727d6 fix(android): l'exception etait lue apres sa liberation
Register et Login mettaient leur gestionnaire d'erreur en file avec
TThread.Queue, puis y lisaient E.ClassName et E.Message. Or la file
s'execute sur le thread principal bien apres que le except a rendu la
main, et Delphi libere E en sortant du gestionnaire : c'etait une lecture
apres liberation.

Elle rendait un message vide - "Login failed: EPMACrypto - " sans la
raison - et parfois une violation d'acces qui remontait a FMX sans rien
laisser au journal. Le vrai motif de l'echec n'a donc jamais ete affiche.

On ne met plus en file que des chaines, qui survivent.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-28 16:46:24 +01:00
r-zakarya 4e0223bee5 fix(android): aucune exception ne sort du pont sans laisser son nom
Le dispatch n'etait garde par rien : une faute dans un handler remontait
jusqu'a FMX, qui affichait "Access violation" avec une adresse, tandis
que le journal ne montrait que la commande recue suivie de rien. On
savait qu'une commande echouait, jamais laquelle ni pourquoi.

On attrape, on nomme, et on rend la main - une commande fautive ne doit
pas laisser l'interface voilee derriere une boite de dialogue.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-28 16:39:10 +01:00
r-zakarya a41c61405c fix(android): retirer le code de deverrouillage demande de le connaitre
Le coffre ouvert ne prouvait rien : il peut l'etre depuis une heure et
rester a l'ecran. Quiconque trouvait le telephone dans cet etat levait la
protection en deux appuis, sans que rien ne le lui demande.

Le code courant voyage maintenant avec la demande, et Delphi le compare a
FPinSealed - ce sous quoi le cache est REELLEMENT scelle, pose seulement
par une ouverture reussie, jamais par un champ.

Fermee au passage : SetUnlockCode('') retirait le code en silence, ce qui
contournait le controle qu'on vient de poser.

Le FBusy de ClearUnlockCode ne sort plus sans un mot - une sortie muette
se lit comme une reussite.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-28 16:30:30 +01:00
r-zakarya 203f45eb7c fix(android): les refus se voient, et la croix se recale sur le champ
Un refus s'affichait du meme gris qu'un etat : "Master password: 8
characters at least" se lisait comme "Vault on this device", et rien ne
disait que l'application venait de refuser. StatusErr le met en rouge -
deux procedures plutot qu'un drapeau devine du texte, parce que trier des
messages sur leur contenu a deja detruit un cache dans ce projet. C'est
l'appelant qui sait s'il refuse.

La croix des champs etait calee a top: 8px, en compensation du margin-top
du champ. Les piles annulent ce margin depuis qu'on y a unifie
l'espacement, et la croix restait donc 8 px trop bas. Elle s'ancre
desormais au bord INFERIEUR, le seul que le champ touche dans les deux
cas.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-28 16:25:07 +01:00
r-zakarya 494efddb44 feat(android): le mot de passe de creation ouvre le coffre
Il ne servait qu'une fois, a la creation : le cache s'ouvrait ensuite
sans rien demander, et n'importe qui tenant le telephone deverrouille
lisait le coffre.

Il est desormais pose comme code de deverrouillage - c'est exactement ce
que ce format sait faire, et il accepte un mot de passe entier aussi bien
que des chiffres depuis qu'on a retire le clavier numerique. Le cache
porte donc VER_PIN, la seule forme qui survive aussi a une
reinitialisation du verrouillage d'ecran.

Retirable en deux appuis depuis les reglages, pour qui prefere
l'ouverture immediate.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-28 16:14:54 +01:00
r-zakarya 9b26a1dbd0 fix(android): un coffre vide n'est pas un coffre ferme
"Coffre ouvert" se lisait sur le nombre d'entrees. Or un coffre vide en
compte zero, exactement comme un coffre ferme - et le coffre d'essai
l'est. Le garde de DoSync restait donc vrai apres l'ouverture, rearmait
la reprise, et l'on tournait en rond : le journal repetait "Vault opened
from cache", l'interface clignotait et ne repondait plus.

Le meme idiome se trouvait a deux autres endroits. Le second compte :
OnIdleTimer se coupait de lui-meme sur un coffre vide, qui restait donc
ouvert indefiniment - et vide aujourd'hui ne veut pas dire vide dans dix
minutes.

FPlain, le clair en main, est le seul signal qui ne mente pas.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-28 16:12:20 +01:00
r-zakarya af28788a0a fix(android): Sync ouvre le coffre des qu'il y en a un, pas seulement sous code
Le garde ne couvrait que le cache scelle par un code. Depuis que les deux
secrets sont separes, la reconciliation a besoin de celui du conteneur
local - qui ne se pose qu'a l'ouverture - donc un coffre ne ici refusait
aussi, avec "open vault first", et ouvrir ensuite ne relancait rien : le
bouton Sync ne vit que sur l'accueil, et le coffre ouvert on est sur la
liste.

Un seul garde desormais : s'il y a un cache lisible et que le coffre
n'est pas ouvert, on ouvre et on reprend la synchronisation. Un appareil
sans cache n'est pas concerne - c'est le premier telechargement.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-28 16:07:25 +01:00
r-zakarya dd44a164f6 fix(android): le cache retient le secret qui ouvre CE coffre
La separation laissait FVaultPwd vide apres une ouverture depuis le
cache - seules la creation et la connexion le posaient - et la
reconciliation refusait donc en boucle, "open vault first" alors que le
coffre etait ouvert.

Le cache porte un secret et un seul : celui du conteneur local pour un
coffre ne ici, celui du depot pour un coffre publie. Les deux ne
coexistent jamais, puisque la reconciliation detruit le conteneur local
en passant l'autorite au depot. CachePwd choisit a l'ecriture, et la
relecture le range dans la meme case.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-28 16:04:04 +01:00
r-zakarya ed7ccdd2d6 feat(android): deux secrets separes, comme sur le poste
Le mot de passe de creation scellait le conteneur local ET pretendait
sceller l'instantane du depot. Un coffre cree ici publiait donc sous son
propre mot de passe, que le poste ne savait plus ouvrir - et le
rafraichissement echouait avec "wrong password" sur un depot pourtant
intact.

FVaultPwd ouvre le conteneur local et s'arrete la. Le secret du depot vit
dans les reglages, doit etre le meme sur tous les appareils, et c'est lui
seul qui ouvre et rescelle l'instantane.

Les deux ne se rencontrent qu'a UN endroit, la reconciliation : le
conteneur local s'ouvre sous le sien, puis la cle est jetee avant de
toucher au depot - la garder rescellerait le depot sous le mauvais
secret. Ailleurs ils ne se croisent jamais : un coffre ne ici ne publie
pas, un coffre publie n'a plus de conteneur local.

Migration : rien a rechiffrer. Les coffres existants ont simplement les
deux valeurs egales, et cessent d'etre forces de le rester.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-28 15:58:17 +01:00
r-zakarya 17cfc11084 fix(android): le mot de passe des reglages suit le coffre a CHAQUE ouverture
La correction precedente ne portait que sur la creation et la connexion
locales, qui n'arrivent qu'une fois. Le chemin reellement emprunte est
l'ouverture depuis le cache, a chaque lancement : PushConfig y reposait
la valeur de premier lancement, l'ouverture ne la remplacait pas, et
DoSync la prefere a celle du coffre. Les reglages continuaient donc
d'afficher TEST_PWD.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-28 15:44:54 +01:00
r-zakarya ea2450abfd feat(android): dire pourquoi le cache est illisible, et accepter un mot de passe comme code
"Local vault unreadable" laissait croire a une corruption, donc a une
perte, alors que le coffre est intact dans le depot. Quand Android a
lui-meme detruit la cle - verrouillage d'ecran retire ou reinitialise -
l'application le dit maintenant, et dit aussi que rien n'est perdu.

Le tri passe par un drapeau pose la ou l'invalidation se constate, pas
par un test sur le texte du message : c'est ce tri-la, fait sur des
chaines, qui detruisait autrefois le cache en se trompant.

Le code de deverrouillage accepte un mot de passe, et l'a toujours
accepte - aucune validation n'a jamais impose des chiffres. Seul
inputmode="numeric" le laissait croire, et le clavier numerique
decourageait d'essayer. Clavier complet, libelles et note mis a jour.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-28 15:24:29 +01:00
r-zakarya 8b4130f13e fix(android): les reglages affichaient un mot de passe qui n'etait pas celui du coffre
PushConfig pose FPwd a la valeur de premier lancement - en debogage une
constante, en release du vide - et rien ne la remplacait ensuite. Creer
ou ouvrir un coffre local mettait a jour FSyncPwd seul, si bien que les
reglages continuaient d'afficher l'autre.

Ce n'etait pas qu'un affichage : DoSync PREFERE FPwd a FSyncPwd, au nom
de "ce qui est tape l'emporte" - or rien n'avait ete tape. Les deux
chemins de synchronisation, le rafraichissement de fond et le bouton,
travaillaient donc avec deux mots de passe differents sur le meme coffre.

Le coffre qui vient de s'ouvrir dit desormais son mot de passe, et les
reglages le montrent.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-28 15:06:27 +01:00
r-zakarya a81fd88414 fix(android): la page revenait pas apres un verrouillage hors du coffre
Le masquage ne demande rien - il suffit de ne pas etre sur l'accueil pour
que la vue disparaisse avant la capture des applications recentes, coffre
ouvert ou non. La restitution, elle, exigeait un coffre ouvert.

Consulter les REGLAGES coffre ferme, puis laisser le telephone se
verrouiller, cachait donc la page pour de bon : au retour il ne restait
que le fond de la fenetre, un aplat bleu sans rien dessus et sans rien
pour en sortir.

La vue revient maintenant dans tous les cas, et APRES le verrouillage
eventuel pour ne jamais montrer une liste qu'on vient d'effacer.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-28 14:58:18 +01:00
r-zakarya 900f5ba740 fix(android): poser, changer et retirer le code exigent un coffre ouvert
Deux branches de l'ouverture posaient le code a partir de ce qui trainait
dans les champs.

La premiere appliquait un "nouveau code" depose par les reglages. Elle
n'exigeait rien de celui qui le deposait : n'importe qui tenant le
telephone deverrouille pouvait en poser un, et c'est le proprietaire qui,
en ouvrant son coffre, l'appliquait contre lui-meme.

La seconde rescellait sous le code tape des que le cache ne l'etait plus,
ce qui DEFAISAIT LE RETRAIT : on retirait le code, le champ le portait
encore, et l'ouverture suivante le reposait sans qu'un mot le dise. Le
premier octet du cache le disait - VER_PIN apres un retrait annonce
reussi.

Poser et changer passent maintenant par SetUnlockCode, jumeau de
ClearUnlockCode : geste explicite, coffre deja ouvert - donc code courant
connu - et effet immediat. Le champ de l'accueil ne veut plus dire qu'une
chose, "ouvre avec ceci", et ne parait que lorsqu'un code est pose.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-28 14:17:24 +01:00
r-zakarya 6c5fb2f4ea fix(android): Sync ouvre puis synchronise, et l'accueil ne demande plus le nouveau code
Le garde pose juste avant fermait la seule porte : le bouton Sync ne vit
que sur l'accueil, et une fois le coffre ouvert on est sur la liste, ou
il n'existe pas. Synchroniser devenait impossible des qu'un code etait
pose. Sync ouvre donc le coffre - ce qui verifie le code, seul LoadVault
le peut - et OpenLocalNow reprend la synchronisation ou elle s'est
arretee. Le drapeau est consomme des sa lecture, pour qu'un code faux ne
laisse pas une synchronisation en embuscade.

Le champ "new unlock code" quitte l'accueil : les reglages posent et
changent le code, il y faisait doublon sur l'ecran ou l'on veut seulement
ouvrir. Il reste dans la page, cache - c'est lui que "Set this code"
remplit avant pushConfig.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-28 12:50:15 +01:00
r-zakarya 138abea88d fix(android): Sync ouvrait le coffre sans demander le code
Le garde de DoSync ne couvrait que l'empreinte, et les deux protections
s'excluent : un cache scelle par un code porte VER_PIN, donc
VaultNeedsAuth y est FAUX. Synchroniser reconstruisait le coffre depuis
le depot et l'affichait sans que le code soit demande - il ne gardait
qu'un bouton sur deux.

Exiger un champ rempli n'aurait rien valu : le depot est scelle par le
mot de passe de sync, pas par le code, donc rien ici ne le confronte a
quoi que ce soit et n'importe quelle frappe serait passee. Seul LoadVault
sait si le code est le bon, et c'est "Open vault" qui l'appelle - d'ou le
renvoi vers lui.

Place AVANT ReconcileWithRemote et PublishPending, qui sortent de DoSync
par leurs propres chemins.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-28 12:41:36 +01:00
r-zakarya ba4ab18d0f feat: the last three passwords travel, and the phone can show them
The desktop keeps twenty previous versions per entry and never sent any. It
now sends three.

Three, not twenty, because the trade is not symmetrical. On the desktop they
sit encrypted column by column and never move. In the snapshot everything
travels in the clear inside the container, and comes down into a phone cache
sealed only by the device key - not by the master password. An old password
stays sensitive: it is often still valid somewhere else. The real use of the
list is short - "I changed it recently, what was it?" - and three cover it.
The other seventeen would be copies with no need facing them.

The phone reads them ON DEMAND from the raw snapshot, never into TVault:
loading them with the vault would put every entry's old passwords in the clear
in memory from the moment it opens, for something one looks at now and then.

Copying goes by RANK, not by value. The page displays the text but never sends
it back - that is the bridge's rule everywhere else, and an old password has
no reason to be the exception just because it happens to be on screen.

They leave with the plaintext at lock, on both sides.
2026-08-22 16:14:04 +01:00
r-zakarya 2010dec22a feat(android): an entry can get its icon, through the same relay as the desktop
Fetching https://<site>/favicon.ico directly would resolve a DNS name - and
open a connection - to EVERY domain kept in the vault. The list of sites where
someone holds an account is precisely what this vault protects; handing it to
the network for a sixteen-pixel drawing would be a poor trade. The relay sees
only that someone is interested in one domain, which is why the call is asked
for entry by entry and never happens on its own.

Two tries: the full host, then the second-level domain - chat.qwen.ai has no
icon at the relay, qwen.ai does. The type comes from the first bytes, never
from the extension: the relay answers PNG under a .ico address.

A dedicated patch rather than PatchEntryField, because icon_custom is a NUMBER
in the snapshot and writing it as a string would give "0" - which the desktop
reads with GetValue<Boolean> and would choke on. It is set to zero: the icon
comes from an automatic lookup, not from a choice, and that flag is what stops
the desktop from ever replacing a chosen icon during a refresh.

Base64 without line breaks. Delphi's encoder wraps at 76 characters by
default, a wrapped data: URI does not display, and that trap has already been
paid once on the containers.
2026-08-22 15:39:19 +01:00