fix(android): locking the vault no longer discards the typed settings
Reported as "the token field saves nothing", and it was exact: LockVault called PushConfig, which pushes the STORED server settings back into the page. Every lock therefore overwrote a freshly typed token with the old one - including the three-minute auto-lock, so it happened with no gesture from the user at all, and the field looked like it forgot on its own. The user's own sequence isolated it: deleting one character gave a 401, which proves the typed value does reach the wire; then open, lock, sync gave a 200 again, the lock having restored the old token in between. PushConfig now runs at startup only. It was pointless in the other four places anyway: PM.wipe clears the list and the detail, never the configuration fields. Along the way, and part of the same confusion: the three settings fields had no labels, only placeholders that vanish once filled - and since the token was masked this morning it became indistinguishable from the sync password sitting right below it. They are labelled now, and the log reports both fingerprints so a value landing in the neighbouring field shows up immediately. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
+32
-8
@@ -32,7 +32,7 @@ interface
|
||||
uses
|
||||
System.SysUtils, System.Types, System.UITypes, System.Classes,
|
||||
System.Diagnostics, System.Rtti, System.NetEncoding, System.DateUtils,
|
||||
System.Generics.Collections, System.IOUtils,
|
||||
System.Generics.Collections, System.IOUtils, System.Hash,
|
||||
FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.Platform,
|
||||
FMX.Controls.Presentation, FMX.StdCtrls, FMX.Memo, FMX.Memo.Types,
|
||||
FMX.ScrollBox, FMX.Layouts, FMX.Edit, FMX.ListBox, FMX.Objects,
|
||||
@@ -418,6 +418,14 @@ begin
|
||||
SetLength(FWebPending, 0);
|
||||
end;
|
||||
|
||||
/// Empreinte courte d'un secret, pour le journal. On veut savoir LEQUEL des
|
||||
/// jetons est en place, jamais sa valeur : huit caracteres de son SHA-256
|
||||
/// suffisent a les distinguer et n'en revelent rien.
|
||||
function Fingerprint(const ASecret: string): string;
|
||||
begin
|
||||
if ASecret = '' then Exit('(vide)');
|
||||
Result := Copy(THashSHA2.GetHashString(ASecret), 1, 8);
|
||||
end;
|
||||
/// Chiffre un petit conteneur, le relit, et le laisse sur le disque prive pour
|
||||
/// qu'une autre implementation le verifie. Iterations volontairement basses :
|
||||
/// ce qu'on eprouve ici est le CABLAGE - cle, IV, place du tag - pas le cout
|
||||
@@ -496,8 +504,8 @@ begin
|
||||
TTimeZone.Local.ToUniversalTime(Now))]),
|
||||
FSyncPwd, 1000);
|
||||
Log('PUT ' + LUrl);
|
||||
Log(' token ' + IntToStr(Length(FToken)) + ' chars, body ' +
|
||||
IntToStr(Length(LBody)) + ' chars');
|
||||
Log(Format(' token %s (%d chars), body %d chars',
|
||||
[Fingerprint(FToken), Length(FToken), Length(LBody)]));
|
||||
// Sha vide : on cree le fichier, ou on echoue en 409 s'il existe deja -
|
||||
// ce qui prouverait le controle de concurrence aussi surement.
|
||||
LRes := LClient.Put(LBody, '', 'write path probe from phone');
|
||||
@@ -528,6 +536,8 @@ begin
|
||||
FUrl := LUrl;
|
||||
if LToken <> '' then FToken := LToken;
|
||||
end;
|
||||
Log(Format('config loaded: token %s (%d chars), url %s',
|
||||
[Fingerprint(FToken), Length(FToken), FUrl]));
|
||||
WebCall(Format('PM.setConfig(%s, %s, %s, %s)',
|
||||
[JsArg(FUrl), JsArg(FToken), JsArg(FPwd),
|
||||
// Replier des champs vides revient a cacher la seule chose a faire.
|
||||
@@ -560,7 +570,16 @@ end;
|
||||
procedure TForm8.OnWebNavigate(ASender: TObject; const AUrl: string);
|
||||
begin
|
||||
// Le moteur navigue aussi pour charger la page elle-meme.
|
||||
if AUrl.StartsWith('cmd://') then HandleWebCommand(AUrl.Substring(6));
|
||||
// L'ACTION SEULE, jamais la requete : elle porte le jeton et le mot de passe.
|
||||
// Sans cette trace on ne peut pas distinguer « la commande n'arrive pas » de
|
||||
// « elle arrive et ne fait rien », et les deux se ressemblent de l'exterieur.
|
||||
if AUrl.StartsWith('cmd://') then
|
||||
begin
|
||||
var LDbg := AUrl.Substring(6);
|
||||
if LDbg.Contains('?') then LDbg := LDbg.Substring(0, LDbg.IndexOf('?')) + '?...';
|
||||
Log('cmd ' + LDbg);
|
||||
HandleWebCommand(AUrl.Substring(6));
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TForm8.HandleWebCommand(const AUrl: string);
|
||||
@@ -613,6 +632,11 @@ begin
|
||||
FUrl := TNetEncoding.URL.Decode(Param('u')).Trim;
|
||||
FToken := TNetEncoding.URL.Decode(Param('t')).Trim;
|
||||
FPwd := TNetEncoding.URL.Decode(Param('p'));
|
||||
// L'empreinte du mot de passe AUSSI : si une saisie destinee au jeton
|
||||
// atterrit dans le champ voisin - les deux sont masques - c'est celle-ci
|
||||
// qui bouge, et le jeton reste inchange sans que rien ne l'explique.
|
||||
Log(Format('config from page: token %s, pwd %s',
|
||||
[Fingerprint(FToken), Fingerprint(FPwd)]));
|
||||
end
|
||||
|
||||
else if LAction = 'openvault' then
|
||||
@@ -678,7 +702,10 @@ begin
|
||||
// Les lignes du detail portent des valeurs EN CLAIR (FRows) : les detruire
|
||||
// fait partie du verrouillage, pas de l'affichage.
|
||||
FCurrent := Default(TVaultEntry);
|
||||
PushConfig;
|
||||
// PAS DE PushConfig HORS DEMARRAGE. Redescendre les coordonnees du serveur
|
||||
// ecrase ce que l'utilisateur vient de taper - l'auto-verrouillage le faisait
|
||||
// donc sans le moindre geste de sa part, et le champ jeton semblait ne rien
|
||||
// retenir. Verrouiller efface le clair ; la configuration n'a rien a y voir.
|
||||
ShowUnlock;
|
||||
end;
|
||||
|
||||
@@ -775,7 +802,6 @@ begin
|
||||
// Un coffre local illisible se remplace, il ne se repare pas.
|
||||
Log('Local vault corrupt: ' + E.Message);
|
||||
ClearVault;
|
||||
PushConfig;
|
||||
ShowUnlock;
|
||||
end;
|
||||
end;
|
||||
@@ -785,7 +811,6 @@ begin
|
||||
// ShowUnlock AVANT le message : il repositionne le statut selon ce que
|
||||
// l'appareil detient, et ecraserait donc l'explication.
|
||||
FVaultUnreadable := True;
|
||||
PushConfig;
|
||||
ShowUnlock;
|
||||
Log('Local vault unreadable: ' + LastStoreError);
|
||||
Status('Local vault unreadable - see log');
|
||||
@@ -841,7 +866,6 @@ begin
|
||||
FVaultUnreadable := True;
|
||||
Log('No usable protection on this device - vault kept but unreadable');
|
||||
Log(' ' + LastBiometricError);
|
||||
PushConfig;
|
||||
ShowUnlock;
|
||||
Status('Screen lock missing - download again to replace the cache');
|
||||
end;
|
||||
|
||||
Reference in New Issue
Block a user