mirror of
https://github.com/bitwarden/android.git
synced 2024-12-25 10:28:28 +03:00
fixed issues with logging out inactive accounts (#1836)
This commit is contained in:
parent
ad7c656868
commit
5008e1daa8
3 changed files with 37 additions and 52 deletions
|
@ -502,41 +502,25 @@ namespace Bit.App.Utilities
|
||||||
|
|
||||||
public static async Task LogOutAsync(string userId, bool userInitiated = false)
|
public static async Task LogOutAsync(string userId, bool userInitiated = false)
|
||||||
{
|
{
|
||||||
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 passwordGenerationService = ServiceContainer.Resolve<IPasswordGenerationService>(
|
|
||||||
"passwordGenerationService");
|
|
||||||
var vaultTimeoutService = ServiceContainer.Resolve<IVaultTimeoutService>("vaultTimeoutService");
|
|
||||||
var stateService = ServiceContainer.Resolve<IStateService>("stateService");
|
var stateService = ServiceContainer.Resolve<IStateService>("stateService");
|
||||||
var deviceActionService = ServiceContainer.Resolve<IDeviceActionService>("deviceActionService");
|
var vaultTimeoutService = ServiceContainer.Resolve<IVaultTimeoutService>("vaultTimeoutService");
|
||||||
var policyService = ServiceContainer.Resolve<IPolicyService>("policyService");
|
|
||||||
var searchService = ServiceContainer.Resolve<ISearchService>("searchService");
|
|
||||||
|
|
||||||
var isActiveAccount = await stateService.IsActiveAccountAsync(userId);
|
var isActiveAccount = await stateService.IsActiveAccountAsync(userId);
|
||||||
|
|
||||||
|
var isAccountRemoval = await vaultTimeoutService.IsLoggedOutByTimeoutAsync(userId) ||
|
||||||
|
await vaultTimeoutService.ShouldLogOutByTimeoutAsync(userId);
|
||||||
|
|
||||||
if (userId == null)
|
if (userId == null)
|
||||||
{
|
{
|
||||||
userId = await stateService.GetActiveUserIdAsync();
|
userId = await stateService.GetActiveUserIdAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
await Task.WhenAll(
|
await stateService.LogoutAccountAsync(userId, userInitiated);
|
||||||
cipherService.ClearAsync(userId),
|
|
||||||
folderService.ClearAsync(userId),
|
|
||||||
collectionService.ClearAsync(userId),
|
|
||||||
passwordGenerationService.ClearAsync(userId),
|
|
||||||
deviceActionService.ClearCacheAsync(),
|
|
||||||
tokenService.ClearTokenAsync(userId),
|
|
||||||
cryptoService.ClearKeysAsync(userId),
|
|
||||||
settingsService.ClearAsync(userId),
|
|
||||||
vaultTimeoutService.ClearAsync(userId),
|
|
||||||
policyService.ClearAsync(userId),
|
|
||||||
stateService.LogoutAccountAsync(userId, userInitiated));
|
|
||||||
|
|
||||||
searchService.ClearIndex();
|
if (isActiveAccount)
|
||||||
|
{
|
||||||
|
await ClearServiceCacheAsync();
|
||||||
|
}
|
||||||
|
|
||||||
if (!userInitiated)
|
if (!userInitiated)
|
||||||
{
|
{
|
||||||
|
@ -558,8 +542,7 @@ namespace Bit.App.Utilities
|
||||||
if (!isActiveAccount)
|
if (!isActiveAccount)
|
||||||
{
|
{
|
||||||
var platformUtilsService = ServiceContainer.Resolve<IPlatformUtilsService>("platformUtilsService");
|
var platformUtilsService = ServiceContainer.Resolve<IPlatformUtilsService>("platformUtilsService");
|
||||||
if (await vaultTimeoutService.IsLoggedOutByTimeoutAsync(userId) ||
|
if (isAccountRemoval)
|
||||||
await vaultTimeoutService.ShouldLogOutByTimeoutAsync())
|
|
||||||
{
|
{
|
||||||
platformUtilsService.ShowToast("info", null, AppResources.AccountRemovedSuccessfully);
|
platformUtilsService.ShowToast("info", null, AppResources.AccountRemovedSuccessfully);
|
||||||
return;
|
return;
|
||||||
|
@ -571,6 +554,12 @@ namespace Bit.App.Utilities
|
||||||
public static async Task OnAccountSwitchAsync()
|
public static async Task OnAccountSwitchAsync()
|
||||||
{
|
{
|
||||||
var environmentService = ServiceContainer.Resolve<IEnvironmentService>("environmentService");
|
var environmentService = ServiceContainer.Resolve<IEnvironmentService>("environmentService");
|
||||||
|
await environmentService.SetUrlsFromStorageAsync();
|
||||||
|
await ClearServiceCacheAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static async Task ClearServiceCacheAsync()
|
||||||
|
{
|
||||||
var tokenService = ServiceContainer.Resolve<ITokenService>("tokenService");
|
var tokenService = ServiceContainer.Resolve<ITokenService>("tokenService");
|
||||||
var cryptoService = ServiceContainer.Resolve<ICryptoService>("cryptoService");
|
var cryptoService = ServiceContainer.Resolve<ICryptoService>("cryptoService");
|
||||||
var settingsService = ServiceContainer.Resolve<ISettingsService>("settingsService");
|
var settingsService = ServiceContainer.Resolve<ISettingsService>("settingsService");
|
||||||
|
@ -584,8 +573,6 @@ namespace Bit.App.Utilities
|
||||||
var policyService = ServiceContainer.Resolve<IPolicyService>("policyService");
|
var policyService = ServiceContainer.Resolve<IPolicyService>("policyService");
|
||||||
var searchService = ServiceContainer.Resolve<ISearchService>("searchService");
|
var searchService = ServiceContainer.Resolve<ISearchService>("searchService");
|
||||||
|
|
||||||
await environmentService.SetUrlsFromStorageAsync();
|
|
||||||
|
|
||||||
await Task.WhenAll(
|
await Task.WhenAll(
|
||||||
cipherService.ClearCacheAsync(),
|
cipherService.ClearCacheAsync(),
|
||||||
deviceActionService.ClearCacheAsync());
|
deviceActionService.ClearCacheAsync());
|
||||||
|
|
|
@ -63,8 +63,8 @@ namespace Bit.Core.Abstractions
|
||||||
Task SetVaultTimeoutAsync(int? value, string userId = null);
|
Task SetVaultTimeoutAsync(int? value, string userId = null);
|
||||||
Task<VaultTimeoutAction?> GetVaultTimeoutActionAsync(string userId = null);
|
Task<VaultTimeoutAction?> GetVaultTimeoutActionAsync(string userId = null);
|
||||||
Task SetVaultTimeoutActionAsync(VaultTimeoutAction? value, string userId = null);
|
Task SetVaultTimeoutActionAsync(VaultTimeoutAction? value, string userId = null);
|
||||||
Task<DateTime?> GetLastFileCacheClearAsync(string userId = null);
|
Task<DateTime?> GetLastFileCacheClearAsync();
|
||||||
Task SetLastFileCacheClearAsync(DateTime? value, string userId = null);
|
Task SetLastFileCacheClearAsync(DateTime? value);
|
||||||
Task<PreviousPageInfo> GetPreviousPageInfoAsync(string userId = null);
|
Task<PreviousPageInfo> GetPreviousPageInfoAsync(string userId = null);
|
||||||
Task SetPreviousPageInfoAsync(PreviousPageInfo value, string userId = null);
|
Task SetPreviousPageInfoAsync(PreviousPageInfo value, string userId = null);
|
||||||
Task<int> GetInvalidUnlockAttemptsAsync(string userId = null);
|
Task<int> GetInvalidUnlockAttemptsAsync(string userId = null);
|
||||||
|
|
|
@ -48,7 +48,6 @@ namespace Bit.Core.Services
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
await CheckStateAsync();
|
|
||||||
return userId == await GetActiveUserIdAsync();
|
return userId == await GetActiveUserIdAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -160,8 +159,9 @@ namespace Bit.Core.Services
|
||||||
await CheckStateAsync();
|
await CheckStateAsync();
|
||||||
await RemoveAccountAsync(userId, userInitiated);
|
await RemoveAccountAsync(userId, userInitiated);
|
||||||
|
|
||||||
// If user initiated logout (not vault timeout) find the next user to make active, if any
|
// If user initiated logout (not vault timeout) and ActiveUserId is null after account removal, find the
|
||||||
if (userInitiated && _state?.Accounts != null)
|
// next user to make active, if any
|
||||||
|
if (userInitiated && _state?.ActiveUserId == null && _state?.Accounts != null)
|
||||||
{
|
{
|
||||||
foreach (var account in _state.Accounts)
|
foreach (var account in _state.Accounts)
|
||||||
{
|
{
|
||||||
|
@ -534,20 +534,18 @@ namespace Bit.Core.Services
|
||||||
await SaveAccountAsync(account, reconciledOptions);
|
await SaveAccountAsync(account, reconciledOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<DateTime?> GetLastFileCacheClearAsync(string userId = null)
|
public async Task<DateTime?> GetLastFileCacheClearAsync()
|
||||||
{
|
{
|
||||||
var reconciledOptions = ReconcileOptions(new StorageOptions { UserId = userId },
|
var options = await GetDefaultStorageOptionsAsync();
|
||||||
await GetDefaultStorageOptionsAsync());
|
|
||||||
var key = Constants.LastFileCacheClearKey;
|
var key = Constants.LastFileCacheClearKey;
|
||||||
return await GetValueAsync<DateTime?>(key, reconciledOptions);
|
return await GetValueAsync<DateTime?>(key, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task SetLastFileCacheClearAsync(DateTime? value, string userId = null)
|
public async Task SetLastFileCacheClearAsync(DateTime? value)
|
||||||
{
|
{
|
||||||
var reconciledOptions = ReconcileOptions(new StorageOptions { UserId = userId },
|
var options = await GetDefaultStorageOptionsAsync();
|
||||||
await GetDefaultStorageOptionsAsync());
|
|
||||||
var key = Constants.LastFileCacheClearKey;
|
var key = Constants.LastFileCacheClearKey;
|
||||||
await SetValueAsync(key, value, reconciledOptions);
|
await SetValueAsync(key, value, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<PreviousPageInfo> GetPreviousPageInfoAsync(string userId = null)
|
public async Task<PreviousPageInfo> GetPreviousPageInfoAsync(string userId = null)
|
||||||
|
@ -1204,6 +1202,11 @@ namespace Bit.Core.Services
|
||||||
|
|
||||||
private async Task SetValueGloballyAsync<T>(Func<string, string> keyPrefix, T value, StorageOptions options)
|
private async Task SetValueGloballyAsync<T>(Func<string, string> keyPrefix, T value, StorageOptions options)
|
||||||
{
|
{
|
||||||
|
if (value == null)
|
||||||
|
{
|
||||||
|
// don't remove values globally
|
||||||
|
return;
|
||||||
|
}
|
||||||
await CheckStateAsync();
|
await CheckStateAsync();
|
||||||
if (_state?.Accounts == null)
|
if (_state?.Accounts == null)
|
||||||
{
|
{
|
||||||
|
@ -1246,14 +1249,11 @@ namespace Bit.Core.Services
|
||||||
}
|
}
|
||||||
|
|
||||||
// Storage
|
// Storage
|
||||||
_state = await GetStateFromStorageAsync();
|
var state = await GetStateFromStorageAsync();
|
||||||
if (_state?.Accounts?.ContainsKey(options.UserId) ?? false)
|
if (state?.Accounts?.ContainsKey(options.UserId) ?? false)
|
||||||
{
|
{
|
||||||
if (_state.Accounts[options.UserId].VolatileData == null)
|
state.Accounts[options.UserId].VolatileData = new Account.AccountVolatileData();
|
||||||
{
|
return state.Accounts[options.UserId];
|
||||||
_state.Accounts[options.UserId].VolatileData = new Account.AccountVolatileData();
|
|
||||||
}
|
|
||||||
return _state.Accounts[options.UserId];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
@ -1321,8 +1321,7 @@ namespace Bit.Core.Services
|
||||||
{
|
{
|
||||||
_state.Accounts[userId].Tokens.AccessToken = null;
|
_state.Accounts[userId].Tokens.AccessToken = null;
|
||||||
_state.Accounts[userId].Tokens.RefreshToken = null;
|
_state.Accounts[userId].Tokens.RefreshToken = null;
|
||||||
_state.Accounts[userId].VolatileData.Key = null;
|
_state.Accounts[userId].VolatileData = null;
|
||||||
_state.Accounts[userId].VolatileData.BiometricLocked = null;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (userInitiated && _state?.ActiveUserId == userId)
|
if (userInitiated && _state?.ActiveUserId == userId)
|
||||||
|
@ -1366,7 +1365,6 @@ namespace Bit.Core.Services
|
||||||
await SetOrgKeysEncryptedAsync(null, userId);
|
await SetOrgKeysEncryptedAsync(null, userId);
|
||||||
await SetPrivateKeyEncryptedAsync(null, userId);
|
await SetPrivateKeyEncryptedAsync(null, userId);
|
||||||
await SetLastActiveTimeAsync(null, userId);
|
await SetLastActiveTimeAsync(null, userId);
|
||||||
await SetLastFileCacheClearAsync(null, userId);
|
|
||||||
await SetPreviousPageInfoAsync(null, userId);
|
await SetPreviousPageInfoAsync(null, userId);
|
||||||
await SetInvalidUnlockAttemptsAsync(null, userId);
|
await SetInvalidUnlockAttemptsAsync(null, userId);
|
||||||
await SetLocalDataAsync(null, userId);
|
await SetLocalDataAsync(null, userId);
|
||||||
|
|
Loading…
Reference in a new issue