fix(android): ask for the device credential alone when no biometric is enrolled
The re-seal never ran and left no trace, because a branch not taken logs nothing. It logs now, verdict and reason, whether or not anything happens - the absence of a line was itself the thing that cost time. And the verdict may have been wrong: asking canAuthenticate for BIOMETRIC_STRONG together with DEVICE_CREDENTIAL can fail outright on a device with a pattern and no enrolled fingerprint, instead of keeping what exists. It now falls back to the credential alone, which is all the key needs, and AuthenticateThen presents whichever set answered - offering something else would draw the same refusal. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -72,6 +72,18 @@ const
|
|||||||
// sans empreinte enrolee, doit rester utilisable. C'est le cas courant.
|
// sans empreinte enrolee, doit rester utilisable. C'est le cas courant.
|
||||||
WANTED_STRENGTHS = [TBiometricStrength.Strong,
|
WANTED_STRENGTHS = [TBiometricStrength.Strong,
|
||||||
TBiometricStrength.DeviceCredential];
|
TBiometricStrength.DeviceCredential];
|
||||||
|
// Repli quand la combinaison ci-dessus est refusee. Observe sur un appareil
|
||||||
|
// avec schema et AUCUNE empreinte : selon les versions, demander
|
||||||
|
// BIOMETRIC_STRONG en meme temps que DEVICE_CREDENTIAL fait echouer
|
||||||
|
// l'ensemble au lieu de retenir ce qui existe. On redemande alors juste ce
|
||||||
|
// dont on a besoin.
|
||||||
|
CREDENTIAL_ONLY = [TBiometricStrength.DeviceCredential];
|
||||||
|
|
||||||
|
var
|
||||||
|
// Le jeu retenu par la derniere interrogation reussie. AuthenticateThen doit
|
||||||
|
// presenter EXACTEMENT celui-la : demander autre chose que ce qui a repondu
|
||||||
|
// « disponible » ramenerait le meme refus.
|
||||||
|
FStrengths: TBiometricStrengths = WANTED_STRENGTHS;
|
||||||
|
|
||||||
/// Recupere le service ET pose les forces d'authentification.
|
/// Recupere le service ET pose les forces d'authentification.
|
||||||
///
|
///
|
||||||
@@ -86,7 +98,7 @@ begin
|
|||||||
Result := TPlatformServices.Current.SupportsPlatformService(
|
Result := TPlatformServices.Current.SupportsPlatformService(
|
||||||
IFMXBiometricAuthService, ASvc);
|
IFMXBiometricAuthService, ASvc);
|
||||||
if Result then
|
if Result then
|
||||||
ASvc.SetBiometricStrengths(WANTED_STRENGTHS);
|
ASvc.SetBiometricStrengths(FStrengths);
|
||||||
end;
|
end;
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
|
|
||||||
@@ -102,6 +114,7 @@ begin
|
|||||||
// ouverture du coffre.
|
// ouverture du coffre.
|
||||||
FLastError := '';
|
FLastError := '';
|
||||||
try
|
try
|
||||||
|
FStrengths := WANTED_STRENGTHS;
|
||||||
if not AcquireService(LSvc) then
|
if not AcquireService(LSvc) then
|
||||||
begin
|
begin
|
||||||
FLastError := 'biometric service missing from the platform';
|
FLastError := 'biometric service missing from the platform';
|
||||||
@@ -109,7 +122,20 @@ begin
|
|||||||
end;
|
end;
|
||||||
Result := LSvc.CanAuthenticate;
|
Result := LSvc.CanAuthenticate;
|
||||||
if not Result then
|
if not Result then
|
||||||
FLastError := 'CanAuthenticate: no usable protection';
|
begin
|
||||||
|
// Second essai sans la biometrie forte : le schema seul suffit a
|
||||||
|
// deverrouiller la cle, et c'est tout ce qu'on demande.
|
||||||
|
FStrengths := CREDENTIAL_ONLY;
|
||||||
|
LSvc.SetBiometricStrengths(FStrengths);
|
||||||
|
Result := LSvc.CanAuthenticate;
|
||||||
|
if Result then
|
||||||
|
FLastError := 'device credential only (no biometric enrolled)'
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
FStrengths := WANTED_STRENGTHS;
|
||||||
|
FLastError := 'CanAuthenticate: no usable protection';
|
||||||
|
end;
|
||||||
|
end;
|
||||||
except
|
except
|
||||||
on E: Exception do
|
on E: Exception do
|
||||||
begin
|
begin
|
||||||
|
|||||||
@@ -839,6 +839,13 @@ begin
|
|||||||
// pendant que l'appareil n'avait pas de verrouillage restait en clair
|
// pendant que l'appareil n'avait pas de verrouillage restait en clair
|
||||||
// indefiniment, meme apres en avoir remis un. On le rescelle ici, ou l'on
|
// indefiniment, meme apres en avoir remis un. On le rescelle ici, ou l'on
|
||||||
// tient justement le clair.
|
// tient justement le clair.
|
||||||
|
// Journalise le verdict MEME quand rien n'est fait : sans cette ligne, un
|
||||||
|
// rescellement qui n'a pas lieu ne laisse aucune trace, et on ne sait pas
|
||||||
|
// s'il a echoue ou s'il n'a jamais ete tente.
|
||||||
|
if not VaultNeedsAuth then
|
||||||
|
Log('Plain cache; device authentication available: ' +
|
||||||
|
BoolToStr(BiometricAvailable, True) + ' ' + LastBiometricError);
|
||||||
|
|
||||||
if (not VaultNeedsAuth) and BiometricAvailable then
|
if (not VaultNeedsAuth) and BiometricAvailable then
|
||||||
begin
|
begin
|
||||||
try
|
try
|
||||||
|
|||||||
Reference in New Issue
Block a user