From b7288e9b4d5c9f889f17511eb695729fde69a861 Mon Sep 17 00:00:00 2001 From: Shane Melton Date: Tue, 7 Mar 2023 17:02:30 -0800 Subject: [PATCH] [AC-1070] Introduce logic to update both temp and regular passwords - Check the Reason to use the appropriate request/endpoint when submitting. - Verify the users current password locally using the user verification service. --- .../UpdateTempPasswordPageViewModel.cs | 67 ++++++++++++++++--- 1 file changed, 58 insertions(+), 9 deletions(-) diff --git a/src/App/Pages/Accounts/UpdateTempPasswordPageViewModel.cs b/src/App/Pages/Accounts/UpdateTempPasswordPageViewModel.cs index 18eea7719..2a85c8229 100644 --- a/src/App/Pages/Accounts/UpdateTempPasswordPageViewModel.cs +++ b/src/App/Pages/Accounts/UpdateTempPasswordPageViewModel.cs @@ -1,21 +1,28 @@ using System; using System.Threading.Tasks; using Bit.App.Resources; +using Bit.Core.Abstractions; +using Bit.Core.Enums; using Bit.Core.Exceptions; using Bit.Core.Models.Domain; using Bit.Core.Models.Request; +using Bit.Core.Utilities; using Xamarin.Forms; namespace Bit.App.Pages { public class UpdateTempPasswordPageViewModel : BaseChangePasswordViewModel { + private readonly IUserVerificationService _userVerificationService; + public UpdateTempPasswordPageViewModel() { PageTitle = AppResources.UpdateMasterPassword; TogglePasswordCommand = new Command(TogglePassword); ToggleConfirmPasswordCommand = new Command(ToggleConfirmPassword); SubmitCommand = new Command(async () => await SubmitAsync()); + + _userVerificationService = ServiceContainer.Resolve("userVerificationService"); } public Command SubmitCommand { get; } @@ -72,6 +79,13 @@ namespace Bit.App.Pages return; } + if ( + RequireCurrentPassword && + !await _userVerificationService.VerifyUser(CurrentMasterPassword, VerificationType.MasterPassword)) + { + return; + } + // Retrieve details for key generation var kdfConfig = await _stateService.GetActiveUserCustomDataAsync(a => new KdfConfig(a?.Profile)); var email = await _stateService.GetEmailAsync(); @@ -83,20 +97,28 @@ namespace Bit.App.Pages // Create new encKey for the User var newEncKey = await _cryptoService.RemakeEncKeyAsync(key); - // Create request - var request = new UpdateTempPasswordRequest - { - Key = newEncKey.Item2.EncryptedString, - NewMasterPasswordHash = masterPasswordHash, - MasterPasswordHint = Hint - }; - // Initiate API action try { await _deviceActionService.ShowLoadingAsync(AppResources.UpdatingPassword); - await _apiService.PutUpdateTempPasswordAsync(request); + + switch (Reason) + { + case ForcePasswordResetReason.AdminForcePasswordReset: + await UpdateTempPasswordAsync(masterPasswordHash, newEncKey); + break; + case ForcePasswordResetReason.WeakMasterPasswordOnLogin: + await UpdatePasswordAsync(masterPasswordHash, newEncKey); + break; + default: + throw new ArgumentOutOfRangeException(); + } await _deviceActionService.HideLoadingAsync(); + + // Clear the force reset password reason + await _stateService.SetForcePasswordResetReasonAsync(null); + + _platformUtilsService.ShowToast("success", null, AppResources.UpdatedMasterPassword); UpdateTempPasswordSuccessAction?.Invoke(); } @@ -115,5 +137,32 @@ namespace Bit.App.Pages } } } + + private async Task UpdateTempPasswordAsync(string newMasterPasswordHash, Tuple newEncKey) + { + var request = new UpdateTempPasswordRequest + { + Key = newEncKey.Item2.EncryptedString, + NewMasterPasswordHash = newMasterPasswordHash, + MasterPasswordHint = Hint + }; + + await _apiService.PutUpdateTempPasswordAsync(request); + } + + private async Task UpdatePasswordAsync(string newMasterPasswordHash, Tuple newEncKey) + { + var currentPasswordHash = await _cryptoService.HashPasswordAsync(CurrentMasterPassword, null); + + var request = new PasswordRequest + { + MasterPasswordHash = currentPasswordHash, + Key = newEncKey.Item2.EncryptedString, + NewMasterPasswordHash = newMasterPasswordHash, + MasterPasswordHint = Hint + }; + + await _apiService.PostPasswordAsync(request); + } } }