|
|
|
@@ -1,4 +1,4 @@
|
|
|
|
|
unit mainApk;
|
|
|
|
|
unit mainApk;
|
|
|
|
|
{
|
|
|
|
|
Client Android en LECTURE SEULE : deverrouiller, chercher, copier.
|
|
|
|
|
|
|
|
|
@@ -218,7 +218,7 @@ var
|
|
|
|
|
LEvents: IFMXApplicationEventService;
|
|
|
|
|
begin
|
|
|
|
|
inherited;
|
|
|
|
|
Caption := 'Coffre';
|
|
|
|
|
Caption := 'Vault';
|
|
|
|
|
// Le fond de la forme, et non celui du style : tout le reste est peint
|
|
|
|
|
// par-dessus, et un gris herite se verrait entre les blocs.
|
|
|
|
|
Fill.Kind := TBrushKind.Solid;
|
|
|
|
@@ -328,8 +328,8 @@ begin
|
|
|
|
|
FLaySettings.Align := TAlignLayout.Top;
|
|
|
|
|
FLaySettings.Height := 116;
|
|
|
|
|
FLaySettings.Visible := False;
|
|
|
|
|
FToken := TopEdit(FLaySettings, 'jeton Bearer', FIRSTRUN_TOKEN);
|
|
|
|
|
FUrl := TopEdit(FLaySettings, 'URL de l''endpoint', FIRSTRUN_URL);
|
|
|
|
|
FToken := TopEdit(FLaySettings, 'bearer token', FIRSTRUN_TOKEN);
|
|
|
|
|
FUrl := TopEdit(FLaySettings, 'endpoint URL', FIRSTRUN_URL);
|
|
|
|
|
FToken.Margins.Rect := RectF(16, 8, 16, 0);
|
|
|
|
|
FUrl.Margins.Rect := RectF(16, 8, 16, 0);
|
|
|
|
|
// Ce que l'appareil a retenu l'emporte sur les valeurs de premier lancement.
|
|
|
|
@@ -347,20 +347,20 @@ begin
|
|
|
|
|
LRow.Height := 48;
|
|
|
|
|
LRow.Margins.Rect := RectF(16, 8, 16, 0);
|
|
|
|
|
|
|
|
|
|
FBtnLog := FlatButton(LRow, 'Journal', OnToggleLog);
|
|
|
|
|
FBtnLog := FlatButton(LRow, 'Log', OnToggleLog);
|
|
|
|
|
FBtnLog.Align := TAlignLayout.Right;
|
|
|
|
|
FBtnLog.Width := 120;
|
|
|
|
|
FBtnLog.Margins.Left := 8;
|
|
|
|
|
|
|
|
|
|
FBtnSettings := FlatButton(LRow, 'Reglages du serveur', OnToggleSettings);
|
|
|
|
|
FBtnSettings := FlatButton(LRow, 'Server settings', OnToggleSettings);
|
|
|
|
|
FBtnSettings.Align := TAlignLayout.Client;
|
|
|
|
|
|
|
|
|
|
FBtnSync := TopButton(FLayUnlock, 'Synchroniser', DoSync);
|
|
|
|
|
FBtnSync := TopButton(FLayUnlock, 'Sync', DoSync);
|
|
|
|
|
// Accentue : c'est l'action attendue quand aucun coffre n'est encore la.
|
|
|
|
|
FBtnOpen := TopButton(FLayUnlock, 'Ouvrir le coffre', DoOpenLocal, 52, True);
|
|
|
|
|
FBtnOpen := TopButton(FLayUnlock, 'Open vault', DoOpenLocal, 52, True);
|
|
|
|
|
|
|
|
|
|
// Pre-rempli depuis le fichier local, jamais depuis ce fichier-ci.
|
|
|
|
|
FPwd := TopEdit(FLayUnlock, 'mot de passe de sync', TEST_PWD, True);
|
|
|
|
|
FPwd := TopEdit(FLayUnlock, 'sync password', TEST_PWD, True);
|
|
|
|
|
FPwd.Margins.Rect := RectF(16, 16, 16, 0);
|
|
|
|
|
|
|
|
|
|
FStatus := TLabel.Create(Self);
|
|
|
|
@@ -386,7 +386,7 @@ begin
|
|
|
|
|
LBar.Align := TAlignLayout.Bottom;
|
|
|
|
|
LBar.Height := 52;
|
|
|
|
|
|
|
|
|
|
LBtnLock := FlatButton(LBar, 'Verrouiller', OnBackTap);
|
|
|
|
|
LBtnLock := FlatButton(LBar, 'Lock', OnBackTap);
|
|
|
|
|
LBtnLock.Align := TAlignLayout.Left;
|
|
|
|
|
LBtnLock.Margins.Rect := RectF(16, 4, 0, 8);
|
|
|
|
|
LBtnLock.Width := 140;
|
|
|
|
@@ -422,7 +422,7 @@ begin
|
|
|
|
|
//
|
|
|
|
|
// Bouton peint et non TComboBox : le combo etait l'un des deux derniers
|
|
|
|
|
// controles a porter encore le style, et il jurait avec le reste.
|
|
|
|
|
FBtnFolder := FlatButton(LTop, 'Tous les dossiers', OnFolderTap);
|
|
|
|
|
FBtnFolder := FlatButton(LTop, 'All folders', OnFolderTap);
|
|
|
|
|
FBtnFolder.Align := TAlignLayout.Right;
|
|
|
|
|
FBtnFolder.Width := 170;
|
|
|
|
|
FBtnFolder.Margins.Left := 8;
|
|
|
|
@@ -445,7 +445,7 @@ begin
|
|
|
|
|
FSearchHint.Margins.Left := 10;
|
|
|
|
|
FSearchHint.HitTest := False;
|
|
|
|
|
FSearchHint.Opacity := 0.45;
|
|
|
|
|
FSearchHint.Text := 'Rechercher';
|
|
|
|
|
FSearchHint.Text := 'Search';
|
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
/// Intitule discret au-dessus d'une valeur. Meme forme pour toutes les
|
|
|
|
@@ -504,7 +504,7 @@ begin
|
|
|
|
|
FLayDetail.Align := TAlignLayout.Client;
|
|
|
|
|
FLayDetail.Visible := False;
|
|
|
|
|
|
|
|
|
|
LBtnBack := FlatButton(FLayDetail, 'Retour', OnBackTap);
|
|
|
|
|
LBtnBack := FlatButton(FLayDetail, 'Back', OnBackTap);
|
|
|
|
|
LBtnBack.Align := TAlignLayout.Bottom;
|
|
|
|
|
LBtnBack.Height := 52;
|
|
|
|
|
LBtnBack.Margins.Rect := RectF(16, 8, 16, 8);
|
|
|
|
@@ -547,15 +547,15 @@ begin
|
|
|
|
|
if HasVault then
|
|
|
|
|
begin
|
|
|
|
|
if VaultNeedsAuth then
|
|
|
|
|
Status('Coffre present sur cet appareil - protege')
|
|
|
|
|
Status('Vault on this device - protected')
|
|
|
|
|
else
|
|
|
|
|
Status('Coffre present sur cet appareil');
|
|
|
|
|
SetButtonText(FBtnSync, 'Synchroniser');
|
|
|
|
|
Status('Vault on this device');
|
|
|
|
|
SetButtonText(FBtnSync, 'Sync');
|
|
|
|
|
end
|
|
|
|
|
else
|
|
|
|
|
begin
|
|
|
|
|
Status('Aucun coffre local - premier telechargement');
|
|
|
|
|
SetButtonText(FBtnSync, 'Telecharger le coffre');
|
|
|
|
|
Status('No local vault - first download');
|
|
|
|
|
SetButtonText(FBtnSync, 'Download vault');
|
|
|
|
|
end;
|
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
@@ -635,10 +635,10 @@ begin
|
|
|
|
|
|
|
|
|
|
// Le corps d'une note est stocke dans le champ mot de passe : meme donnee,
|
|
|
|
|
// autre intitule, et pas de raison de la masquer comme un secret.
|
|
|
|
|
if FCurrent.IsNote then LPwdCaption := 'Contenu' else LPwdCaption := 'Mot de passe';
|
|
|
|
|
if FCurrent.IsNote then LPwdCaption := 'Content' else LPwdCaption := 'Password';
|
|
|
|
|
|
|
|
|
|
Add('Site', FCurrent.Site, False);
|
|
|
|
|
Add('Identifiant', FCurrent.Username, False);
|
|
|
|
|
Add('Username', FCurrent.Username, False);
|
|
|
|
|
Add(LPwdCaption, FCurrent.Password, not FCurrent.IsNote);
|
|
|
|
|
for I := 0 to High(FCurrent.Fields) do
|
|
|
|
|
Add(FCurrent.Fields[I].Caption, FCurrent.Fields[I].Value,
|
|
|
|
@@ -658,16 +658,16 @@ begin
|
|
|
|
|
// rendu bidirectionnel de FMX en fait n'importe quoi. Separes, chacun se
|
|
|
|
|
// lit dans son sens.
|
|
|
|
|
for I := 0 to High(FCurrent.Attachments) do
|
|
|
|
|
Add('Piece jointe - ' + HumanSize(FCurrent.Attachments[I].SizeBytes),
|
|
|
|
|
Add('Attachment - ' + HumanSize(FCurrent.Attachments[I].SizeBytes),
|
|
|
|
|
FCurrent.Attachments[I].FileName, False);
|
|
|
|
|
|
|
|
|
|
Add('Dossier / etiquettes', LMeta, False);
|
|
|
|
|
Add('Folder / tags', LMeta, False);
|
|
|
|
|
// Le sous-type n'existe que pour les modeles (carte, cle SSH, serveur...) ;
|
|
|
|
|
// Add ignore une valeur vide, donc rien a tester ici.
|
|
|
|
|
Add('Type', FCurrent.Template, False);
|
|
|
|
|
// Horodatage tel quel : c'est de l'ISO 8601 UTC, lisible, et le reformater
|
|
|
|
|
// demanderait de decider d'un fuseau alors qu'il n'y a rien a arbitrer.
|
|
|
|
|
Add('Modifie le', FCurrent.UpdatedAt, False);
|
|
|
|
|
Add('Updated', FCurrent.UpdatedAt, False);
|
|
|
|
|
|
|
|
|
|
SetLength(FRowValues, Length(FRows));
|
|
|
|
|
SetLength(FRowShown, Length(FRows));
|
|
|
|
@@ -678,12 +678,12 @@ begin
|
|
|
|
|
LOrder := 0;
|
|
|
|
|
if FCurrent.Totp <> '' then
|
|
|
|
|
begin
|
|
|
|
|
LRow := MakeRow(FDetBody, 'Code 2FA', LOrder, FTotpValue);
|
|
|
|
|
LRow := MakeRow(FDetBody, '2FA code', LOrder, FTotpValue);
|
|
|
|
|
Inc(LOrder);
|
|
|
|
|
SetLength(FRowCtls, Length(FRowCtls) + 1);
|
|
|
|
|
FRowCtls[High(FRowCtls)] := LRow;
|
|
|
|
|
FTotpValue.TextSettings.Font.Size := 26;
|
|
|
|
|
AddRowButton(LRow, 'Copier', -1, OnCopyTap);
|
|
|
|
|
AddRowButton(LRow, 'Copy', -1, OnCopyTap);
|
|
|
|
|
OnTotpTick(nil); // pas d'attente d'une seconde a l'ouverture
|
|
|
|
|
FTotpTimer.Enabled := True;
|
|
|
|
|
end;
|
|
|
|
@@ -698,11 +698,11 @@ begin
|
|
|
|
|
if FRows[I].Secret then
|
|
|
|
|
begin
|
|
|
|
|
LValue.Text := MASK;
|
|
|
|
|
AddRowButton(LRow, 'Afficher', I, OnRevealTap);
|
|
|
|
|
AddRowButton(LRow, 'Show', I, OnRevealTap);
|
|
|
|
|
end
|
|
|
|
|
else
|
|
|
|
|
LValue.Text := FRows[I].Value;
|
|
|
|
|
AddRowButton(LRow, 'Copier', I, OnCopyTap);
|
|
|
|
|
AddRowButton(LRow, 'Copy', I, OnCopyTap);
|
|
|
|
|
end;
|
|
|
|
|
// La derniere ligne affichee touche sinon le bord du defilement, ce qui la
|
|
|
|
|
// fait passer pour tronquee alors qu'elle est juste collee.
|
|
|
|
@@ -728,7 +728,7 @@ begin
|
|
|
|
|
if FTotpCode = '' then
|
|
|
|
|
begin
|
|
|
|
|
// Un secret illisible ne doit pas passer pour un code : le dire.
|
|
|
|
|
FTotpValue.Text := 'secret illisible';
|
|
|
|
|
FTotpValue.Text := 'unreadable secret';
|
|
|
|
|
FTotpTimer.Enabled := False;
|
|
|
|
|
Exit;
|
|
|
|
|
end;
|
|
|
|
@@ -810,8 +810,8 @@ end;
|
|
|
|
|
procedure TForm8.AdoptVault(const APlainJson: string);
|
|
|
|
|
begin
|
|
|
|
|
FVault.LoadFromJson(APlainJson);
|
|
|
|
|
Log(' ' + FVault.LiveCount.ToString + ' entrees, ' +
|
|
|
|
|
FVault.TrashCount.ToString + ' en corbeille');
|
|
|
|
|
Log(' ' + FVault.LiveCount.ToString + ' entries, ' +
|
|
|
|
|
FVault.TrashCount.ToString + ' in trash');
|
|
|
|
|
RebuildIcons;
|
|
|
|
|
PopulateFolders;
|
|
|
|
|
Touch;
|
|
|
|
@@ -845,7 +845,7 @@ begin
|
|
|
|
|
on E: Exception do
|
|
|
|
|
begin
|
|
|
|
|
// Un coffre local illisible se remplace, il ne se repare pas.
|
|
|
|
|
Log('Coffre local corrompu : ' + E.Message);
|
|
|
|
|
Log('Local vault corrupt: ' + E.Message);
|
|
|
|
|
ClearVault;
|
|
|
|
|
ShowUnlock;
|
|
|
|
|
end;
|
|
|
|
@@ -856,8 +856,8 @@ begin
|
|
|
|
|
// ShowUnlock AVANT le message : il repositionne le statut selon ce que
|
|
|
|
|
// l'appareil detient, et ecraserait donc l'explication.
|
|
|
|
|
ShowUnlock;
|
|
|
|
|
Log('Coffre local illisible : ' + LastStoreError);
|
|
|
|
|
Status('Coffre local illisible - voir le journal');
|
|
|
|
|
Log('Local vault unreadable: ' + LastStoreError);
|
|
|
|
|
Status('Local vault unreadable - see log');
|
|
|
|
|
end;
|
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
@@ -877,13 +877,13 @@ begin
|
|
|
|
|
Exit;
|
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
if not AAuto then Status('Authentification...');
|
|
|
|
|
AuthenticateThen('Acceder au coffre',
|
|
|
|
|
if not AAuto then Status('Authenticating...');
|
|
|
|
|
AuthenticateThen('Unlock the vault',
|
|
|
|
|
procedure(AOutcome: TBioOutcome)
|
|
|
|
|
begin
|
|
|
|
|
case AOutcome of
|
|
|
|
|
boOK: OpenLocalNow;
|
|
|
|
|
boCancelled: Status('Annule');
|
|
|
|
|
boCancelled: Status('Cancelled');
|
|
|
|
|
boUnavailable:
|
|
|
|
|
// Reponse nette du systeme : plus rien pour authentifier sur cet
|
|
|
|
|
// appareil, donc la cle est perdue et le cache avec elle.
|
|
|
|
@@ -895,13 +895,13 @@ begin
|
|
|
|
|
// masquerait la vraie cause. L'utilisateur tranche en reessayant.
|
|
|
|
|
if AAuto then
|
|
|
|
|
begin
|
|
|
|
|
Log('Authentification indisponible au lancement - cache conserve');
|
|
|
|
|
Log('Authentication unavailable at launch - cache kept');
|
|
|
|
|
Log(' ' + LastBiometricError);
|
|
|
|
|
Status('Authentification indisponible - reessayer');
|
|
|
|
|
Status('Authentication unavailable - try again');
|
|
|
|
|
end
|
|
|
|
|
else
|
|
|
|
|
begin
|
|
|
|
|
Log('Plus aucune protection sur l''appareil - cache efface');
|
|
|
|
|
Log('No protection left on this device - cache cleared');
|
|
|
|
|
Log(' ' + LastBiometricError);
|
|
|
|
|
ClearVault;
|
|
|
|
|
ShowUnlock;
|
|
|
|
@@ -909,8 +909,8 @@ begin
|
|
|
|
|
else
|
|
|
|
|
// boFailed : la couche Java a leve quelque chose. Cela ne dit rien de
|
|
|
|
|
// l'appareil, donc on ne touche a rien - on rapporte.
|
|
|
|
|
Log('Echec de l''authentification : ' + LastBiometricError);
|
|
|
|
|
Status('Echec de l''authentification');
|
|
|
|
|
Log('Authentication failed: ' + LastBiometricError);
|
|
|
|
|
Status('Authentication failed');
|
|
|
|
|
end;
|
|
|
|
|
end);
|
|
|
|
|
end;
|
|
|
|
@@ -930,7 +930,7 @@ begin
|
|
|
|
|
if LPwd = '' then LPwd := FSyncPwd;
|
|
|
|
|
if LPwd = '' then
|
|
|
|
|
begin
|
|
|
|
|
Status('Mot de passe de sync requis');
|
|
|
|
|
Status('Sync password required');
|
|
|
|
|
Exit;
|
|
|
|
|
end;
|
|
|
|
|
FLog.Lines.Clear;
|
|
|
|
@@ -942,16 +942,16 @@ begin
|
|
|
|
|
// 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',
|
|
|
|
|
Status('Authenticating...');
|
|
|
|
|
AuthenticateThen('Unlock the vault',
|
|
|
|
|
procedure(AOutcome: TBioOutcome)
|
|
|
|
|
begin
|
|
|
|
|
if AOutcome = boOK then
|
|
|
|
|
FetchAndDecrypt(LUrl, LTok, LPwd)
|
|
|
|
|
else
|
|
|
|
|
begin
|
|
|
|
|
Log('Synchronisation refusee : ' + LastBiometricError);
|
|
|
|
|
Status('Authentification requise');
|
|
|
|
|
Log('Sync refused: ' + LastBiometricError);
|
|
|
|
|
Status('Authentication required');
|
|
|
|
|
end;
|
|
|
|
|
end);
|
|
|
|
|
Exit;
|
|
|
|
@@ -966,7 +966,7 @@ var
|
|
|
|
|
LCanAuth: Boolean;
|
|
|
|
|
begin
|
|
|
|
|
SetBusy(True);
|
|
|
|
|
if not ASilent then Status('Telechargement...');
|
|
|
|
|
if not ASilent then Status('Downloading...');
|
|
|
|
|
// NE JAMAIS FERMER LE CACHE DERRIERE UNE PORTE QU'ON NE SAIT PAS OUVRIR.
|
|
|
|
|
// Demander une cle protegee par authentification alors que l'invite ne peut
|
|
|
|
|
// pas s'afficher (permission absente, aucune protection configuree) produit
|
|
|
|
@@ -997,7 +997,7 @@ begin
|
|
|
|
|
LSw := TStopwatch.StartNew;
|
|
|
|
|
LRes := LClient.Fetch(FETag);
|
|
|
|
|
LSw.Stop;
|
|
|
|
|
Log(' HTTP ' + LRes.HttpCode.ToString + ' en ' +
|
|
|
|
|
Log(' HTTP ' + LRes.HttpCode.ToString + ' in ' +
|
|
|
|
|
LSw.ElapsedMilliseconds.ToString + ' ms');
|
|
|
|
|
|
|
|
|
|
case LRes.Status of
|
|
|
|
@@ -1018,14 +1018,14 @@ begin
|
|
|
|
|
// rafraichissement de fond c'est le cas courant, et il
|
|
|
|
|
// doit passer inapercu - surtout pas de retour a la liste
|
|
|
|
|
// alors que l'utilisateur consulte une entree.
|
|
|
|
|
Log(' 304 : inchange, coffre deja ouvert')
|
|
|
|
|
Log(' 304: unchanged, vault already open')
|
|
|
|
|
else if LCached <> '' then
|
|
|
|
|
begin
|
|
|
|
|
Log(' 304 : inchange, coffre servi depuis le cache');
|
|
|
|
|
Log(' 304: unchanged, vault served from cache');
|
|
|
|
|
try
|
|
|
|
|
AdoptVault(LCached);
|
|
|
|
|
except
|
|
|
|
|
on E: Exception do Status('Cache illisible : ' + E.Message);
|
|
|
|
|
on E: Exception do Status('Cache unreadable: ' + E.Message);
|
|
|
|
|
end;
|
|
|
|
|
end
|
|
|
|
|
else
|
|
|
|
@@ -1034,7 +1034,7 @@ begin
|
|
|
|
|
// On le jette pour que l'appel suivant retelecharge.
|
|
|
|
|
FETag := '';
|
|
|
|
|
if not ASilent then
|
|
|
|
|
Status('Cache absent - appuyer a nouveau pour telecharger');
|
|
|
|
|
Status('No cache - tap again to download');
|
|
|
|
|
end;
|
|
|
|
|
end);
|
|
|
|
|
Exit;
|
|
|
|
@@ -1042,10 +1042,10 @@ begin
|
|
|
|
|
ssNoSnapshot:
|
|
|
|
|
begin
|
|
|
|
|
// Le serveur repond pareil dans les deux cas, par conception.
|
|
|
|
|
Log(' 404 : pas d''instantane OU jeton invalide');
|
|
|
|
|
Log(' 404: no snapshot OR invalid token');
|
|
|
|
|
if not ASilent then
|
|
|
|
|
TThread.Queue(nil, procedure
|
|
|
|
|
begin Status('Rien a telecharger (404)'); end);
|
|
|
|
|
begin Status('Nothing to download (404)'); end);
|
|
|
|
|
Exit;
|
|
|
|
|
end;
|
|
|
|
|
ssRefused, ssHttpError, ssNetworkError:
|
|
|
|
@@ -1053,17 +1053,17 @@ begin
|
|
|
|
|
// En fond, un echec reseau ne se signale pas : le coffre local
|
|
|
|
|
// est affiche, hors ligne est un etat normal, et une alerte ici
|
|
|
|
|
// apprendrait a l'utilisateur a ignorer les alertes.
|
|
|
|
|
Log(' echec : ' + LRes.Error);
|
|
|
|
|
Log(' failed: ' + LRes.Error);
|
|
|
|
|
if not ASilent then
|
|
|
|
|
TThread.Queue(nil, procedure
|
|
|
|
|
begin Status('Echec reseau'); end);
|
|
|
|
|
begin Status('Network failure'); end);
|
|
|
|
|
Exit;
|
|
|
|
|
end;
|
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
Log(' recu ' + Length(LRes.Container).ToString + ' octets');
|
|
|
|
|
Log(' received ' + Length(LRes.Container).ToString + ' bytes');
|
|
|
|
|
if not ASilent then
|
|
|
|
|
TThread.Queue(nil, procedure begin Status('Dechiffrement...'); end);
|
|
|
|
|
TThread.Queue(nil, procedure begin Status('Decrypting...'); end);
|
|
|
|
|
|
|
|
|
|
LSw := TStopwatch.StartNew;
|
|
|
|
|
// Volontairement AVANT de retenir l'ETag : un echec ici doit laisser
|
|
|
|
@@ -1071,7 +1071,7 @@ begin
|
|
|
|
|
LPlain := DecryptContainer(LRes.Container, APwd);
|
|
|
|
|
LSw.Stop;
|
|
|
|
|
FETag := LRes.ETag;
|
|
|
|
|
Log(' dechiffre en ' + LSw.ElapsedMilliseconds.ToString + ' ms');
|
|
|
|
|
Log(' decrypted in ' + LSw.ElapsedMilliseconds.ToString + ' ms');
|
|
|
|
|
|
|
|
|
|
// Ecrit APRES un dechiffrement reussi seulement, et avec son ETag :
|
|
|
|
|
// les deux doivent rester coherents.
|
|
|
|
@@ -1083,16 +1083,16 @@ begin
|
|
|
|
|
// pas des reglages saisis, on enregistre des reglages EPROUVES.
|
|
|
|
|
SaveDeviceSettings(AUrl, ATok);
|
|
|
|
|
if VaultNeedsAuth then
|
|
|
|
|
Log(' cache ecrit - protege par biometrie/code')
|
|
|
|
|
Log(' cache written - protected by biometrics/PIN')
|
|
|
|
|
else if LCanAuth then
|
|
|
|
|
Log(' cache ecrit - cle simple (Keystore a refuse la contrainte)')
|
|
|
|
|
Log(' cache written - plain key (Keystore refused the constraint)')
|
|
|
|
|
else
|
|
|
|
|
Log(' cache ecrit - AUCUNE protection : pas d''authentification ici');
|
|
|
|
|
Log(' cache written - NO protection: no authentication here');
|
|
|
|
|
except
|
|
|
|
|
// La classe compte autant que le message : "methode introuvable"
|
|
|
|
|
// designe une signature JNI fausse, pas un probleme de stockage.
|
|
|
|
|
on E: Exception do
|
|
|
|
|
Log(' cache non ecrit : ' + E.ClassName + ' - ' + E.Message);
|
|
|
|
|
Log(' cache not written: ' + E.ClassName + ' - ' + E.Message);
|
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
TThread.Queue(nil,
|
|
|
|
@@ -1104,13 +1104,13 @@ begin
|
|
|
|
|
except
|
|
|
|
|
on E: Exception do
|
|
|
|
|
if not ASilent then
|
|
|
|
|
Status('Instantane illisible : ' + E.Message);
|
|
|
|
|
Status('Snapshot unreadable: ' + E.Message);
|
|
|
|
|
end;
|
|
|
|
|
end);
|
|
|
|
|
except
|
|
|
|
|
on E: Exception do
|
|
|
|
|
begin
|
|
|
|
|
Log('ERREUR ' + E.ClassName + ' : ' + E.Message);
|
|
|
|
|
Log('ERROR ' + E.ClassName + ' : ' + E.Message);
|
|
|
|
|
// Le cas de loin le plus frequent, et le message par defaut ne le
|
|
|
|
|
// dit pas : GCM echoue a la verification quand la cle est fausse.
|
|
|
|
|
//
|
|
|
|
@@ -1120,7 +1120,7 @@ begin
|
|
|
|
|
// le champ prerempli, et le coffre local reste consultable.
|
|
|
|
|
if not ASilent then
|
|
|
|
|
TThread.Queue(nil, procedure
|
|
|
|
|
begin Status('Echec - mot de passe de sync incorrect ?'); end);
|
|
|
|
|
begin Status('Failed - wrong sync password?'); end);
|
|
|
|
|
end;
|
|
|
|
|
end;
|
|
|
|
|
finally
|
|
|
|
@@ -1188,7 +1188,7 @@ begin
|
|
|
|
|
LPrev := FFolderNames[FFolderSel];
|
|
|
|
|
|
|
|
|
|
SetLength(FFolderNames, 1);
|
|
|
|
|
FFolderNames[0] := 'Tous les dossiers';
|
|
|
|
|
FFolderNames[0] := 'All folders';
|
|
|
|
|
for LF in FVault.Folders do
|
|
|
|
|
begin
|
|
|
|
|
SetLength(FFolderNames, Length(FFolderNames) + 1);
|
|
|
|
@@ -1341,7 +1341,7 @@ begin
|
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
if (FSearch.Text.Trim = '') and (LFolder = '') then
|
|
|
|
|
FCount.Text := FVault.LiveCount.ToString + ' entrees'
|
|
|
|
|
FCount.Text := FVault.LiveCount.ToString + ' entries'
|
|
|
|
|
else
|
|
|
|
|
FCount.Text := Length(FFiltered).ToString + ' / ' +
|
|
|
|
|
FVault.LiveCount.ToString;
|
|
|
|
@@ -1369,12 +1369,12 @@ begin
|
|
|
|
|
if FRowShown[I] then
|
|
|
|
|
begin
|
|
|
|
|
FRowValues[I].Text := FRows[I].Value;
|
|
|
|
|
SetButtonText(TRectangle(Sender), 'Masquer');
|
|
|
|
|
SetButtonText(TRectangle(Sender), 'Hide');
|
|
|
|
|
end
|
|
|
|
|
else
|
|
|
|
|
begin
|
|
|
|
|
FRowValues[I].Text := MASK;
|
|
|
|
|
SetButtonText(TRectangle(Sender), 'Afficher');
|
|
|
|
|
SetButtonText(TRectangle(Sender), 'Show');
|
|
|
|
|
end;
|
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
@@ -1388,7 +1388,7 @@ begin
|
|
|
|
|
// -1 : la ligne du TOTP, qui n'est pas dans FRows - sa valeur change chaque
|
|
|
|
|
// periode et ne vit que dans FTotpCode. Copie sans l'espace d'affichage.
|
|
|
|
|
if I = -1 then
|
|
|
|
|
CopyToClipboard(FTotpCode, 'Code 2FA')
|
|
|
|
|
CopyToClipboard(FTotpCode, '2FA code')
|
|
|
|
|
else if (I >= 0) and (I <= High(FRows)) then
|
|
|
|
|
CopyToClipboard(FRows[I].Value, FRows[I].Caption);
|
|
|
|
|
end;
|
|
|
|
@@ -1408,7 +1408,7 @@ begin
|
|
|
|
|
// ponytail: le message reste jusqu'a la prochaine navigation, pas de minuterie
|
|
|
|
|
// pour l'effacer. Un deuxieme TTimer pour deux secondes d'affichage serait
|
|
|
|
|
// plus de code que ce que ca apporte.
|
|
|
|
|
FDetToast.Text := ALabel + ' copie - presse-papiers efface dans ' +
|
|
|
|
|
FDetToast.Text := ALabel + ' copied - clipboard cleared in ' +
|
|
|
|
|
CLIPBOARD_CLEAR_SECONDS.ToString + ' s';
|
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
@@ -1477,7 +1477,7 @@ begin
|
|
|
|
|
end;
|
|
|
|
|
if MinutesBetween(Now, FLastActivity) >= AUTOLOCK_MINUTES then
|
|
|
|
|
begin
|
|
|
|
|
Log('Verrouille apres ' + AUTOLOCK_MINUTES.ToString + ' min d''inactivite');
|
|
|
|
|
Log('Locked after ' + AUTOLOCK_MINUTES.ToString + ' min idle');
|
|
|
|
|
LockVault;
|
|
|
|
|
end;
|
|
|
|
|
end;
|
|
|
|
|