From 9edcc8b4f7f96abaaa5576eba59a23c984070501 Mon Sep 17 00:00:00 2001 From: Federico Maccaroni Date: Wed, 19 Jun 2024 08:57:04 -0300 Subject: [PATCH] [AC-2788] Remove unassigned items feature flag and logic (#3300) --- src/Core/Abstractions/IApiService.cs | 1 - src/Core/Abstractions/ICipherService.cs | 1 - src/Core/Abstractions/IStateService.cs | 2 - src/Core/Constants.cs | 2 - src/Core/Models/AppOptions.cs | 1 - src/Core/Pages/Accounts/LockPage.xaml.cs | 5 -- .../Accounts/LoginApproveDevicePage.xaml.cs | 5 -- src/Core/Pages/Accounts/LoginPage.xaml.cs | 5 -- .../LoginPasswordlessRequestPage.xaml.cs | 5 -- .../Pages/Accounts/SetPasswordPage.xaml.cs | 5 -- src/Core/Pages/Accounts/TwoFactorPage.xaml.cs | 5 -- src/Core/Pages/TabsPage.cs | 2 +- .../Vault/GroupingsPage/GroupingsPage.xaml.cs | 5 +- .../GroupingsPage/GroupingsPageViewModel.cs | 59 ------------------- .../Localization/AppResources.Designer.cs | 36 ----------- .../Resources/Localization/AppResources.resx | 12 ---- src/Core/Services/ApiService.cs | 5 -- src/Core/Services/CipherService.cs | 18 ------ src/Core/Services/StateService.cs | 10 ---- 19 files changed, 2 insertions(+), 182 deletions(-) diff --git a/src/Core/Abstractions/IApiService.cs b/src/Core/Abstractions/IApiService.cs index bbd3b9357..313b4dc03 100644 --- a/src/Core/Abstractions/IApiService.cs +++ b/src/Core/Abstractions/IApiService.cs @@ -41,7 +41,6 @@ public interface IApiService Task PutShareCipherAsync(string id, CipherShareRequest request); Task PutDeleteCipherAsync(string id); Task PutRestoreCipherAsync(string id); - Task HasUnassignedCiphersAsync(); Task RefreshIdentityTokenAsync(); Task PreValidateSsoAsync(string identifier); Task SendAsync(HttpMethod method, string path, diff --git a/src/Core/Abstractions/ICipherService.cs b/src/Core/Abstractions/ICipherService.cs index 59c395b44..e769c051a 100644 --- a/src/Core/Abstractions/ICipherService.cs +++ b/src/Core/Abstractions/ICipherService.cs @@ -36,6 +36,5 @@ Task, List, List>> GetAllDecrypte Task RestoreWithServerAsync(string id); Task CreateNewLoginForPasskeyAsync(Fido2ConfirmNewCredentialParams newPasskeyParams); Task CopyTotpCodeIfNeededAsync(CipherView cipher); - Task VerifyOrganizationHasUnassignedItemsAsync(); } } diff --git a/src/Core/Abstractions/IStateService.cs b/src/Core/Abstractions/IStateService.cs index 0afb34da6..44ec8079f 100644 --- a/src/Core/Abstractions/IStateService.cs +++ b/src/Core/Abstractions/IStateService.cs @@ -187,8 +187,6 @@ public interface IStateService Task GetPreAuthRegionAsync(); Task SetPreAuthRegionAsync(BwRegion value); Task ReloadStateAsync(); - Task GetShouldCheckOrganizationUnassignedItemsAsync(string userId = null); - Task SetShouldCheckOrganizationUnassignedItemsAsync(bool shouldCheck, string userId = null); [Obsolete("Use GetPinKeyEncryptedUserKeyAsync instead, left for migration purposes")] Task GetPinProtectedAsync(string userId = null); [Obsolete("Use SetPinKeyEncryptedUserKeyAsync instead, left for migration purposes")] diff --git a/src/Core/Constants.cs b/src/Core/Constants.cs index 5370c3a23..9f483906d 100644 --- a/src/Core/Constants.cs +++ b/src/Core/Constants.cs @@ -45,7 +45,6 @@ public static class Constants public const string PasswordlessLoginRequestKey = "passwordlessLoginRequest"; public const string PreLoginEmailKey = "preLoginEmailKey"; public const string ConfigsKey = "configsKey"; - public const string UnassignedItemsBannerFlag = "unassigned-items-banner"; public const string RegionEnvironment = "regionEnvironment"; public const string DuoCallback = "bitwarden://duo-callback"; public const string NavigateToMessageCommand = "navigateTo"; @@ -138,7 +137,6 @@ public static string AccountBiometricIntegrityValidKey(string userId, string sys public static string ShouldConnectToWatchKey(string userId) => $"shouldConnectToWatch_{userId}"; public static string ScreenCaptureAllowedKey(string userId) => $"screenCaptureAllowed_{userId}"; public static string PendingAdminAuthRequest(string userId) => $"pendingAdminAuthRequest_{userId}"; - public static string ShouldCheckOrganizationUnassignedItemsKey(string userId) => $"shouldCheckOrganizationUnassignedItems_{userId}"; [Obsolete] public static string KeyKey(string userId) => $"key_{userId}"; [Obsolete] diff --git a/src/Core/Models/AppOptions.cs b/src/Core/Models/AppOptions.cs index 6f99f40b9..6682db887 100644 --- a/src/Core/Models/AppOptions.cs +++ b/src/Core/Models/AppOptions.cs @@ -27,7 +27,6 @@ public class AppOptions public bool HideAccountSwitcher { get; set; } public OtpData? OtpData { get; set; } public bool HasUnlockedInThisTransaction { get; set; } - public bool HasJustLoggedInOrUnlocked { get; set; } public void SetAllFrom(AppOptions o) { diff --git a/src/Core/Pages/Accounts/LockPage.xaml.cs b/src/Core/Pages/Accounts/LockPage.xaml.cs index ce45b6eb8..c101c8860 100644 --- a/src/Core/Pages/Accounts/LockPage.xaml.cs +++ b/src/Core/Pages/Accounts/LockPage.xaml.cs @@ -232,11 +232,6 @@ private async Task UnlockedAsync() return; } var previousPage = await AppHelpers.ClearPreviousPage(); - - if (_appOptions != null) - { - _appOptions.HasJustLoggedInOrUnlocked = true; - } App.MainPage = new TabsPage(_appOptions, previousPage); } } diff --git a/src/Core/Pages/Accounts/LoginApproveDevicePage.xaml.cs b/src/Core/Pages/Accounts/LoginApproveDevicePage.xaml.cs index f28be1485..65d212b5a 100644 --- a/src/Core/Pages/Accounts/LoginApproveDevicePage.xaml.cs +++ b/src/Core/Pages/Accounts/LoginApproveDevicePage.xaml.cs @@ -35,11 +35,6 @@ private async Task ContinueToVaultAsync() { return; } - - if (_appOptions != null) - { - _appOptions.HasJustLoggedInOrUnlocked = true; - } var previousPage = await AppHelpers.ClearPreviousPage(); App.MainPage = new TabsPage(_appOptions, previousPage); } diff --git a/src/Core/Pages/Accounts/LoginPage.xaml.cs b/src/Core/Pages/Accounts/LoginPage.xaml.cs index 182cd2bbd..194a67bbf 100644 --- a/src/Core/Pages/Accounts/LoginPage.xaml.cs +++ b/src/Core/Pages/Accounts/LoginPage.xaml.cs @@ -196,11 +196,6 @@ private async Task LogInSuccessAsync() { return; } - - if (_appOptions != null) - { - _appOptions.HasJustLoggedInOrUnlocked = true; - } var previousPage = await AppHelpers.ClearPreviousPage(); App.MainPage = new TabsPage(_appOptions, previousPage); } diff --git a/src/Core/Pages/Accounts/LoginPasswordlessRequestPage.xaml.cs b/src/Core/Pages/Accounts/LoginPasswordlessRequestPage.xaml.cs index c1492e761..41e00ae8e 100644 --- a/src/Core/Pages/Accounts/LoginPasswordlessRequestPage.xaml.cs +++ b/src/Core/Pages/Accounts/LoginPasswordlessRequestPage.xaml.cs @@ -56,11 +56,6 @@ private async Task LogInSuccessAsync() { return; } - - if (_appOptions != null) - { - _appOptions.HasJustLoggedInOrUnlocked = true; - } var previousPage = await AppHelpers.ClearPreviousPage(); App.MainPage = new TabsPage(_appOptions, previousPage); } diff --git a/src/Core/Pages/Accounts/SetPasswordPage.xaml.cs b/src/Core/Pages/Accounts/SetPasswordPage.xaml.cs index 558375dfb..19013dba4 100644 --- a/src/Core/Pages/Accounts/SetPasswordPage.xaml.cs +++ b/src/Core/Pages/Accounts/SetPasswordPage.xaml.cs @@ -71,11 +71,6 @@ private async Task SetPasswordSuccessAsync() { return; } - - if (_appOptions != null) - { - _appOptions.HasJustLoggedInOrUnlocked = true; - } var previousPage = await AppHelpers.ClearPreviousPage(); App.MainPage = new TabsPage(_appOptions, previousPage); } diff --git a/src/Core/Pages/Accounts/TwoFactorPage.xaml.cs b/src/Core/Pages/Accounts/TwoFactorPage.xaml.cs index b6b53e8ea..14cf76be1 100644 --- a/src/Core/Pages/Accounts/TwoFactorPage.xaml.cs +++ b/src/Core/Pages/Accounts/TwoFactorPage.xaml.cs @@ -207,11 +207,6 @@ private async Task TwoFactorAuthSuccessToMainAsync() { return; } - - if (_appOptions != null) - { - _appOptions.HasJustLoggedInOrUnlocked = true; - } var previousPage = await AppHelpers.ClearPreviousPage(); App.MainPage = new TabsPage(_appOptions, previousPage); } diff --git a/src/Core/Pages/TabsPage.cs b/src/Core/Pages/TabsPage.cs index 367d51e22..f37c4ee04 100644 --- a/src/Core/Pages/TabsPage.cs +++ b/src/Core/Pages/TabsPage.cs @@ -33,7 +33,7 @@ public TabsPage(AppOptions appOptions = null, PreviousPageInfo previousPage = nu _keyConnectorService = ServiceContainer.Resolve("keyConnectorService"); _stateService = ServiceContainer.Resolve(); - _groupingsPage = new NavigationPage(new GroupingsPage(true, previousPage: previousPage, appOptions: appOptions)) + _groupingsPage = new NavigationPage(new GroupingsPage(true, previousPage: previousPage)) { Title = AppResources.MyVault, IconImageSource = "lock.png" diff --git a/src/Core/Pages/Vault/GroupingsPage/GroupingsPage.xaml.cs b/src/Core/Pages/Vault/GroupingsPage/GroupingsPage.xaml.cs index dea34cf22..d44bd593b 100644 --- a/src/Core/Pages/Vault/GroupingsPage/GroupingsPage.xaml.cs +++ b/src/Core/Pages/Vault/GroupingsPage/GroupingsPage.xaml.cs @@ -28,7 +28,7 @@ public partial class GroupingsPage : BaseContentPage public GroupingsPage(bool mainPage, CipherType? type = null, string folderId = null, string collectionId = null, string pageTitle = null, string vaultFilterSelection = null, - PreviousPageInfo previousPage = null, bool deleted = false, bool showTotp = false, AppOptions appOptions = null) + PreviousPageInfo previousPage = null, bool deleted = false, bool showTotp = false) { _pageName = string.Concat(nameof(GroupingsPage), "_", DateTime.UtcNow.Ticks); InitializeComponent(); @@ -51,7 +51,6 @@ public GroupingsPage(bool mainPage, CipherType? type = null, string folderId = n _vm.CollectionId = collectionId; _vm.Deleted = deleted; _vm.ShowTotp = showTotp; - _vm.AppOptions = appOptions; _previousPage = previousPage; if (pageTitle != null) { @@ -162,8 +161,6 @@ await LoadOnAppearedAsync(_mainLayout, false, async () => return; } - await _vm.CheckOrganizationUnassignedItemsAsync(); - // Push registration var lastPushRegistration = await _stateService.GetPushLastRegistrationDateAsync(); lastPushRegistration = lastPushRegistration.GetValueOrDefault(DateTime.MinValue); diff --git a/src/Core/Pages/Vault/GroupingsPage/GroupingsPageViewModel.cs b/src/Core/Pages/Vault/GroupingsPage/GroupingsPageViewModel.cs index 4430372b3..0c4a5299b 100644 --- a/src/Core/Pages/Vault/GroupingsPage/GroupingsPageViewModel.cs +++ b/src/Core/Pages/Vault/GroupingsPage/GroupingsPageViewModel.cs @@ -46,8 +46,6 @@ public class GroupingsPageViewModel : VaultFilterViewModel private readonly IPasswordRepromptService _passwordRepromptService; private readonly IOrganizationService _organizationService; private readonly IPolicyService _policyService; - private readonly IConfigService _configService; - private readonly IEnvironmentService _environmentService; private readonly ILogger _logger; public GroupingsPageViewModel() @@ -64,8 +62,6 @@ public GroupingsPageViewModel() _passwordRepromptService = ServiceContainer.Resolve("passwordRepromptService"); _organizationService = ServiceContainer.Resolve("organizationService"); _policyService = ServiceContainer.Resolve("policyService"); - _configService = ServiceContainer.Resolve(); - _environmentService = ServiceContainer.Resolve(); _logger = ServiceContainer.Resolve("logger"); Loading = true; @@ -109,7 +105,6 @@ public GroupingsPageViewModel() public List Collections { get; set; } public List> NestedCollections { get; set; } - public AppOptions AppOptions { get; internal set; } protected override ICipherService cipherService => _cipherService; protected override IPolicyService policyService => _policyService; protected override IOrganizationService organizationService => _organizationService; @@ -705,59 +700,5 @@ private List BuildFolders(List decFolders) var folders = decFolders.Where(f => _allCiphers.Any(c => c.FolderId == f.Id)).ToList(); return folders.Any() ? folders : null; } - - internal async Task CheckOrganizationUnassignedItemsAsync() - { - try - { - if (AppOptions?.HasJustLoggedInOrUnlocked != true) - { - return; - } - - AppOptions.HasJustLoggedInOrUnlocked = false; - - if (!await _configService.GetFeatureFlagBoolAsync(Core.Constants.UnassignedItemsBannerFlag) - || - !await _stateService.GetShouldCheckOrganizationUnassignedItemsAsync()) - { - return; - } - - var waitSyncTask = Task.Run(async () => - { - while (_syncService.SyncInProgress) - { - await Task.Delay(100); - } - }); - await waitSyncTask.WaitAsync(TimeSpan.FromMinutes(5)); - - if (!await _cipherService.VerifyOrganizationHasUnassignedItemsAsync()) - { - return; - } - - var message = _environmentService.SelectedRegion == Core.Enums.Region.SelfHosted - ? AppResources.OrganizationUnassignedItemsMessageSelfHost041624DescriptionLong - : AppResources.OrganizationUnassignedItemsMessageUSEUDescriptionLong; - - var response = await _deviceActionService.DisplayAlertAsync(AppResources.Notice, - message, - null, - AppResources.RemindMeLater, - AppResources.Ok); - - if (response == AppResources.Ok) - { - await _stateService.SetShouldCheckOrganizationUnassignedItemsAsync(false); - } - } - catch (TimeoutException) { } - catch (Exception ex) - { - _logger.Exception(ex); - } - } } } diff --git a/src/Core/Resources/Localization/AppResources.Designer.cs b/src/Core/Resources/Localization/AppResources.Designer.cs index d3d1003a5..fb6b8fd88 100644 --- a/src/Core/Resources/Localization/AppResources.Designer.cs +++ b/src/Core/Resources/Localization/AppResources.Designer.cs @@ -4929,15 +4929,6 @@ public static string NoThanks { } } - /// - /// Looks up a localized string similar to Notice. - /// - public static string Notice { - get { - return ResourceManager.GetString("Notice", resourceCulture); - } - } - /// /// Looks up a localized string similar to This account has two-step login set up, however, none of the configured two-step providers are supported on this device. Please use a supported device and/or add additional providers that are better supported across devices (such as an authenticator app).. /// @@ -5173,24 +5164,6 @@ public static string OrganizationSsoIdentifierRequired { } } - /// - /// Looks up a localized string similar to On May 16, 2024, unassigned organization items will no longer be visible in the All Vaults view and only accessible via the Admin Console. Assign these items to a collection from the Admin Console to make them visible.. - /// - public static string OrganizationUnassignedItemsMessageSelfHost041624DescriptionLong { - get { - return ResourceManager.GetString("OrganizationUnassignedItemsMessageSelfHost041624DescriptionLong", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Unassigned organization items are no longer visible in the All Vaults view and only accessible via the Admin Console. Assign these items to a collection from the Admin Console to make them visible.. - /// - public static string OrganizationUnassignedItemsMessageUSEUDescriptionLong { - get { - return ResourceManager.GetString("OrganizationUnassignedItemsMessageUSEUDescriptionLong", resourceCulture); - } - } - /// /// Looks up a localized string similar to Organization identifier. /// @@ -5876,15 +5849,6 @@ public static string RememberThisDevice { } } - /// - /// Looks up a localized string similar to Remind me later. - /// - public static string RemindMeLater { - get { - return ResourceManager.GetString("RemindMeLater", resourceCulture); - } - } - /// /// Looks up a localized string similar to Remove. /// diff --git a/src/Core/Resources/Localization/AppResources.resx b/src/Core/Resources/Localization/AppResources.resx index b3d0bfb71..0d1bef932 100644 --- a/src/Core/Resources/Localization/AppResources.resx +++ b/src/Core/Resources/Localization/AppResources.resx @@ -2975,18 +2975,6 @@ Do you want to switch to this account? Your passkey will be saved to your Bitwarden vault for {0} - - Unassigned organization items are no longer visible in the All Vaults view and only accessible via the Admin Console. Assign these items to a collection from the Admin Console to make them visible. - - - On May 16, 2024, unassigned organization items will no longer be visible in the All Vaults view and only accessible via the Admin Console. Assign these items to a collection from the Admin Console to make them visible. - - - Remind me later - - - Notice - Passkeys not supported for this app diff --git a/src/Core/Services/ApiService.cs b/src/Core/Services/ApiService.cs index f26de73a4..242f40ff5 100644 --- a/src/Core/Services/ApiService.cs +++ b/src/Core/Services/ApiService.cs @@ -334,11 +334,6 @@ public Task PutRestoreCipherAsync(string id) return SendAsync(HttpMethod.Put, string.Concat("/ciphers/", id, "/restore"), null, true, true); } - public Task HasUnassignedCiphersAsync() - { - return SendAsync(HttpMethod.Get, "/ciphers/has-unassigned-ciphers", null, true, true); - } - #endregion #region Attachments APIs diff --git a/src/Core/Services/CipherService.cs b/src/Core/Services/CipherService.cs index 14054d0c2..f5e7a2b81 100644 --- a/src/Core/Services/CipherService.cs +++ b/src/Core/Services/CipherService.cs @@ -835,24 +835,6 @@ public async Task RestoreWithServerAsync(string id) await ClearCacheAsync(); } - public async Task VerifyOrganizationHasUnassignedItemsAsync() - { - var organizations = await _stateService.GetOrganizationsAsync(); - if (organizations?.Any() != true) - { - return false; - } - - try - { - return await _apiService.HasUnassignedCiphersAsync(); - } - catch (ApiException ex) when (ex.Error?.StatusCode == System.Net.HttpStatusCode.BadRequest) - { - return false; - } - } - // Helpers private async Task> MakeAttachmentKeyAsync(string organizationId, Cipher cipher = null, CipherView cipherView = null) diff --git a/src/Core/Services/StateService.cs b/src/Core/Services/StateService.cs index fbfeb18d3..a6685d391 100644 --- a/src/Core/Services/StateService.cs +++ b/src/Core/Services/StateService.cs @@ -1384,16 +1384,6 @@ public async Task SetPreAuthRegionAsync(BwRegion value) await _storageMediatorService.SaveAsync(Constants.RegionEnvironment, value); } - public async Task GetShouldCheckOrganizationUnassignedItemsAsync(string userId = null) - { - return await _storageMediatorService.GetAsync(await ComposeKeyAsync(Constants.ShouldCheckOrganizationUnassignedItemsKey, userId)) ?? true; - } - - public async Task SetShouldCheckOrganizationUnassignedItemsAsync(bool shouldCheck, string userId = null) - { - await _storageMediatorService.SaveAsync(await ComposeKeyAsync(Constants.ShouldCheckOrganizationUnassignedItemsKey, userId), shouldCheck); - } - // Helpers [Obsolete("Use IStorageMediatorService instead")]