From 77280a42f102feab85d75330db24f9445ecbe28d Mon Sep 17 00:00:00 2001 From: Shane Melton Date: Fri, 10 Mar 2023 14:11:22 -0800 Subject: [PATCH] [AC-1070] Change master password options to method variable to avoid class field Add null check for password strength result and log an error as this is an unexpected flow --- src/App/Pages/Accounts/LockPageViewModel.cs | 29 +++++++++++++-------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/src/App/Pages/Accounts/LockPageViewModel.cs b/src/App/Pages/Accounts/LockPageViewModel.cs index b9f5af0e1..ad38b5965 100644 --- a/src/App/Pages/Accounts/LockPageViewModel.cs +++ b/src/App/Pages/Accounts/LockPageViewModel.cs @@ -49,8 +49,6 @@ namespace Bit.App.Pages private bool _isPinProtected; private bool _isPinProtectedWithKey; - private MasterPasswordPolicyOptions _enforcedMasterPasswordOptions; - public LockPageViewModel() { _apiService = ServiceContainer.Resolve("apiService"); @@ -300,6 +298,7 @@ namespace Bit.App.Pages var key = await _cryptoService.MakeKeyAsync(MasterPassword, _email, kdfConfig); var storedKeyHash = await _cryptoService.GetKeyHashAsync(); var passwordValid = false; + MasterPasswordPolicyOptions enforcedMasterPasswordOptions = null; if (storedKeyHash != null) { @@ -311,10 +310,11 @@ namespace Bit.App.Pages var keyHash = await _cryptoService.HashPasswordAsync(MasterPassword, key, HashPurpose.ServerAuthorization); var request = new PasswordVerificationRequest(); request.MasterPasswordHash = keyHash; + try { var response = await _apiService.PostAccountVerifyPasswordAsync(request); - _enforcedMasterPasswordOptions = response.MasterPasswordPolicy; + enforcedMasterPasswordOptions = response.MasterPasswordPolicy; passwordValid = true; var localKeyHash = await _cryptoService.HashPasswordAsync(MasterPassword, key, HashPurpose.LocalAuthorization); await _cryptoService.SetKeyHashAsync(localKeyHash); @@ -336,7 +336,7 @@ namespace Bit.App.Pages await _stateService.SetPinProtectedKeyAsync(await _cryptoService.EncryptAsync(key.Key, pinKey)); } - if (await RequirePasswordChangeAsync()) + if (await RequirePasswordChangeAsync(enforcedMasterPasswordOptions)) { // Save the ForcePasswordResetReason to force a password reset after unlock await _stateService.SetForcePasswordResetReasonAsync( @@ -370,24 +370,31 @@ namespace Bit.App.Pages /// /// Checks if the master password requires updating to meet the enforced policy requirements /// - private async Task RequirePasswordChangeAsync() + /// + private async Task RequirePasswordChangeAsync(MasterPasswordPolicyOptions options = null) { - // If we do not have any saved policies, attempt to load them from the service - _enforcedMasterPasswordOptions ??= await _policyService.GetMasterPasswordPolicyOptions(); + // If no policy options are provided, attempt to load them from the policy service + var enforcedOptions = options ?? await _policyService.GetMasterPasswordPolicyOptions(); // No policy to enforce on login/unlock - if (!(_enforcedMasterPasswordOptions is { EnforceOnLogin: true })) + if (!(enforcedOptions is { EnforceOnLogin: true })) { return false; } var strength = _passwordGenerationService.PasswordStrength( - MasterPassword, _passwordGenerationService.GetPasswordStrengthUserInput(_email)).Score; + MasterPassword, _passwordGenerationService.GetPasswordStrengthUserInput(_email))?.Score; + + if (!strength.HasValue) + { + _logger.Error("Unable to evaluate master password strength during unlock"); + return false; + } return !await _policyService.EvaluateMasterPassword( - strength, + strength.Value, MasterPassword, - _enforcedMasterPasswordOptions + enforcedOptions ); }