mirror of
https://github.com/bitwarden/mobile
synced 2025-12-30 15:13:24 +00:00
Account Switching (#1807)
* Account Switching (#1720) * Account switching * WIP * wip * wip * updates to send test logic * fixed Send tests * fixes for theme handling on account switching and re-adding existing account * switch fixes * fixes * fixes * cleanup * vault timeout fixes * account list status enhancements * logout fixes and token handling improvements * merge latest (#1727) * remove duplicate dependency * fix for initial login token storage paradox (#1730) * Fix avatar color update toolbar item issue on iOS for account switching (#1735) * Updated account switching menu UI (#1733) * updated account switching menu UI * additional changes * add key suffix to constant * GetFirstLetters method tweaks * Fix crash on account switching when logging out when having more than user at a time (#1740) * single account migration to multi-account on app update (#1741) * Account Switching Tap to dismiss (#1743) * Added tap to dismiss on the Account switching overlay and improved a bit the code * Fix account switching overlay background transparent on the proper place * Fixed transparent background and the shadow on the account switching overlay * Fix iOS top space on Account switching list overlay after modal (#1746) * Fix top space added to Account switching list overlay after closing modal * Fix top space added to Account switching list overlay after closing modal on lock, login and home views just in case we add modals in the future there as well * Usability: dismiss account list on certain events (#1748) * dismiss account list on certain events * use new FireAndForget method for back button logic * Create and use Account Switching overlay control (#1753) * Added Account switching overlay control and its own ViewModel and refactored accordingly * Fix account switching Accounts list binding update * Implemented dismiss account switching overlay when changing tabs and when selecting the same tab. Also updated the deprecated listener on CustomTabbedRenderer on Android (#1755) * Overriden Equals on AvatarImageSource so it doesn't get set multiple times when it's the same image thus producing blinking on tab chaged (#1756) * Usability improvements for logout on vault timeout (#1781) * accountswitching fixes (#1784) * Fix for invalid PIN lock state when switching accounts (#1792) * fix for pin lock flow * named tuple values and updated async * clear send service cache on account switch (#1796) * Global theme and account removal (#1793) * Global theme and account removal * remove redundant call to hide account list overlay * cleanup and additional tweaks * add try/catch to remove account dialog flow Co-authored-by: Federico Maccaroni <fedemkr@gmail.com>
This commit is contained in:
@@ -2,7 +2,6 @@
|
||||
using Bit.App.Abstractions;
|
||||
using Bit.App.Pages;
|
||||
using Bit.App.Resources;
|
||||
using Bit.Core;
|
||||
using Bit.Core.Abstractions;
|
||||
using Bit.Core.Models.View;
|
||||
using Bit.Core.Utilities;
|
||||
@@ -14,6 +13,7 @@ using System.Threading.Tasks;
|
||||
using Bit.App.Models;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Exceptions;
|
||||
using Bit.Core.Models.Data;
|
||||
using Newtonsoft.Json;
|
||||
using Xamarin.Essentials;
|
||||
using Xamarin.Forms;
|
||||
@@ -46,8 +46,8 @@ namespace Bit.App.Utilities
|
||||
}
|
||||
if (!string.IsNullOrWhiteSpace(cipher.Login.Totp))
|
||||
{
|
||||
var userService = ServiceContainer.Resolve<IUserService>("userService");
|
||||
var canAccessPremium = await userService.CanAccessPremiumAsync();
|
||||
var stateService = ServiceContainer.Resolve<IStateService>("stateService");
|
||||
var canAccessPremium = await stateService.CanAccessPremiumAsync();
|
||||
if (canAccessPremium || cipher.OrganizationUseTotp)
|
||||
{
|
||||
options.Add(AppResources.CopyTotp);
|
||||
@@ -330,33 +330,15 @@ namespace Bit.App.Utilities
|
||||
}
|
||||
|
||||
public static async Task<bool> PerformUpdateTasksAsync(ISyncService syncService,
|
||||
IDeviceActionService deviceActionService, IStorageService storageService)
|
||||
IDeviceActionService deviceActionService, IStateService stateService)
|
||||
{
|
||||
var currentBuild = deviceActionService.GetBuildNumber();
|
||||
var lastBuild = await storageService.GetAsync<string>(Constants.LastBuildKey);
|
||||
if (lastBuild == null)
|
||||
{
|
||||
// Installed
|
||||
var currentTimeout = await storageService.GetAsync<int?>(Constants.VaultTimeoutKey);
|
||||
if (currentTimeout == null)
|
||||
{
|
||||
await storageService.SaveAsync(Constants.VaultTimeoutKey, 15);
|
||||
}
|
||||
|
||||
var currentAction = await storageService.GetAsync<string>(Constants.VaultTimeoutActionKey);
|
||||
if (currentAction == null)
|
||||
{
|
||||
await storageService.SaveAsync(Constants.VaultTimeoutActionKey, "lock");
|
||||
}
|
||||
}
|
||||
else if (lastBuild != currentBuild)
|
||||
var lastBuild = await stateService.GetLastBuildAsync();
|
||||
if (lastBuild == null || lastBuild != currentBuild)
|
||||
{
|
||||
// Updated
|
||||
var tasks = Task.Run(() => syncService.FullSyncAsync(true));
|
||||
}
|
||||
if (lastBuild != currentBuild)
|
||||
{
|
||||
await storageService.SaveAsync(Constants.LastBuildKey, currentBuild);
|
||||
await stateService.SetLastBuildAsync(currentBuild);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -418,35 +400,34 @@ namespace Bit.App.Utilities
|
||||
|
||||
public static async Task<PreviousPageInfo> ClearPreviousPage()
|
||||
{
|
||||
var storageService = ServiceContainer.Resolve<IStorageService>("storageService");
|
||||
var previousPage = await storageService.GetAsync<PreviousPageInfo>(Constants.PreviousPageKey);
|
||||
var stateService = ServiceContainer.Resolve<IStateService>("stateService");
|
||||
var previousPage = await stateService.GetPreviousPageInfoAsync();
|
||||
if (previousPage != null)
|
||||
{
|
||||
await storageService.RemoveAsync(Constants.PreviousPageKey);
|
||||
await stateService.SetPreviousPageInfoAsync(null);
|
||||
}
|
||||
return previousPage;
|
||||
}
|
||||
|
||||
public static async Task<int> IncrementInvalidUnlockAttemptsAsync()
|
||||
{
|
||||
var storageService = ServiceContainer.Resolve<IStorageService>("storageService");
|
||||
var invalidUnlockAttempts = await storageService.GetAsync<int>(Constants.InvalidUnlockAttempts);
|
||||
var stateService = ServiceContainer.Resolve<IStateService>("stateService");
|
||||
var invalidUnlockAttempts = await stateService.GetInvalidUnlockAttemptsAsync();
|
||||
invalidUnlockAttempts++;
|
||||
await storageService.SaveAsync(Constants.InvalidUnlockAttempts, invalidUnlockAttempts);
|
||||
await stateService.SetInvalidUnlockAttemptsAsync(invalidUnlockAttempts);
|
||||
return invalidUnlockAttempts;
|
||||
}
|
||||
|
||||
public static async Task ResetInvalidUnlockAttemptsAsync()
|
||||
{
|
||||
var storageService = ServiceContainer.Resolve<IStorageService>("storageService");
|
||||
await storageService.RemoveAsync(Constants.InvalidUnlockAttempts);
|
||||
var stateService = ServiceContainer.Resolve<IStateService>("stateService");
|
||||
await stateService.SetInvalidUnlockAttemptsAsync(null);
|
||||
}
|
||||
|
||||
public static async Task<bool> IsVaultTimeoutImmediateAsync()
|
||||
{
|
||||
var storageService = ServiceContainer.Resolve<IStorageService>("storageService");
|
||||
|
||||
var vaultTimeoutMinutes = await storageService.GetAsync<int?>(Constants.VaultTimeoutKey);
|
||||
var stateService = ServiceContainer.Resolve<IStateService>("stateService");
|
||||
var vaultTimeoutMinutes = await stateService.GetVaultTimeoutAsync();
|
||||
if (vaultTimeoutMinutes.GetValueOrDefault(-1) == 0)
|
||||
{
|
||||
return true;
|
||||
@@ -466,10 +447,8 @@ namespace Bit.App.Utilities
|
||||
return Convert.ToBase64String(Encoding.UTF8.GetBytes(multiByteEscaped));
|
||||
}
|
||||
|
||||
public static async Task LogOutAsync()
|
||||
public static async Task LogOutAsync(string userId, bool userInitiated = false)
|
||||
{
|
||||
var userService = ServiceContainer.Resolve<IUserService>("userService");
|
||||
var syncService = ServiceContainer.Resolve<ISyncService>("syncService");
|
||||
var tokenService = ServiceContainer.Resolve<ITokenService>("tokenService");
|
||||
var cryptoService = ServiceContainer.Resolve<ICryptoService>("cryptoService");
|
||||
var settingsService = ServiceContainer.Resolve<ISettingsService>("settingsService");
|
||||
@@ -481,23 +460,70 @@ namespace Bit.App.Utilities
|
||||
var vaultTimeoutService = ServiceContainer.Resolve<IVaultTimeoutService>("vaultTimeoutService");
|
||||
var stateService = ServiceContainer.Resolve<IStateService>("stateService");
|
||||
var deviceActionService = ServiceContainer.Resolve<IDeviceActionService>("deviceActionService");
|
||||
var policyService = ServiceContainer.Resolve<IPolicyService>("policyService");
|
||||
var searchService = ServiceContainer.Resolve<ISearchService>("searchService");
|
||||
|
||||
var userId = await userService.GetUserIdAsync();
|
||||
if (userId == null)
|
||||
{
|
||||
userId = await stateService.GetActiveUserIdAsync();
|
||||
}
|
||||
|
||||
await Task.WhenAll(
|
||||
syncService.SetLastSyncAsync(DateTime.MinValue),
|
||||
tokenService.ClearTokenAsync(),
|
||||
cryptoService.ClearKeysAsync(),
|
||||
userService.ClearAsync(),
|
||||
settingsService.ClearAsync(userId),
|
||||
cipherService.ClearAsync(userId),
|
||||
folderService.ClearAsync(userId),
|
||||
collectionService.ClearAsync(userId),
|
||||
passwordGenerationService.ClearAsync(),
|
||||
vaultTimeoutService.ClearAsync(),
|
||||
stateService.PurgeAsync(),
|
||||
passwordGenerationService.ClearAsync(userId),
|
||||
deviceActionService.ClearCacheAsync(),
|
||||
tokenService.ClearTokenAsync(userId),
|
||||
cryptoService.ClearKeysAsync(userId),
|
||||
settingsService.ClearAsync(userId),
|
||||
vaultTimeoutService.ClearAsync(userId),
|
||||
policyService.ClearAsync(userId),
|
||||
stateService.LogoutAccountAsync(userId, userInitiated));
|
||||
|
||||
stateService.BiometricLocked = true;
|
||||
searchService.ClearIndex();
|
||||
|
||||
// check if we switched accounts automatically
|
||||
if (userInitiated && await stateService.GetActiveUserIdAsync() != null)
|
||||
{
|
||||
var messagingService = ServiceContainer.Resolve<IMessagingService>("messagingService");
|
||||
messagingService.Send("switchedAccount");
|
||||
|
||||
var platformUtilsService = ServiceContainer.Resolve<IPlatformUtilsService>("platformUtilsService");
|
||||
platformUtilsService.ShowToast("info", null, AppResources.AccountSwitchedAutomatically);
|
||||
}
|
||||
}
|
||||
|
||||
public static async Task OnAccountSwitchAsync()
|
||||
{
|
||||
var environmentService = ServiceContainer.Resolve<IEnvironmentService>("environmentService");
|
||||
var tokenService = ServiceContainer.Resolve<ITokenService>("tokenService");
|
||||
var cryptoService = ServiceContainer.Resolve<ICryptoService>("cryptoService");
|
||||
var settingsService = ServiceContainer.Resolve<ISettingsService>("settingsService");
|
||||
var cipherService = ServiceContainer.Resolve<ICipherService>("cipherService");
|
||||
var folderService = ServiceContainer.Resolve<IFolderService>("folderService");
|
||||
var collectionService = ServiceContainer.Resolve<ICollectionService>("collectionService");
|
||||
var sendService = ServiceContainer.Resolve<ISendService>("sendService");
|
||||
var passwordGenerationService = ServiceContainer.Resolve<IPasswordGenerationService>(
|
||||
"passwordGenerationService");
|
||||
var deviceActionService = ServiceContainer.Resolve<IDeviceActionService>("deviceActionService");
|
||||
var policyService = ServiceContainer.Resolve<IPolicyService>("policyService");
|
||||
var searchService = ServiceContainer.Resolve<ISearchService>("searchService");
|
||||
|
||||
await environmentService.SetUrlsFromStorageAsync();
|
||||
|
||||
await Task.WhenAll(
|
||||
cipherService.ClearCacheAsync(),
|
||||
deviceActionService.ClearCacheAsync());
|
||||
vaultTimeoutService.BiometricLocked = true;
|
||||
tokenService.ClearCache();
|
||||
cryptoService.ClearCache();
|
||||
settingsService.ClearCache();
|
||||
folderService.ClearCache();
|
||||
collectionService.ClearCache();
|
||||
sendService.ClearCache();
|
||||
passwordGenerationService.ClearCache();
|
||||
policyService.ClearCache();
|
||||
searchService.ClearIndex();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user