fixed issues with logging out inactive accounts (#1836)

This commit is contained in:
Matt Portune 2022-03-10 09:02:01 -05:00 committed by GitHub
parent ad7c656868
commit 5008e1daa8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 37 additions and 52 deletions

View file

@ -502,41 +502,25 @@ namespace Bit.App.Utilities
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 deviceActionService = ServiceContainer.Resolve<IDeviceActionService>("deviceActionService");
var policyService = ServiceContainer.Resolve<IPolicyService>("policyService");
var searchService = ServiceContainer.Resolve<ISearchService>("searchService");
var vaultTimeoutService = ServiceContainer.Resolve<IVaultTimeoutService>("vaultTimeoutService");
var isActiveAccount = await stateService.IsActiveAccountAsync(userId);
var isAccountRemoval = await vaultTimeoutService.IsLoggedOutByTimeoutAsync(userId) ||
await vaultTimeoutService.ShouldLogOutByTimeoutAsync(userId);
if (userId == null)
{
userId = await stateService.GetActiveUserIdAsync();
}
await Task.WhenAll(
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));
await stateService.LogoutAccountAsync(userId, userInitiated);
searchService.ClearIndex();
if (isActiveAccount)
{
await ClearServiceCacheAsync();
}
if (!userInitiated)
{
@ -558,8 +542,7 @@ namespace Bit.App.Utilities
if (!isActiveAccount)
{
var platformUtilsService = ServiceContainer.Resolve<IPlatformUtilsService>("platformUtilsService");
if (await vaultTimeoutService.IsLoggedOutByTimeoutAsync(userId) ||
await vaultTimeoutService.ShouldLogOutByTimeoutAsync())
if (isAccountRemoval)
{
platformUtilsService.ShowToast("info", null, AppResources.AccountRemovedSuccessfully);
return;
@ -571,6 +554,12 @@ namespace Bit.App.Utilities
public static async Task OnAccountSwitchAsync()
{
var environmentService = ServiceContainer.Resolve<IEnvironmentService>("environmentService");
await environmentService.SetUrlsFromStorageAsync();
await ClearServiceCacheAsync();
}
public static async Task ClearServiceCacheAsync()
{
var tokenService = ServiceContainer.Resolve<ITokenService>("tokenService");
var cryptoService = ServiceContainer.Resolve<ICryptoService>("cryptoService");
var settingsService = ServiceContainer.Resolve<ISettingsService>("settingsService");
@ -584,8 +573,6 @@ namespace Bit.App.Utilities
var policyService = ServiceContainer.Resolve<IPolicyService>("policyService");
var searchService = ServiceContainer.Resolve<ISearchService>("searchService");
await environmentService.SetUrlsFromStorageAsync();
await Task.WhenAll(
cipherService.ClearCacheAsync(),
deviceActionService.ClearCacheAsync());

View file

@ -63,8 +63,8 @@ namespace Bit.Core.Abstractions
Task SetVaultTimeoutAsync(int? value, string userId = null);
Task<VaultTimeoutAction?> GetVaultTimeoutActionAsync(string userId = null);
Task SetVaultTimeoutActionAsync(VaultTimeoutAction? value, string userId = null);
Task<DateTime?> GetLastFileCacheClearAsync(string userId = null);
Task SetLastFileCacheClearAsync(DateTime? value, string userId = null);
Task<DateTime?> GetLastFileCacheClearAsync();
Task SetLastFileCacheClearAsync(DateTime? value);
Task<PreviousPageInfo> GetPreviousPageInfoAsync(string userId = null);
Task SetPreviousPageInfoAsync(PreviousPageInfo value, string userId = null);
Task<int> GetInvalidUnlockAttemptsAsync(string userId = null);

View file

@ -48,7 +48,6 @@ namespace Bit.Core.Services
{
return true;
}
await CheckStateAsync();
return userId == await GetActiveUserIdAsync();
}
@ -160,8 +159,9 @@ namespace Bit.Core.Services
await CheckStateAsync();
await RemoveAccountAsync(userId, userInitiated);
// If user initiated logout (not vault timeout) find the next user to make active, if any
if (userInitiated && _state?.Accounts != null)
// If user initiated logout (not vault timeout) and ActiveUserId is null after account removal, find the
// next user to make active, if any
if (userInitiated && _state?.ActiveUserId == null && _state?.Accounts != null)
{
foreach (var account in _state.Accounts)
{
@ -534,20 +534,18 @@ namespace Bit.Core.Services
await SaveAccountAsync(account, reconciledOptions);
}
public async Task<DateTime?> GetLastFileCacheClearAsync(string userId = null)
public async Task<DateTime?> GetLastFileCacheClearAsync()
{
var reconciledOptions = ReconcileOptions(new StorageOptions { UserId = userId },
await GetDefaultStorageOptionsAsync());
var options = await GetDefaultStorageOptionsAsync();
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 },
await GetDefaultStorageOptionsAsync());
var options = await GetDefaultStorageOptionsAsync();
var key = Constants.LastFileCacheClearKey;
await SetValueAsync(key, value, reconciledOptions);
await SetValueAsync(key, value, options);
}
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)
{
if (value == null)
{
// don't remove values globally
return;
}
await CheckStateAsync();
if (_state?.Accounts == null)
{
@ -1246,14 +1249,11 @@ namespace Bit.Core.Services
}
// Storage
_state = await GetStateFromStorageAsync();
if (_state?.Accounts?.ContainsKey(options.UserId) ?? false)
var state = await GetStateFromStorageAsync();
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;
@ -1321,8 +1321,7 @@ namespace Bit.Core.Services
{
_state.Accounts[userId].Tokens.AccessToken = null;
_state.Accounts[userId].Tokens.RefreshToken = null;
_state.Accounts[userId].VolatileData.Key = null;
_state.Accounts[userId].VolatileData.BiometricLocked = null;
_state.Accounts[userId].VolatileData = null;
}
}
if (userInitiated && _state?.ActiveUserId == userId)
@ -1366,7 +1365,6 @@ namespace Bit.Core.Services
await SetOrgKeysEncryptedAsync(null, userId);
await SetPrivateKeyEncryptedAsync(null, userId);
await SetLastActiveTimeAsync(null, userId);
await SetLastFileCacheClearAsync(null, userId);
await SetPreviousPageInfoAsync(null, userId);
await SetInvalidUnlockAttemptsAsync(null, userId);
await SetLocalDataAsync(null, userId);