diff --git a/mainApk.pas b/mainApk.pas index 20d6f93..bbcfff3 100644 --- a/mainApk.pas +++ b/mainApk.pas @@ -395,13 +395,21 @@ end; /// Intitule discret au-dessus d'une valeur. Meme forme pour toutes les /// lignes, y compris celle du TOTP. -function MakeRow(AParent: TFmxObject; const ACaption: string; +/// AOrder fixe la place de la ligne dans la liste d'enfants du parent. +/// +/// SANS LUI L'ORDRE N'EST PAS STABLE : observe sur appareil, le formulaire +/// s'affichait dans le bon ordre a la premiere ouverture puis a l'envers apres +/// un verrouillage. Les conventions d'empilement de FMX different deja entre +/// TLayout et TVertScrollBox ; apres destruction et recreation des lignes, +/// elles ne sont meme plus constantes. On ne s'y fie donc pas du tout. +function MakeRow(AParent: TFmxObject; const ACaption: string; AOrder: Integer; out AValue: TLabel): TLayout; var LCap: TLabel; begin Result := TLayout.Create(nil); // detruite a la main, voir ClearDetailRows Result.Parent := AParent; + Result.Index := AOrder; Result.Align := TAlignLayout.Top; Result.Height := 62; Result.Margins.Rect := RectF(12, 10, 12, 0); @@ -546,7 +554,7 @@ end; procedure TForm8.ShowDetail(AVaultIndex: Integer); var LMeta, LPwdCaption: string; - I: Integer; + I, LOrder: Integer; LRow: TLayout; LValue: TLabel; @@ -602,11 +610,13 @@ begin SetLength(FRowShown, Length(FRows)); SetLength(FRowCtls, Length(FRows)); - // Le TOTP EN PREMIER, donc en tete d'ecran : c'est ce qu'on vient chercher - // sur un telephone. Seule ligne vivante, rafraichie chaque seconde. + // Le TOTP en tete d'ecran : c'est ce qu'on vient chercher sur un telephone. + // Seule ligne vivante, rafraichie chaque seconde. + LOrder := 0; if FCurrent.Totp <> '' then begin - LRow := MakeRow(FDetBody, 'Code 2FA', FTotpValue); + LRow := MakeRow(FDetBody, 'Code 2FA', LOrder, FTotpValue); + Inc(LOrder); SetLength(FRowCtls, Length(FRowCtls) + 1); FRowCtls[High(FRowCtls)] := LRow; FTotpValue.TextSettings.Font.Size := 26; @@ -615,13 +625,10 @@ begin FTotpTimer.Enabled := True; end; - // DANS L'ORDRE, ici : au sein d'un TVertScrollBox les enfants alignes en - // haut s'empilent dans l'ordre de creation - l'inverse d'un TLayout, ou le - // dernier cree se retrouve en tete. Se tromper de convention renvoie le - // formulaire a l'envers, sans rien casser d'autre. for I := 0 to High(FRows) do begin - LRow := MakeRow(FDetBody, FRows[I].Caption, LValue); + LRow := MakeRow(FDetBody, FRows[I].Caption, LOrder, LValue); + Inc(LOrder); FRowCtls[I] := LRow; FRowValues[I] := LValue; FRowShown[I] := False; @@ -851,6 +858,29 @@ begin Exit; end; FLog.Lines.Clear; + + // MEME PORTE QUE « Ouvrir le coffre ». Sans cela la protection ne tenait + // qu'a un bouton pres : synchroniser reconstruit le coffre depuis le serveur + // et l'affiche, ce qui revient exactement au meme resultat sans passer par + // l'authentification. La condition est la presence d'un cache protege sur + // cet appareil - c'est lui qui exprime le choix de l'utilisateur. + if VaultNeedsAuth and (FVault.Count = 0) then + begin + Status('Authentification...'); + AuthenticateThen('Acceder au coffre', + procedure(AOutcome: TBioOutcome) + begin + if AOutcome = boOK then + FetchAndDecrypt(LUrl, LTok, LPwd) + else + begin + Log('Synchronisation refusee : ' + LastBiometricError); + Status('Authentification requise'); + end; + end); + Exit; + end; + FetchAndDecrypt(LUrl, LTok, LPwd); end;