From c1748acf397667fb84aa842c806f2f76f55edda5 Mon Sep 17 00:00:00 2001 From: Matt Portune <59324545+mportune-bw@users.noreply.github.com> Date: Thu, 17 Mar 2022 14:27:01 -0400 Subject: [PATCH] Misc fixes for account switching (#1849) * Misc fixes for account switching * use unique bio integrity key in ShareExtension --- src/Android/Services/DeviceActionService.cs | 5 +++++ src/App/Abstractions/IDeviceActionService.cs | 1 + src/App/App.xaml.cs | 3 ++- src/App/Services/MobileStorageService.cs | 2 ++ src/App/Utilities/AppHelpers.cs | 2 ++ src/Core/Constants.cs | 5 ++++- src/iOS.Core/Services/DeviceActionService.cs | 5 +++++ src/iOS.Core/Utilities/ASHelpers.cs | 4 ++++ src/iOS.ShareExtension/LoadingViewController.cs | 4 ++-- src/iOS.ShareExtension/LockPasswordViewController.cs | 2 +- src/iOS/AppDelegate.cs | 11 ++--------- 11 files changed, 30 insertions(+), 14 deletions(-) diff --git a/src/Android/Services/DeviceActionService.cs b/src/Android/Services/DeviceActionService.cs index 4a3e52d22..11ef29774 100644 --- a/src/Android/Services/DeviceActionService.cs +++ b/src/Android/Services/DeviceActionService.cs @@ -943,5 +943,10 @@ namespace Bit.Droid.Services var activity = CrossCurrentActivity.Current?.Activity as MainActivity; return activity?.Resources?.Configuration?.FontScale ?? 1; } + + public async Task OnAccountSwitchCompleteAsync() + { + // for any Android-specific cleanup required after switching accounts + } } } diff --git a/src/App/Abstractions/IDeviceActionService.cs b/src/App/Abstractions/IDeviceActionService.cs index ea54a7b44..ad267f7ab 100644 --- a/src/App/Abstractions/IDeviceActionService.cs +++ b/src/App/Abstractions/IDeviceActionService.cs @@ -46,5 +46,6 @@ namespace Bit.App.Abstractions void CloseMainApp(); bool SupportsFido2(); float GetSystemFontSizeScale(); + Task OnAccountSwitchCompleteAsync(); } } diff --git a/src/App/App.xaml.cs b/src/App/App.xaml.cs index 50ce388b6..f51974df2 100644 --- a/src/App/App.xaml.cs +++ b/src/App/App.xaml.cs @@ -428,7 +428,7 @@ namespace Bit.App }); } - private async Task LockedAsync(string userId, bool autoPromptBiometric) + private async Task LockedAsync(string userId, bool userInitiated) { if (!await _stateService.IsActiveAccountAsync(userId)) { @@ -436,6 +436,7 @@ namespace Bit.App return; } + var autoPromptBiometric = !userInitiated; if (autoPromptBiometric && Device.RuntimePlatform == Device.iOS) { var vaultTimeout = await _stateService.GetVaultTimeoutAsync(); diff --git a/src/App/Services/MobileStorageService.cs b/src/App/Services/MobileStorageService.cs index 8f506a323..11694bf77 100644 --- a/src/App/Services/MobileStorageService.cs +++ b/src/App/Services/MobileStorageService.cs @@ -29,6 +29,8 @@ namespace Bit.App.Services Constants.iOSAutoFillBiometricIntegrityKey, Constants.iOSExtensionClearCiphersCacheKey, Constants.iOSExtensionBiometricIntegrityKey, + Constants.iOSShareExtensionClearCiphersCacheKey, + Constants.iOSShareExtensionBiometricIntegrityKey, Constants.RememberedEmailKey, Constants.RememberedOrgIdentifierKey, }; diff --git a/src/App/Utilities/AppHelpers.cs b/src/App/Utilities/AppHelpers.cs index be90e364a..d795fcf98 100644 --- a/src/App/Utilities/AppHelpers.cs +++ b/src/App/Utilities/AppHelpers.cs @@ -556,6 +556,8 @@ namespace Bit.App.Utilities var environmentService = ServiceContainer.Resolve("environmentService"); await environmentService.SetUrlsFromStorageAsync(); await ClearServiceCacheAsync(); + var deviceActionService = ServiceContainer.Resolve("deviceActionService"); + await deviceActionService.OnAccountSwitchCompleteAsync(); } public static async Task ClearServiceCacheAsync() diff --git a/src/Core/Constants.cs b/src/Core/Constants.cs index 119588bdf..cfdec4eee 100644 --- a/src/Core/Constants.cs +++ b/src/Core/Constants.cs @@ -23,6 +23,8 @@ public static string iOSAutoFillBiometricIntegrityKey = "iOSAutoFillBiometricIntegrityState"; public static string iOSExtensionClearCiphersCacheKey = "iOSExtensionClearCiphersCache"; public static string iOSExtensionBiometricIntegrityKey = "iOSExtensionBiometricIntegrityState"; + public static string iOSShareExtensionClearCiphersCacheKey = "iOSShareExtensionClearCiphersCache"; + public static string iOSShareExtensionBiometricIntegrityKey = "iOSShareExtensionBiometricIntegrityState"; public static string EventCollectionKey = "eventCollection"; public static string RememberedEmailKey = "rememberedEmail"; public static string RememberedOrgIdentifierKey = "rememberedOrgIdentifier"; @@ -39,7 +41,8 @@ { ClearCiphersCacheKey, iOSAutoFillClearCiphersCacheKey, - iOSExtensionClearCiphersCacheKey + iOSExtensionClearCiphersCacheKey, + iOSShareExtensionClearCiphersCacheKey }; public static string CiphersKey(string userId) => $"ciphers_{userId}"; diff --git a/src/iOS.Core/Services/DeviceActionService.cs b/src/iOS.Core/Services/DeviceActionService.cs index 39e59c9af..5699e5f9b 100644 --- a/src/iOS.Core/Services/DeviceActionService.cs +++ b/src/iOS.Core/Services/DeviceActionService.cs @@ -594,6 +594,11 @@ namespace Bit.iOS.Core.Services return scaledHeight / tempHeight; } + public async Task OnAccountSwitchCompleteAsync() + { + await ASHelpers.ReplaceAllIdentities(); + } + public class PickerDelegate : UIDocumentPickerDelegate { private readonly DeviceActionService _deviceActionService; diff --git a/src/iOS.Core/Utilities/ASHelpers.cs b/src/iOS.Core/Utilities/ASHelpers.cs index 74c7665a9..dfee195c7 100644 --- a/src/iOS.Core/Utilities/ASHelpers.cs +++ b/src/iOS.Core/Utilities/ASHelpers.cs @@ -20,11 +20,13 @@ namespace Bit.iOS.Core.Utilities var timeoutAction = await stateService.GetVaultTimeoutActionAsync(); if (timeoutAction == VaultTimeoutAction.Logout) { + await ASCredentialIdentityStore.SharedStore?.RemoveAllCredentialIdentitiesAsync(); return; } var vaultTimeoutService = ServiceContainer.Resolve("vaultTimeoutService"); if (await vaultTimeoutService.IsLockedAsync()) { + await ASCredentialIdentityStore.SharedStore?.RemoveAllCredentialIdentitiesAsync(); await storageService.SaveAsync(Constants.AutofillNeedsIdentityReplacementKey, true); return; } @@ -43,7 +45,9 @@ namespace Bit.iOS.Core.Utilities { await ASCredentialIdentityStore.SharedStore?.ReplaceCredentialIdentitiesAsync(identities.ToArray()); await storageService.SaveAsync(Constants.AutofillNeedsIdentityReplacementKey, false); + return; } + await ASCredentialIdentityStore.SharedStore?.RemoveAllCredentialIdentitiesAsync(); } } diff --git a/src/iOS.ShareExtension/LoadingViewController.cs b/src/iOS.ShareExtension/LoadingViewController.cs index 6a3304f26..c1a15d1cf 100644 --- a/src/iOS.ShareExtension/LoadingViewController.cs +++ b/src/iOS.ShareExtension/LoadingViewController.cs @@ -31,7 +31,7 @@ namespace Bit.iOS.ShareExtension private NFCNdefReaderSession _nfcSession = null; private Core.NFCReaderDelegate _nfcDelegate = null; - readonly LazyResolve _stateService = new LazyResolve("stateervice"); + readonly LazyResolve _stateService = new LazyResolve("stateService"); readonly LazyResolve _vaultTimeoutService = new LazyResolve("vaultTimeoutService"); readonly LazyResolve _deviceActionService = new LazyResolve("deviceActionService"); readonly LazyResolve _eventService = new LazyResolve("eventService"); @@ -215,7 +215,7 @@ namespace Bit.iOS.ShareExtension iOSCoreHelpers.RegisterLocalServices(); var messagingService = ServiceContainer.Resolve("messagingService"); ServiceContainer.Init(_deviceActionService.Value.DeviceUserAgent, - Bit.Core.Constants.iOSExtensionClearCiphersCacheKey, Bit.Core.Constants.iOSAllClearCipherCacheKeys); + Bit.Core.Constants.iOSShareExtensionClearCiphersCacheKey, Bit.Core.Constants.iOSAllClearCipherCacheKeys); if (!_initedAppCenter) { iOSCoreHelpers.RegisterAppCenter(); diff --git a/src/iOS.ShareExtension/LockPasswordViewController.cs b/src/iOS.ShareExtension/LockPasswordViewController.cs index 9ac9cfc36..7a1b599f7 100644 --- a/src/iOS.ShareExtension/LockPasswordViewController.cs +++ b/src/iOS.ShareExtension/LockPasswordViewController.cs @@ -9,7 +9,7 @@ namespace Bit.iOS.ShareExtension public LockPasswordViewController(IntPtr handle) : base(handle) { - BiometricIntegrityKey = Bit.Core.Constants.iOSExtensionBiometricIntegrityKey; + BiometricIntegrityKey = Bit.Core.Constants.iOSShareExtensionBiometricIntegrityKey; DismissModalAction = Cancel; } diff --git a/src/iOS/AppDelegate.cs b/src/iOS/AppDelegate.cs index aeedeec98..7de023dc7 100644 --- a/src/iOS/AppDelegate.cs +++ b/src/iOS/AppDelegate.cs @@ -146,12 +146,7 @@ namespace Bit.iOS { if (_deviceActionService.SystemMajorVersion() >= 12) { - var extras = message.Data as Tuple; - var userId = extras?.Item1; - var userInitiated = extras?.Item2; - var expired = extras?.Item3; - // TODO make specific to userId - // await ASCredentialIdentityStore.SharedStore?.RemoveAllCredentialIdentitiesAsync(); + await ASCredentialIdentityStore.SharedStore?.RemoveAllCredentialIdentitiesAsync(); } } else if ((message.Command == "softDeletedCipher" || message.Command == "restoredCipher") @@ -164,9 +159,7 @@ namespace Bit.iOS var timeoutAction = await _stateService.GetVaultTimeoutActionAsync(); if (timeoutAction == VaultTimeoutAction.Logout) { - var userId = await _stateService.GetActiveUserIdAsync(); - // TODO make specific to userId - // await ASCredentialIdentityStore.SharedStore?.RemoveAllCredentialIdentitiesAsync(); + await ASCredentialIdentityStore.SharedStore?.RemoveAllCredentialIdentitiesAsync(); } else {