diff --git a/src/App/App.xaml.cs b/src/App/App.xaml.cs index a6fc61929..095d5778a 100644 --- a/src/App/App.xaml.cs +++ b/src/App/App.xaml.cs @@ -308,6 +308,7 @@ namespace Bit.App private async Task SleptAsync() { await _vaultTimeoutService.CheckVaultTimeoutAsync(); + await ClearSensitiveFieldsAsync(); _messagingService.Send("stopEventTimer"); } @@ -315,6 +316,7 @@ namespace Bit.App { await _stateService.CheckExtensionActiveUserAndSwitchIfNeededAsync(); await _vaultTimeoutService.CheckVaultTimeoutAsync(); + await ClearSensitiveFieldsAsync(); _messagingService.Send("startEventTimer"); await UpdateThemeAsync(); await ClearCacheIfNeededAsync(); @@ -335,6 +337,14 @@ namespace Bit.App }); } + private async Task ClearSensitiveFieldsAsync() + { + await Device.InvokeOnMainThreadAsync(() => + { + _messagingService.Send(Constants.ClearSensitiveFields); + }); + } + private void SetCulture() { // Calendars are removed by linker. ref https://bugzilla.xamarin.com/show_bug.cgi?id=59077 diff --git a/src/App/Pages/Accounts/LockPage.xaml.cs b/src/App/Pages/Accounts/LockPage.xaml.cs index 22f6416ef..f5a7914a5 100644 --- a/src/App/Pages/Accounts/LockPage.xaml.cs +++ b/src/App/Pages/Accounts/LockPage.xaml.cs @@ -3,6 +3,8 @@ using System.Threading.Tasks; using Bit.App.Models; using Bit.App.Resources; using Bit.App.Utilities; +using Bit.Core; +using Bit.Core.Abstractions; using Bit.Core.Utilities; using Xamarin.Forms; @@ -10,6 +12,7 @@ namespace Bit.App.Pages { public partial class LockPage : BaseContentPage { + private readonly IBroadcasterService _broadcasterService; private readonly AppOptions _appOptions; private readonly bool _autoPromptBiometric; private readonly LockPageViewModel _vm; @@ -22,6 +25,7 @@ namespace Bit.App.Pages _appOptions = appOptions; _autoPromptBiometric = autoPromptBiometric; InitializeComponent(); + _broadcasterService = ServiceContainer.Resolve(); _vm = BindingContext as LockPageViewModel; _vm.Page = this; _vm.UnlockedAction = () => Device.BeginInvokeOnMainThread(async () => await UnlockedAsync()); @@ -64,6 +68,13 @@ namespace Bit.App.Pages protected override async void OnAppearing() { base.OnAppearing(); + _broadcasterService.Subscribe(nameof(LockPage), message => + { + if (message.Command == Constants.ClearSensitiveFields) + { + Device.BeginInvokeOnMainThread(_vm.ResetPinPasswordFields); + } + }); if (_appeared) { return; @@ -129,6 +140,7 @@ namespace Bit.App.Pages base.OnDisappearing(); _accountAvatar?.OnDisappearing(); + _broadcasterService.Unsubscribe(nameof(LockPage)); } private void Unlock_Clicked(object sender, EventArgs e) diff --git a/src/App/Pages/Accounts/LockPageViewModel.cs b/src/App/Pages/Accounts/LockPageViewModel.cs index efa89edac..1ed66fc34 100644 --- a/src/App/Pages/Accounts/LockPageViewModel.cs +++ b/src/App/Pages/Accounts/LockPageViewModel.cs @@ -9,6 +9,7 @@ using Bit.Core.Abstractions; using Bit.Core.Enums; using Bit.Core.Models.Domain; using Bit.Core.Models.Request; +using Bit.Core.Services; using Bit.Core.Utilities; using Xamarin.CommunityToolkit.Helpers; using Xamarin.Forms; @@ -32,6 +33,8 @@ namespace Bit.App.Pages private readonly WeakEventManager _secretEntryFocusWeakEventManager = new WeakEventManager(); private string _email; + private string _masterPassword; + private string _pin; private bool _showPassword; private bool _pinLock; private bool _biometricLock; @@ -70,6 +73,18 @@ namespace Bit.App.Pages }; } + public string MasterPassword + { + get => _masterPassword; + set => SetProperty(ref _masterPassword, value); + } + + public string Pin + { + get => _pin; + set => SetProperty(ref _pin, value); + } + public bool ShowPassword { get => _showPassword; @@ -134,8 +149,6 @@ namespace Bit.App.Pages public Command TogglePasswordCommand { get; } public string ShowPasswordIcon => ShowPassword ? BitwardenIcons.EyeSlash : BitwardenIcons.Eye; public string PasswordVisibilityAccessibilityText => ShowPassword ? AppResources.PasswordIsVisibleTapToHide : AppResources.PasswordIsNotVisibleTapToShow; - public string MasterPassword { get; set; } - public string Pin { get; set; } public Action UnlockedAction { get; set; } public event Action FocusSecretEntry { @@ -349,6 +362,20 @@ namespace Bit.App.Pages } } + public void ResetPinPasswordFields() + { + try + { + MasterPassword = string.Empty; + Pin = string.Empty; + ShowPassword = false; + } + catch (Exception ex) + { + LoggerHelper.LogEvenIfCantBeResolved(ex); + } + } + public void TogglePassword() { ShowPassword = !ShowPassword; diff --git a/src/App/Pages/Accounts/LoginPage.xaml.cs b/src/App/Pages/Accounts/LoginPage.xaml.cs index fba9debcb..09be8cb4a 100644 --- a/src/App/Pages/Accounts/LoginPage.xaml.cs +++ b/src/App/Pages/Accounts/LoginPage.xaml.cs @@ -2,6 +2,7 @@ using System.Threading.Tasks; using Bit.App.Models; using Bit.App.Utilities; +using Bit.Core; using Bit.Core.Abstractions; using Bit.Core.Services; using Bit.Core.Utilities; @@ -12,6 +13,7 @@ namespace Bit.App.Pages { public partial class LoginPage : BaseContentPage { + private readonly IBroadcasterService _broadcasterService; private readonly LoginPageViewModel _vm; private readonly AppOptions _appOptions; @@ -23,6 +25,7 @@ namespace Bit.App.Pages { _appOptions = appOptions; InitializeComponent(); + _broadcasterService = ServiceContainer.Resolve(); _vm = BindingContext as LoginPageViewModel; _vm.Page = this; _vm.StartTwoFactorAction = () => Device.BeginInvokeOnMainThread(async () => await StartTwoFactorAsync()); @@ -70,6 +73,13 @@ namespace Bit.App.Pages protected override async void OnAppearing() { base.OnAppearing(); + _broadcasterService.Subscribe(nameof(LoginPage), message => + { + if (message.Command == Constants.ClearSensitiveFields) + { + Device.BeginInvokeOnMainThread(_vm.ResetPasswordField); + } + }); _mainContent.Content = _mainLayout; _accountAvatar?.OnAppearing(); @@ -104,6 +114,7 @@ namespace Bit.App.Pages base.OnDisappearing(); _accountAvatar?.OnDisappearing(); + _broadcasterService.Unsubscribe(nameof(LoginPage)); } private async void LogIn_Clicked(object sender, EventArgs e) diff --git a/src/App/Pages/Accounts/LoginPageViewModel.cs b/src/App/Pages/Accounts/LoginPageViewModel.cs index 74c9fe701..be8ab4d99 100644 --- a/src/App/Pages/Accounts/LoginPageViewModel.cs +++ b/src/App/Pages/Accounts/LoginPageViewModel.cs @@ -255,6 +255,19 @@ namespace Bit.App.Pages } } + public void ResetPasswordField() + { + try + { + MasterPassword = string.Empty; + ShowPassword = false; + } + catch (Exception ex) + { + LoggerHelper.LogEvenIfCantBeResolved(ex); + } + } + private async Task MoreAsync() { var buttons = IsEmailEnabled || CanRemoveAccount diff --git a/src/Core/Constants.cs b/src/Core/Constants.cs index 5455682e4..beb8c6d99 100644 --- a/src/Core/Constants.cs +++ b/src/Core/Constants.cs @@ -47,6 +47,7 @@ /// public const string LastUserShouldConnectToWatchKey = "lastUserShouldConnectToWatch"; public const string AppLocaleKey = "appLocale"; + public const string ClearSensitiveFields = "clearSensitiveFields"; public const int SelectFileRequestCode = 42; public const int SelectFilePermissionRequestCode = 43; public const int SaveFileRequestCode = 44;