From 4c3df2e1e15f28ca0e56b2697c293062a2ffa761 Mon Sep 17 00:00:00 2001 From: Vincent Salucci <26154748+vincentsalucci@users.noreply.github.com> Date: Fri, 29 May 2020 11:26:36 -0500 Subject: [PATCH] [Auto Logout] Final review of feature (#932) * Initial commit of LockService name refactor (#831) * [Auto-Logout] Update Service layer logic (#835) * Initial commit of service logic update * Added default value for action * Updated ToggleTokensAsync conditional * Removed unused variables, updated action conditional * Initial commit: lockOption/lock refactor app layer (#840) * [Auto-Logout] Settings Refactor - Application Layer Part 2 (#844) * Initial commit of app layer part 2 * Updated biometrics position * Reverted resource name refactor * LockOptions refactor revert * Updated method casing :: Removed VaultTimeout prefix for timeouts * Fixed dupe string resource (#854) * Updated dependency to use VaultTimeoutService (#896) * [Auto Logout] Xamarin Forms in AutoFill flow (iOS) (#902) * fix typo in PINRequireMasterPasswordRestart (#900) * initial commit for xf usage in autofill * Fixed databinding for hint button * Updated Two Factor page launch - removed unused imports * First pass at broadcast/messenger implentation for autofill * setting theme in extension using theme manager * extension app resources * App resources from main app * fix ref to twoFactorPage * apply resources to page * load empty app for sytling in extension * move ios renderers to ios core * static ref to resources and GetResourceColor helper * fix method ref * move application.current.resources refs to helper * switch login page alerts to device action dialogs * run on main thread * showDialog with device action service * abstract action sheet to device action service * add support for yubikey * add yubikey iimages to extension * support close button action * add support to action extension * remove empty lines Co-authored-by: Jonas Kittner <54631600+theendlessriver13@users.noreply.github.com> Co-authored-by: Kyle Spearrin * [Auto Logout] Update lock option to be default value (#929) * Initial commit - make lock action default * Removed extra whitespace Co-authored-by: Jonas Kittner <54631600+theendlessriver13@users.noreply.github.com> Co-authored-by: Kyle Spearrin Co-authored-by: Kyle Spearrin --- src/Android/Autofill/AutofillService.cs | 8 +- src/Android/Effects/FabShadowEffect.cs | 3 +- src/Android/MainActivity.cs | 18 +-- src/Android/Receivers/LockAlarmReceiver.cs | 4 +- .../Renderers/CipherViewCellRenderer.cs | 11 +- src/Android/Services/DeviceActionService.cs | 15 ++- src/App/Abstractions/IDeviceActionService.cs | 1 + src/App/App.xaml.cs | 93 +++++++++------- src/App/Models/AppOptions.cs | 1 + src/App/Pages/Accounts/LockPageViewModel.cs | 18 +-- src/App/Pages/Accounts/LoginPage.xaml | 4 +- src/App/Pages/Accounts/LoginPage.xaml.cs | 10 +- src/App/Pages/Accounts/LoginPageViewModel.cs | 17 ++- src/App/Pages/Accounts/TwoFactorPage.xaml.cs | 3 +- .../Pages/Accounts/TwoFactorPageViewModel.cs | 5 +- .../SettingsPage/SettingsPage.xaml.cs | 8 +- .../SettingsPage/SettingsPageListItem.cs | 5 +- .../SettingsPage/SettingsPageViewModel.cs | 103 +++++++++++++----- .../Vault/GroupingsPage/GroupingsPage.xaml.cs | 6 +- .../GroupingsPage/GroupingsPageViewModel.cs | 6 +- src/App/Pages/Vault/ViewPageViewModel.cs | 4 +- src/App/Resources/AppResources.Designer.cs | 57 +++++----- src/App/Resources/AppResources.af.resx | 2 +- src/App/Resources/AppResources.de.resx | 2 +- src/App/Resources/AppResources.es.resx | 2 +- src/App/Resources/AppResources.et.resx | 2 +- src/App/Resources/AppResources.fa.resx | 2 +- src/App/Resources/AppResources.hu.resx | 2 +- src/App/Resources/AppResources.id.resx | 2 +- src/App/Resources/AppResources.it.resx | 2 +- src/App/Resources/AppResources.ko.resx | 2 +- src/App/Resources/AppResources.nb.resx | 2 +- src/App/Resources/AppResources.resx | 30 ++--- src/App/Resources/AppResources.ro.resx | 2 +- src/App/Resources/AppResources.sk.resx | 2 +- src/App/Resources/AppResources.th.resx | 2 +- src/App/Resources/AppResources.vi.resx | 2 +- src/App/Services/MobileStorageService.cs | 3 +- src/App/Utilities/AppHelpers.cs | 16 ++- src/App/Utilities/PasswordFormatter.cs | 6 +- src/App/Utilities/ThemeManager.cs | 49 ++++++--- src/Core/Abstractions/ITokenService.cs | 3 +- ...LockService.cs => IVaultTimeoutService.cs} | 7 +- src/Core/Constants.cs | 3 +- src/Core/Services/AuthService.cs | 8 +- src/Core/Services/CryptoService.cs | 4 +- src/Core/Services/TokenService.cs | 37 +++++++ ...{LockService.cs => VaultTimeoutService.cs} | 53 ++++++--- src/Core/Utilities/ServiceContainer.cs | 13 ++- .../CredentialProviderViewController.cs | 83 ++++++++++---- src/iOS.Autofill/Resources/yubikey.png | Bin 0 -> 54828 bytes src/iOS.Autofill/Resources/yubikey@2x.png | Bin 0 -> 204568 bytes src/iOS.Autofill/Resources/yubikey@3x.png | Bin 0 -> 427125 bytes src/iOS.Autofill/iOS.Autofill.csproj | 9 ++ .../Controllers/LockPasswordViewController.cs | 18 +-- src/{iOS => iOS.Core}/NFCReaderDelegate.cs | 2 +- .../Renderers/CustomButtonRenderer.cs | 6 +- .../Renderers/CustomContentPageRenderer.cs | 4 +- .../Renderers/CustomEditorRenderer.cs | 6 +- .../Renderers/CustomEntryRenderer.cs | 8 +- .../Renderers/CustomLabelRenderer.cs | 6 +- .../Renderers/CustomPickerRenderer.cs | 8 +- .../Renderers/CustomSearchBarRenderer.cs | 6 +- .../Renderers/CustomTabbedRenderer.cs | 4 +- .../Renderers/CustomViewCellRenderer.cs | 7 +- .../Renderers/HybridWebViewRenderer.cs | 4 +- src/iOS.Core/Services/DeviceActionService.cs | 39 +++++++ src/iOS.Core/Utilities/ASHelpers.cs | 4 +- src/iOS.Core/Utilities/Dialogs.cs | 10 +- src/iOS.Core/Utilities/iOSCoreHelpers.cs | 53 +++++++++ src/{iOS => iOS.Core}/Utilities/iOSHelpers.cs | 9 +- src/iOS.Core/Views/Toast.cs | 7 +- src/iOS.Core/iOS.Core.csproj | 12 ++ src/iOS.Extension/LoadingViewController.cs | 72 ++++++++++-- src/iOS.Extension/Resources/yubikey.png | Bin 0 -> 54828 bytes src/iOS.Extension/Resources/yubikey@2x.png | Bin 0 -> 204568 bytes src/iOS.Extension/Resources/yubikey@3x.png | Bin 0 -> 427125 bytes src/iOS.Extension/iOS.Extension.csproj | 3 + src/iOS/AppDelegate.cs | 71 +++++------- src/iOS/iOS.csproj | 12 -- 80 files changed, 744 insertions(+), 379 deletions(-) rename src/Core/Abstractions/{ILockService.cs => IVaultTimeoutService.cs} (72%) rename src/Core/Services/{LockService.cs => VaultTimeoutService.cs} (74%) create mode 100644 src/iOS.Autofill/Resources/yubikey.png create mode 100644 src/iOS.Autofill/Resources/yubikey@2x.png create mode 100644 src/iOS.Autofill/Resources/yubikey@3x.png rename src/{iOS => iOS.Core}/NFCReaderDelegate.cs (98%) rename src/{iOS => iOS.Core}/Renderers/CustomButtonRenderer.cs (92%) rename src/{iOS => iOS.Core}/Renderers/CustomContentPageRenderer.cs (97%) rename src/{iOS => iOS.Core}/Renderers/CustomEditorRenderer.cs (92%) rename src/{iOS => iOS.Core}/Renderers/CustomEntryRenderer.cs (94%) rename src/{iOS => iOS.Core}/Renderers/CustomLabelRenderer.cs (93%) rename src/{iOS => iOS.Core}/Renderers/CustomPickerRenderer.cs (85%) rename src/{iOS => iOS.Core}/Renderers/CustomSearchBarRenderer.cs (84%) rename src/{iOS => iOS.Core}/Renderers/CustomTabbedRenderer.cs (86%) rename src/{iOS => iOS.Core}/Renderers/CustomViewCellRenderer.cs (78%) rename src/{iOS => iOS.Core}/Renderers/HybridWebViewRenderer.cs (97%) rename src/{iOS => iOS.Core}/Utilities/iOSHelpers.cs (92%) create mode 100644 src/iOS.Extension/Resources/yubikey.png create mode 100644 src/iOS.Extension/Resources/yubikey@2x.png create mode 100644 src/iOS.Extension/Resources/yubikey@3x.png diff --git a/src/Android/Autofill/AutofillService.cs b/src/Android/Autofill/AutofillService.cs index 1062c2274..cbbcb2642 100644 --- a/src/Android/Autofill/AutofillService.cs +++ b/src/Android/Autofill/AutofillService.cs @@ -21,7 +21,7 @@ namespace Bit.Droid.Autofill public class AutofillService : Android.Service.Autofill.AutofillService { private ICipherService _cipherService; - private ILockService _lockService; + private IVaultTimeoutService _vaultTimeoutService; private IStorageService _storageService; public async override void OnFillRequest(FillRequest request, CancellationSignal cancellationSignal, @@ -47,13 +47,13 @@ namespace Bit.Droid.Autofill return; } - if (_lockService == null) + if (_vaultTimeoutService == null) { - _lockService = ServiceContainer.Resolve("lockService"); + _vaultTimeoutService = ServiceContainer.Resolve("vaultTimeoutService"); } List items = null; - var locked = await _lockService.IsLockedAsync(); + var locked = await _vaultTimeoutService.IsLockedAsync(); if (!locked) { if (_cipherService == null) diff --git a/src/Android/Effects/FabShadowEffect.cs b/src/Android/Effects/FabShadowEffect.cs index ad0083d37..11bda2e4f 100644 --- a/src/Android/Effects/FabShadowEffect.cs +++ b/src/Android/Effects/FabShadowEffect.cs @@ -1,4 +1,5 @@ using Android.Graphics.Drawables; +using Bit.App.Utilities; using Bit.Droid.Effects; using Xamarin.Forms; using Xamarin.Forms.Platform.Android; @@ -13,7 +14,7 @@ namespace Bit.Droid.Effects if (Control is Android.Widget.Button button) { var gd = new GradientDrawable(); - gd.SetColor(((Color)Application.Current.Resources["FabColor"]).ToAndroid()); + gd.SetColor(ThemeManager.GetResourceColor("FabColor").ToAndroid()); gd.SetCornerRadius(100); button.SetBackground(gd); diff --git a/src/Android/MainActivity.cs b/src/Android/MainActivity.cs index 0155c3992..d36a6df89 100644 --- a/src/Android/MainActivity.cs +++ b/src/Android/MainActivity.cs @@ -37,7 +37,7 @@ namespace Bit.Droid private IAppIdService _appIdService; private IStorageService _storageService; private IEventService _eventService; - private PendingIntent _lockAlarmPendingIntent; + private PendingIntent _vaultTimeoutAlarmPendingIntent; private PendingIntent _clearClipboardPendingIntent; private PendingIntent _eventUploadPendingIntent; private AppOptions _appOptions; @@ -51,7 +51,7 @@ namespace Bit.Droid _eventUploadPendingIntent = PendingIntent.GetBroadcast(this, 0, eventUploadIntent, PendingIntentFlags.UpdateCurrent); var alarmIntent = new Intent(this, typeof(LockAlarmReceiver)); - _lockAlarmPendingIntent = PendingIntent.GetBroadcast(this, 0, alarmIntent, + _vaultTimeoutAlarmPendingIntent = PendingIntent.GetBroadcast(this, 0, alarmIntent, PendingIntentFlags.UpdateCurrent); var clearClipboardIntent = new Intent(this, typeof(ClearClipboardAlarmReceiver)); _clearClipboardPendingIntent = PendingIntent.GetBroadcast(this, 0, clearClipboardIntent, @@ -90,18 +90,18 @@ namespace Bit.Droid _broadcasterService.Subscribe(_activityKey, (message) => { - if (message.Command == "scheduleLockTimer") + if (message.Command == "scheduleVaultTimeoutTimer") { var alarmManager = GetSystemService(AlarmService) as AlarmManager; - var lockOptionMinutes = (int)message.Data; - var lockOptionMs = lockOptionMinutes * 60000; - var triggerMs = Java.Lang.JavaSystem.CurrentTimeMillis() + lockOptionMs + 10; - alarmManager.Set(AlarmType.RtcWakeup, triggerMs, _lockAlarmPendingIntent); + var vaultTimeoutMinutes = (int)message.Data; + var vaultTimeoutMs = vaultTimeoutMinutes * 60000; + var triggerMs = Java.Lang.JavaSystem.CurrentTimeMillis() + vaultTimeoutMs + 10; + alarmManager.Set(AlarmType.RtcWakeup, triggerMs, _vaultTimeoutAlarmPendingIntent); } - else if (message.Command == "cancelLockTimer") + else if (message.Command == "cancelVaultTimeoutTimer") { var alarmManager = GetSystemService(AlarmService) as AlarmManager; - alarmManager.Cancel(_lockAlarmPendingIntent); + alarmManager.Cancel(_vaultTimeoutAlarmPendingIntent); } else if (message.Command == "startEventTimer") { diff --git a/src/Android/Receivers/LockAlarmReceiver.cs b/src/Android/Receivers/LockAlarmReceiver.cs index 95979c3bc..e774a367b 100644 --- a/src/Android/Receivers/LockAlarmReceiver.cs +++ b/src/Android/Receivers/LockAlarmReceiver.cs @@ -9,8 +9,8 @@ namespace Bit.Droid.Receivers { public async override void OnReceive(Context context, Intent intent) { - var lockService = ServiceContainer.Resolve("lockService"); - await lockService.CheckLockAsync(); + var vaultTimeoutService = ServiceContainer.Resolve("vaultTimeoutService"); + await vaultTimeoutService.CheckVaultTimeoutAsync(); } } } diff --git a/src/Android/Renderers/CipherViewCellRenderer.cs b/src/Android/Renderers/CipherViewCellRenderer.cs index 0d4811cb1..80b26518c 100644 --- a/src/Android/Renderers/CipherViewCellRenderer.cs +++ b/src/Android/Renderers/CipherViewCellRenderer.cs @@ -7,6 +7,7 @@ using Android.Views; using Android.Views.InputMethods; using Android.Widget; using Bit.App.Controls; +using Bit.App.Utilities; using Bit.Droid.Renderers; using FFImageLoading; using FFImageLoading.Views; @@ -42,19 +43,15 @@ namespace Bit.Droid.Renderers } if (_textColor == default(Android.Graphics.Color)) { - _textColor = ((Xamarin.Forms.Color)Xamarin.Forms.Application.Current.Resources["TextColor"]) - .ToAndroid(); + _textColor = ThemeManager.GetResourceColor("TextColor").ToAndroid(); } if (_mutedColor == default(Android.Graphics.Color)) { - _mutedColor = ((Xamarin.Forms.Color)Xamarin.Forms.Application.Current.Resources["MutedColor"]) - .ToAndroid(); + _mutedColor = ThemeManager.GetResourceColor("MutedColor").ToAndroid(); } if (_disabledIconColor == default(Android.Graphics.Color)) { - _disabledIconColor = - ((Xamarin.Forms.Color)Xamarin.Forms.Application.Current.Resources["DisabledIconColor"]) - .ToAndroid(); + _disabledIconColor = ThemeManager.GetResourceColor("DisabledIconColor").ToAndroid(); } var cipherCell = item as CipherViewCell; diff --git a/src/Android/Services/DeviceActionService.cs b/src/Android/Services/DeviceActionService.cs index 78390e741..57b8063f4 100644 --- a/src/Android/Services/DeviceActionService.cs +++ b/src/Android/Services/DeviceActionService.cs @@ -200,13 +200,13 @@ namespace Bit.Droid.Services catch { } return null; } - + public bool SaveFile(byte[] fileData, string id, string fileName, string contentUri) { try { var activity = (MainActivity)CrossCurrentActivity.Current.Activity; - + if (contentUri != null) { var uri = Android.Net.Uri.Parse(contentUri); @@ -219,7 +219,7 @@ namespace Bit.Droid.Services javaStream.Close(); return true; } - + // Prompt for location to save file var extension = MimeTypeMap.GetFileExtensionFromUrl(fileName.Replace(' ', '_').ToLower()); if (extension == null) @@ -238,7 +238,7 @@ namespace Bit.Droid.Services intent.SetType(mimeType); intent.AddCategory(Intent.CategoryOpenable); intent.PutExtra(Intent.ExtraTitle, fileName); - + activity.StartActivityForResult(intent, Constants.SaveFileRequestCode); return true; } @@ -569,6 +569,13 @@ namespace Bit.Droid.Services return result.Task; } + public async Task DisplayActionSheetAsync(string title, string cancel, string destruction, + params string[] buttons) + { + return await Xamarin.Forms.Application.Current.MainPage.DisplayActionSheet( + title, cancel, destruction, buttons); + } + public void Autofill(CipherView cipher) { var activity = (MainActivity)CrossCurrentActivity.Current.Activity; diff --git a/src/App/Abstractions/IDeviceActionService.cs b/src/App/Abstractions/IDeviceActionService.cs index 785402fd6..994943317 100644 --- a/src/App/Abstractions/IDeviceActionService.cs +++ b/src/App/Abstractions/IDeviceActionService.cs @@ -32,6 +32,7 @@ namespace Bit.App.Abstractions int SystemMajorVersion(); string SystemModel(); Task DisplayAlertAsync(string title, string message, string cancel, params string[] buttons); + Task DisplayActionSheetAsync(string title, string cancel, string destruction, params string[] buttons); void Autofill(CipherView cipher); void CloseAutofill(); void Background(); diff --git a/src/App/App.xaml.cs b/src/App/App.xaml.cs index e862ffa34..fb9482346 100644 --- a/src/App/App.xaml.cs +++ b/src/App/App.xaml.cs @@ -22,7 +22,7 @@ namespace Bit.App private readonly IBroadcasterService _broadcasterService; private readonly IMessagingService _messagingService; private readonly IStateService _stateService; - private readonly ILockService _lockService; + private readonly IVaultTimeoutService _vaultTimeoutService; private readonly ISyncService _syncService; private readonly ITokenService _tokenService; private readonly ICryptoService _cryptoService; @@ -37,18 +37,22 @@ namespace Bit.App private readonly IStorageService _storageService; private readonly IStorageService _secureStorageService; private readonly IDeviceActionService _deviceActionService; - private readonly AppOptions _appOptions; private static bool _isResumed; public App(AppOptions appOptions) { - _appOptions = appOptions ?? new AppOptions(); + Options = appOptions ?? new AppOptions(); + if (Options.EmptyApp) + { + Current = this; + return; + } _userService = ServiceContainer.Resolve("userService"); _broadcasterService = ServiceContainer.Resolve("broadcasterService"); _messagingService = ServiceContainer.Resolve("messagingService"); _stateService = ServiceContainer.Resolve("stateService"); - _lockService = ServiceContainer.Resolve("lockService"); + _vaultTimeoutService = ServiceContainer.Resolve("vaultTimeoutService"); _syncService = ServiceContainer.Resolve("syncService"); _tokenService = ServiceContainer.Resolve("tokenService"); _cryptoService = ServiceContainer.Resolve("cryptoService"); @@ -95,7 +99,7 @@ namespace Bit.App } else if (message.Command == "lockVault") { - await _lockService.LockAsync(true); + await _vaultTimeoutService.LockAsync(true); } else if (message.Command == "logout") { @@ -139,12 +143,12 @@ namespace Bit.App } if (message.Command == "popAllAndGoToTabMyVault") { - _appOptions.MyVaultTile = false; + Options.MyVaultTile = false; tabsPage.ResetToVaultPage(); } else { - _appOptions.GeneratorTile = false; + Options.GeneratorTile = false; tabsPage.ResetToGeneratorPage(); } } @@ -152,14 +156,16 @@ namespace Bit.App } }); } - + + public AppOptions Options { get; private set; } + protected async override void OnStart() { System.Diagnostics.Debug.WriteLine("XF App: OnStart"); await ClearCacheIfNeededAsync(); await TryClearCiphersCacheAsync(); Prime(); - if (string.IsNullOrWhiteSpace(_appOptions.Uri)) + if (string.IsNullOrWhiteSpace(Options.Uri)) { var updated = await AppHelpers.PerformUpdateTasksAsync(_syncService, _deviceActionService, _storageService); @@ -177,7 +183,7 @@ namespace Bit.App _isResumed = false; if (Device.RuntimePlatform == Device.Android) { - var isLocked = await _lockService.IsLockedAsync(); + var isLocked = await _vaultTimeoutService.IsLockedAsync(); if (!isLocked) { await _storageService.SaveAsync(Constants.LastActiveKey, DateTime.UtcNow); @@ -199,13 +205,13 @@ namespace Bit.App private async Task SleptAsync() { - await HandleLockingAsync(); + await HandleVaultTimeoutAsync(); _messagingService.Send("stopEventTimer"); } private async void ResumedAsync() { - _messagingService.Send("cancelLockTimer"); + _messagingService.Send("cancelVaultTimeoutTimer"); _messagingService.Send("startEventTimer"); await ClearCacheIfNeededAsync(); await TryClearCiphersCacheAsync(); @@ -238,9 +244,9 @@ namespace Bit.App _folderService.ClearAsync(userId), _collectionService.ClearAsync(userId), _passwordGenerationService.ClearAsync(), - _lockService.ClearAsync(), + _vaultTimeoutService.ClearAsync(), _stateService.PurgeAsync()); - _lockService.FingerprintLocked = true; + _vaultTimeoutService.FingerprintLocked = true; _searchService.ClearIndex(); _authService.LogOut(() => { @@ -257,32 +263,32 @@ namespace Bit.App var authed = await _userService.IsAuthenticatedAsync(); if (authed) { - if (await _lockService.IsLockedAsync()) + if (await _vaultTimeoutService.IsLockedAsync()) { - Current.MainPage = new NavigationPage(new LockPage(_appOptions)); + Current.MainPage = new NavigationPage(new LockPage(Options)); } - else if (_appOptions.FromAutofillFramework && _appOptions.SaveType.HasValue) + else if (Options.FromAutofillFramework && Options.SaveType.HasValue) { - Current.MainPage = new NavigationPage(new AddEditPage(appOptions: _appOptions)); + Current.MainPage = new NavigationPage(new AddEditPage(appOptions: Options)); } - else if (_appOptions.Uri != null) + else if (Options.Uri != null) { - Current.MainPage = new NavigationPage(new AutofillCiphersPage(_appOptions)); + Current.MainPage = new NavigationPage(new AutofillCiphersPage(Options)); } else { - Current.MainPage = new TabsPage(_appOptions); + Current.MainPage = new TabsPage(Options); } } else { - Current.MainPage = new HomePage(_appOptions); + Current.MainPage = new HomePage(Options); } } - private async Task HandleLockingAsync() + private async Task HandleVaultTimeoutAsync() { - if (await _lockService.IsLockedAsync()) + if (await _vaultTimeoutService.IsLockedAsync()) { return; } @@ -291,19 +297,28 @@ namespace Bit.App { return; } - var lockOption = _platformUtilsService.LockTimeout(); - if (lockOption == null) + // Will only ever be null - look to remove this in the future + var vaultTimeout = _platformUtilsService.LockTimeout(); + if (vaultTimeout == null) { - lockOption = await _storageService.GetAsync(Constants.LockOptionKey); + vaultTimeout = await _storageService.GetAsync(Constants.VaultTimeoutKey); } - lockOption = lockOption.GetValueOrDefault(-1); - if (lockOption > 0) + vaultTimeout = vaultTimeout.GetValueOrDefault(-1); + if (vaultTimeout > 0) { - _messagingService.Send("scheduleLockTimer", lockOption.Value); + _messagingService.Send("scheduleVaultTimeoutTimer", vaultTimeout.Value); } - else if (lockOption == 0) + else if (vaultTimeout == 0) { - await _lockService.LockAsync(true); + var action = await _storageService.GetAsync(Constants.VaultTimeoutActionKey); + if (action == "logOut") + { + await _vaultTimeoutService.LogOutAsync(); + } + else + { + await _vaultTimeoutService.LockAsync(true); + } } } @@ -318,14 +333,14 @@ namespace Bit.App private void SetTabsPageFromAutofill(bool isLocked) { - if (Device.RuntimePlatform == Device.Android && !string.IsNullOrWhiteSpace(_appOptions.Uri) && - !_appOptions.FromAutofillFramework) + if (Device.RuntimePlatform == Device.Android && !string.IsNullOrWhiteSpace(Options.Uri) && + !Options.FromAutofillFramework) { Task.Run(() => { Device.BeginInvokeOnMainThread(() => { - _appOptions.Uri = null; + Options.Uri = null; if (isLocked) { Current.MainPage = new NavigationPage(new LockPage()); @@ -352,7 +367,7 @@ namespace Bit.App { InitializeComponent(); SetCulture(); - ThemeManager.SetTheme(Device.RuntimePlatform == Device.Android); + ThemeManager.SetTheme(Device.RuntimePlatform == Device.Android, Current.Resources); Current.MainPage = new HomePage(); var mainPageTask = SetMainPageAsync(); ServiceContainer.Resolve("platformUtilsService").Init(); @@ -394,8 +409,8 @@ namespace Bit.App await _stateService.PurgeAsync(); if (autoPromptFingerprint && Device.RuntimePlatform == Device.iOS) { - var lockOptions = await _storageService.GetAsync(Constants.LockOptionKey); - if (lockOptions == 0) + var vaultTimeout = await _storageService.GetAsync(Constants.VaultTimeoutKey); + if (vaultTimeout == 0) { autoPromptFingerprint = false; } @@ -430,7 +445,7 @@ namespace Bit.App } } await _storageService.SaveAsync(Constants.PreviousPageKey, lastPageBeforeLock); - var lockPage = new LockPage(_appOptions, autoPromptFingerprint); + var lockPage = new LockPage(Options, autoPromptFingerprint); Device.BeginInvokeOnMainThread(() => Current.MainPage = new NavigationPage(lockPage)); } } diff --git a/src/App/Models/AppOptions.cs b/src/App/Models/AppOptions.cs index 8469f4957..c772714b6 100644 --- a/src/App/Models/AppOptions.cs +++ b/src/App/Models/AppOptions.cs @@ -18,5 +18,6 @@ namespace Bit.App.Models public string SaveCardExpMonth { get; set; } public string SaveCardExpYear { get; set; } public string SaveCardCode { get; set; } + public bool EmptyApp { get; set; } } } diff --git a/src/App/Pages/Accounts/LockPageViewModel.cs b/src/App/Pages/Accounts/LockPageViewModel.cs index 6d5dce8f7..1361cfc96 100644 --- a/src/App/Pages/Accounts/LockPageViewModel.cs +++ b/src/App/Pages/Accounts/LockPageViewModel.cs @@ -16,7 +16,7 @@ namespace Bit.App.Pages { private readonly IPlatformUtilsService _platformUtilsService; private readonly IDeviceActionService _deviceActionService; - private readonly ILockService _lockService; + private readonly IVaultTimeoutService _vaultTimeoutService; private readonly ICryptoService _cryptoService; private readonly IStorageService _storageService; private readonly IUserService _userService; @@ -39,7 +39,7 @@ namespace Bit.App.Pages { _platformUtilsService = ServiceContainer.Resolve("platformUtilsService"); _deviceActionService = ServiceContainer.Resolve("deviceActionService"); - _lockService = ServiceContainer.Resolve("lockService"); + _vaultTimeoutService = ServiceContainer.Resolve("vaultTimeoutService"); _cryptoService = ServiceContainer.Resolve("cryptoService"); _storageService = ServiceContainer.Resolve("storageService"); _userService = ServiceContainer.Resolve("userService"); @@ -102,9 +102,9 @@ namespace Bit.App.Pages public async Task InitAsync(bool autoPromptFingerprint) { - _pinSet = await _lockService.IsPinLockSetAsync(); - PinLock = (_pinSet.Item1 && _lockService.PinProtectedKey != null) || _pinSet.Item2; - FingerprintLock = await _lockService.IsFingerprintLockSetAsync(); + _pinSet = await _vaultTimeoutService.IsPinLockSetAsync(); + PinLock = (_pinSet.Item1 && _vaultTimeoutService.PinProtectedKey != null) || _pinSet.Item2; + FingerprintLock = await _vaultTimeoutService.IsFingerprintLockSetAsync(); _email = await _userService.GetEmailAsync(); var webVault = _environmentService.GetWebVaultUrl(); if (string.IsNullOrWhiteSpace(webVault)) @@ -180,7 +180,7 @@ namespace Bit.App.Pages { var key = await _cryptoService.MakeKeyFromPinAsync(Pin, _email, kdf.GetValueOrDefault(KdfType.PBKDF2_SHA256), kdfIterations.GetValueOrDefault(5000), - _lockService.PinProtectedKey); + _vaultTimeoutService.PinProtectedKey); var encKey = await _cryptoService.GetEncKeyAsync(key); var protectedPin = await _storageService.GetAsync(Constants.ProtectedPin); var decPin = await _cryptoService.DecryptToUtf8Async(new CipherString(protectedPin), encKey); @@ -240,7 +240,7 @@ namespace Bit.App.Pages var decPin = await _cryptoService.DecryptToUtf8Async(new CipherString(protectedPin), encKey); var pinKey = await _cryptoService.MakePinKeyAysnc(decPin, _email, kdf.GetValueOrDefault(KdfType.PBKDF2_SHA256), kdfIterations.GetValueOrDefault(5000)); - _lockService.PinProtectedKey = await _cryptoService.EncryptAsync(key.Key, pinKey); + _vaultTimeoutService.PinProtectedKey = await _cryptoService.EncryptAsync(key.Key, pinKey); } MasterPassword = string.Empty; await SetKeyAndContinueAsync(key); @@ -290,7 +290,7 @@ namespace Bit.App.Pages page.MasterPasswordEntry.Focus(); } }); - _lockService.FingerprintLocked = !success; + _vaultTimeoutService.FingerprintLocked = !success; if (success) { await DoContinueAsync(); @@ -309,7 +309,7 @@ namespace Bit.App.Pages private async Task DoContinueAsync() { - _lockService.FingerprintLocked = false; + _vaultTimeoutService.FingerprintLocked = false; var disableFavicon = await _storageService.GetAsync(Constants.DisableFaviconKey); await _stateService.SaveAsync(Constants.DisableFaviconKey, disableFavicon.GetValueOrDefault()); _messagingService.Send("unlocked"); diff --git a/src/App/Pages/Accounts/LoginPage.xaml b/src/App/Pages/Accounts/LoginPage.xaml index 340fd0731..3c8677d1a 100644 --- a/src/App/Pages/Accounts/LoginPage.xaml +++ b/src/App/Pages/Accounts/LoginPage.xaml @@ -73,8 +73,8 @@ AutomationProperties.Name="{u:I18n ToggleVisibility}" /> - - + +