mirror of
https://github.com/bitwarden/mobile
synced 2025-12-15 07:43:37 +00:00
PM-6706 Add maximum attempts to UV with MP and with PIN (#3079)
This commit is contained in:
committed by
GitHub
parent
970d3c2621
commit
39da2a82c6
@@ -9,6 +9,6 @@ namespace Bit.Core.Abstractions
|
|||||||
Task<bool> ShouldPerformMasterPasswordRepromptAsync(Fido2UserVerificationOptions options);
|
Task<bool> ShouldPerformMasterPasswordRepromptAsync(Fido2UserVerificationOptions options);
|
||||||
Task<(bool CanPerfom, bool IsUnlocked)> PerformOSUnlockAsync();
|
Task<(bool CanPerfom, bool IsUnlocked)> PerformOSUnlockAsync();
|
||||||
Task<(bool canPerformUnlockWithPin, bool pinVerified)> VerifyPinCodeAsync();
|
Task<(bool canPerformUnlockWithPin, bool pinVerified)> VerifyPinCodeAsync();
|
||||||
Task<(bool canPerformUnlockWithMasterPassword, bool mpVerified)> VerifyMasterPasswordAsync();
|
Task<(bool canPerformUnlockWithMasterPassword, bool mpVerified)> VerifyMasterPasswordAsync(bool isMasterPasswordReprompt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ namespace Bit.Core.Services.UserVerification
|
|||||||
return pinVerified;
|
return pinVerified;
|
||||||
}
|
}
|
||||||
|
|
||||||
var (canPerformUnlockWithMasterPassword, mpVerified) = await _userVerificationMediatorService.VerifyMasterPasswordAsync();
|
var (canPerformUnlockWithMasterPassword, mpVerified) = await _userVerificationMediatorService.VerifyMasterPasswordAsync(false);
|
||||||
if (canPerformUnlockWithMasterPassword)
|
if (canPerformUnlockWithMasterPassword)
|
||||||
{
|
{
|
||||||
return mpVerified;
|
return mpVerified;
|
||||||
|
|||||||
@@ -10,6 +10,8 @@ namespace Bit.Core.Services.UserVerification
|
|||||||
{
|
{
|
||||||
public class UserVerificationMediatorService : IUserVerificationMediatorService
|
public class UserVerificationMediatorService : IUserVerificationMediatorService
|
||||||
{
|
{
|
||||||
|
private const byte MAX_ATTEMPTS = 5;
|
||||||
|
|
||||||
private readonly IPlatformUtilsService _platformUtilsService;
|
private readonly IPlatformUtilsService _platformUtilsService;
|
||||||
private readonly IPasswordRepromptService _passwordRepromptService;
|
private readonly IPasswordRepromptService _passwordRepromptService;
|
||||||
private readonly IUserPinService _userPinService;
|
private readonly IUserPinService _userPinService;
|
||||||
@@ -44,7 +46,8 @@ namespace Bit.Core.Services.UserVerification
|
|||||||
await options.OnNeedUITask();
|
await options.OnNeedUITask();
|
||||||
}
|
}
|
||||||
|
|
||||||
return await _passwordRepromptService.PromptAndCheckPasswordIfNeededAsync(Enums.CipherRepromptType.Password);
|
var (canPerformMP, mpVerified) = await VerifyMasterPasswordAsync(true);
|
||||||
|
return canPerformMP && mpVerified;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_fido2UserVerificationStrategies.TryGetValue(options.UserVerificationPreference, out var userVerificationServiceStrategy))
|
if (!_fido2UserVerificationStrategies.TryGetValue(options.UserVerificationPreference, out var userVerificationServiceStrategy))
|
||||||
@@ -94,6 +97,8 @@ namespace Bit.Core.Services.UserVerification
|
|||||||
}
|
}
|
||||||
|
|
||||||
public async Task<(bool canPerformUnlockWithPin, bool pinVerified)> VerifyPinCodeAsync()
|
public async Task<(bool canPerformUnlockWithPin, bool pinVerified)> VerifyPinCodeAsync()
|
||||||
|
{
|
||||||
|
return await VerifyWithAttemptsAsync(async () =>
|
||||||
{
|
{
|
||||||
if (!await _userPinService.IsPinLockEnabledAsync())
|
if (!await _userPinService.IsPinLockEnabledAsync())
|
||||||
{
|
{
|
||||||
@@ -121,17 +126,43 @@ namespace Bit.Core.Services.UserVerification
|
|||||||
{
|
{
|
||||||
return (true, false);
|
return (true, false);
|
||||||
}
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<(bool canPerformUnlockWithMasterPassword, bool mpVerified)> VerifyMasterPasswordAsync()
|
public async Task<(bool canPerformUnlockWithMasterPassword, bool mpVerified)> VerifyMasterPasswordAsync(bool isMasterPasswordReprompt)
|
||||||
|
{
|
||||||
|
return await VerifyWithAttemptsAsync(async () =>
|
||||||
{
|
{
|
||||||
if (!await _userVerificationService.HasMasterPasswordAsync(true))
|
if (!await _userVerificationService.HasMasterPasswordAsync(true))
|
||||||
{
|
{
|
||||||
return (false, false);
|
return (false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
var (_, isValid) = await _platformUtilsService.ShowPasswordDialogAndGetItAsync(AppResources.MasterPassword, string.Empty, _userVerificationService.VerifyMasterPasswordAsync);
|
var title = isMasterPasswordReprompt ? AppResources.PasswordConfirmation : AppResources.MasterPassword;
|
||||||
|
var body = isMasterPasswordReprompt ? AppResources.PasswordConfirmationDesc : string.Empty;
|
||||||
|
|
||||||
|
var (_, isValid) = await _platformUtilsService.ShowPasswordDialogAndGetItAsync(title, body, _userVerificationService.VerifyMasterPasswordAsync);
|
||||||
return (true, isValid);
|
return (true, isValid);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task<(bool canPerform, bool isVerified)> VerifyWithAttemptsAsync(Func<Task<(bool canPerform, bool isVerified)>> verifyAsync)
|
||||||
|
{
|
||||||
|
byte attempts = 0;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
var (canPerform, verified) = await verifyAsync();
|
||||||
|
if (!canPerform)
|
||||||
|
{
|
||||||
|
return (false, false);
|
||||||
|
}
|
||||||
|
if (verified)
|
||||||
|
{
|
||||||
|
return (true, true);
|
||||||
|
}
|
||||||
|
} while (attempts++ < MAX_ATTEMPTS);
|
||||||
|
|
||||||
|
return (true, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user