[PM-3393] Excessive Invalid Biometric unlock attempts should automatically log out TDE users (#2747)

* [PM-3393] Log user out on biometric exceed attempts

* [PM-3393] Move duplicated code to AppHelpers

* [PM-3393] Update copy on new pop up

* [PM-3393] Moved VaultTimeoutService to LazyResolve.

* [PM-3382] Change IVaultTimeoutService for messaging

* [PM-3393] Use default values.
This commit is contained in:
André Bispo 2023-09-19 10:32:23 +01:00 committed by GitHub
parent b932824b5a
commit a6f05338c2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 41 additions and 6 deletions

View file

@ -465,7 +465,8 @@ namespace Bit.App.Pages
}
var success = await _platformUtilsService.AuthenticateBiometricAsync(null,
PinEnabled ? AppResources.PIN : AppResources.MasterPassword,
() => _secretEntryFocusWeakEventManager.RaiseEvent((int?)null, nameof(FocusSecretEntry)));
() => _secretEntryFocusWeakEventManager.RaiseEvent((int?)null, nameof(FocusSecretEntry)),
!PinEnabled && !HasMasterPassword);
await _stateService.SetBiometricLockedAsync(!success);
if (success)
{

View file

@ -256,6 +256,15 @@ namespace Bit.App.Resources {
}
}
/// <summary>
/// Looks up a localized string similar to Account logged out..
/// </summary>
public static string AccountLoggedOutBiometricExceeded {
get {
return ResourceManager.GetString("AccountLoggedOutBiometricExceeded", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Account logged out successfully.
/// </summary>
@ -6498,6 +6507,15 @@ namespace Bit.App.Resources {
}
}
/// <summary>
/// Looks up a localized string similar to Too many attempts.
/// </summary>
public static string TooManyAttempts {
get {
return ResourceManager.GetString("TooManyAttempts", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to TOTP.
/// </summary>
@ -6751,7 +6769,7 @@ namespace Bit.App.Resources {
}
/// <summary>
/// Looks up a localized string similar to Unlocking may fail due to insufficient memory. Decrease your KDF memory settings to resolve..
/// Looks up a localized string similar to Unlocking may fail due to insufficient memory. Decrease your KDF memory settings or set up biometric unlock to resolve..
/// </summary>
public static string UnlockingMayFailDueToInsufficientMemoryDecreaseYourKDFMemorySettingsToResolve {
get {

View file

@ -2762,4 +2762,10 @@ Do you want to switch to this account?</value>
<data name="LoggingInOn" xml:space="preserve">
<value>Logging in on</value>
</data>
<data name="TooManyAttempts" xml:space="preserve">
<value>Too many attempts</value>
</data>
<data name="AccountLoggedOutBiometricExceeded" xml:space="preserve">
<value>Account logged out.</value>
</data>
</root>

View file

@ -32,7 +32,8 @@ namespace Bit.App.Services
IDeviceActionService deviceActionService,
IClipboardService clipboardService,
IMessagingService messagingService,
IBroadcasterService broadcasterService)
IBroadcasterService broadcasterService
)
{
_deviceActionService = deviceActionService;
_clipboardService = clipboardService;
@ -242,7 +243,7 @@ namespace Bit.App.Services
}
public async Task<bool> AuthenticateBiometricAsync(string text = null, string fallbackText = null,
Action fallback = null)
Action fallback = null, bool logOutOnTooManyAttempts = false)
{
try
{
@ -269,6 +270,12 @@ namespace Bit.App.Services
{
fallback?.Invoke();
}
if (result.Status == FingerprintAuthenticationResultStatus.TooManyAttempts
&& logOutOnTooManyAttempts)
{
await ShowDialogAsync(AppResources.AccountLoggedOutBiometricExceeded, AppResources.TooManyAttempts, AppResources.Ok);
_messagingService.Send(AccountsManagerMessageCommands.LOGOUT);
}
}
catch { }
return false;

View file

@ -15,6 +15,7 @@ using Bit.Core.Enums;
using Bit.Core.Exceptions;
using Bit.Core.Models.Data;
using Bit.Core.Models.View;
using Bit.Core.Services;
using Bit.Core.Utilities;
using Newtonsoft.Json;
using Xamarin.Essentials;

View file

@ -29,7 +29,7 @@ namespace Bit.Core.Abstractions
bool SupportsDuo();
Task<bool> SupportsBiometricAsync();
Task<bool> IsBiometricIntegrityValidAsync(string bioIntegritySrcKey = null);
Task<bool> AuthenticateBiometricAsync(string text = null, string fallbackText = null, Action fallback = null);
Task<bool> AuthenticateBiometricAsync(string text = null, string fallbackText = null, Action fallback = null, bool logOutOnTooManyAttempts = false);
long GetActiveTime();
}
}

View file

@ -378,7 +378,9 @@ namespace Bit.iOS.Core.Controllers
}
var success = await _platformUtilsService.AuthenticateBiometricAsync(null,
_pinEnabled ? AppResources.PIN : AppResources.MasterPassword,
() => MasterPasswordCell.TextField.BecomeFirstResponder());
() => MasterPasswordCell.TextField.BecomeFirstResponder(),
!_pinEnabled && !_hasMasterPassword);
await _stateService.SetBiometricLockedAsync(!success);
if (success)
{