mirror of
https://github.com/bitwarden/mobile
synced 2025-12-05 23:53:33 +00:00
wip
This commit is contained in:
@@ -80,11 +80,12 @@ namespace Bit.App
|
||||
}
|
||||
else if (message.Command == "logout")
|
||||
{
|
||||
var extras = message.Data as Tuple<bool?, string>;
|
||||
var expired = extras?.Item1;
|
||||
var userId = extras?.Item2;
|
||||
var extras = message.Data as Tuple<string, bool, bool>;
|
||||
var userId = extras?.Item1;
|
||||
var userInitiated = extras?.Item2;
|
||||
var expired = extras?.Item3;
|
||||
Device.BeginInvokeOnMainThread(async () =>
|
||||
await LogOutAsync(expired.GetValueOrDefault(), userId));
|
||||
await LogOutAsync(userId, userInitiated, expired));
|
||||
}
|
||||
else if (message.Command == "loggedOut")
|
||||
{
|
||||
@@ -111,7 +112,7 @@ namespace Bit.App
|
||||
}
|
||||
else if (message.Command == "switchedAccount")
|
||||
{
|
||||
await SwitchedAccount();
|
||||
await SwitchedAccountAsync();
|
||||
}
|
||||
else if (message.Command == "migrated")
|
||||
{
|
||||
@@ -241,13 +242,13 @@ namespace Bit.App
|
||||
new System.Globalization.UmAlQuraCalendar();
|
||||
}
|
||||
|
||||
private async Task LogOutAsync(bool expired, string userId)
|
||||
private async Task LogOutAsync(string userId, bool? userInitiated, bool? expired)
|
||||
{
|
||||
await AppHelpers.LogOutAsync(userId);
|
||||
await AppHelpers.LogOutAsync(userId, userInitiated.GetValueOrDefault(true));
|
||||
await SetMainPageAsync();
|
||||
_authService.LogOut(() =>
|
||||
{
|
||||
Current.MainPage = new NavigationPage(new HomePage(Options));
|
||||
if (expired)
|
||||
if (expired.GetValueOrDefault())
|
||||
{
|
||||
_platformUtilsService.ShowToast("warning", null, AppResources.LoginExpired);
|
||||
}
|
||||
@@ -258,14 +259,14 @@ namespace Bit.App
|
||||
{
|
||||
Device.BeginInvokeOnMainThread(async () =>
|
||||
{
|
||||
Options.ShowAccountSwitcher = true;
|
||||
Current.MainPage = new NavigationPage(new HomePage(Options));
|
||||
});
|
||||
}
|
||||
|
||||
private async Task SwitchedAccount()
|
||||
private async Task SwitchedAccountAsync()
|
||||
{
|
||||
await AppHelpers.ClearServiceCache();
|
||||
await AppHelpers.OnAccountSwitchAsync();
|
||||
UpdateTheme();
|
||||
Device.BeginInvokeOnMainThread(async () =>
|
||||
{
|
||||
await SetMainPageAsync();
|
||||
@@ -274,10 +275,7 @@ namespace Bit.App
|
||||
|
||||
private async Task SetMainPageAsync()
|
||||
{
|
||||
if (await _stateService.HasMultipleAccountsAsync())
|
||||
{
|
||||
Options.ShowAccountSwitcher = true;
|
||||
}
|
||||
await _stateService.RefreshAccountViews();
|
||||
var authed = await _stateService.IsAuthenticatedAsync();
|
||||
if (authed)
|
||||
{
|
||||
|
||||
@@ -45,13 +45,13 @@
|
||||
<Label
|
||||
Grid.Column="0"
|
||||
Grid.Row="0"
|
||||
Text="{Binding Account.Email}"
|
||||
Text="{Binding AccountView.Email}"
|
||||
StyleClass="list-title"
|
||||
LineBreakMode="TailTruncation" />
|
||||
<Label
|
||||
Grid.Column="0"
|
||||
Grid.Row="1"
|
||||
Text="{Binding Account.Hostname}"
|
||||
Text="{Binding AccountView.Hostname}"
|
||||
StyleClass="list-sub"
|
||||
LineBreakMode="TailTruncation" />
|
||||
</Grid>
|
||||
|
||||
@@ -5,27 +5,27 @@ namespace Bit.App.Controls
|
||||
{
|
||||
public class AccountViewCellViewModel : ExtendedViewModel
|
||||
{
|
||||
private AccountView _account;
|
||||
private AccountView _accountView;
|
||||
|
||||
public AccountViewCellViewModel(AccountView accountView)
|
||||
{
|
||||
Account = accountView;
|
||||
AccountView = accountView;
|
||||
}
|
||||
|
||||
public AccountView Account
|
||||
public AccountView AccountView
|
||||
{
|
||||
get => _account;
|
||||
set => SetProperty(ref _account, value);
|
||||
get => _accountView;
|
||||
set => SetProperty(ref _accountView, value);
|
||||
}
|
||||
|
||||
public bool IsAccount
|
||||
{
|
||||
get => Account.IsAccount;
|
||||
get => AccountView.IsAccount;
|
||||
}
|
||||
|
||||
public string AuthStatusText
|
||||
{
|
||||
get => Account.AuthStatus.ToString();
|
||||
get => AccountView.AuthStatus.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -100,7 +100,8 @@ namespace Bit.App.Controls
|
||||
for (var i = 0; i < 3; i++)
|
||||
{
|
||||
var value = (hash >> (i * 8)) & 0xff;
|
||||
color += Convert.ToString(value, 16);
|
||||
var base16 = "00" + Convert.ToString(value, 16);
|
||||
color += base16.Substring(base16.Length - 2);
|
||||
}
|
||||
if (Device.RuntimePlatform == Device.iOS)
|
||||
{
|
||||
|
||||
@@ -21,7 +21,6 @@ namespace Bit.App.Models
|
||||
public string SaveCardCode { get; set; }
|
||||
public bool IosExtension { get; set; }
|
||||
public Tuple<SendType, string, byte[], string> CreateSend { get; set; }
|
||||
public bool ShowAccountSwitcher { get; set; }
|
||||
|
||||
public void SetAllFrom(AppOptions o)
|
||||
{
|
||||
@@ -45,7 +44,6 @@ namespace Bit.App.Models
|
||||
SaveCardCode = o.SaveCardCode;
|
||||
IosExtension = o.IosExtension;
|
||||
CreateSend = o.CreateSend;
|
||||
ShowAccountSwitcher = o.ShowAccountSwitcher;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,7 +88,7 @@
|
||||
xct:ShadowEffect.Radius="10"
|
||||
xct:ShadowEffect.OffsetY="3">
|
||||
<ListView
|
||||
ItemsSource="{Binding Accounts}"
|
||||
ItemsSource="{Binding AccountViews}"
|
||||
ItemSelected="AccountRow_Selected"
|
||||
VerticalOptions="FillAndExpand"
|
||||
RowHeight="60">
|
||||
|
||||
@@ -14,6 +14,8 @@ namespace Bit.App.Pages
|
||||
private readonly AppOptions _appOptions;
|
||||
private IBroadcasterService _broadcasterService;
|
||||
|
||||
private bool _appeared;
|
||||
|
||||
public HomePage(AppOptions appOptions = null)
|
||||
{
|
||||
_broadcasterService = ServiceContainer.Resolve<IBroadcasterService>("broadcasterService");
|
||||
@@ -31,10 +33,6 @@ namespace Bit.App.Pages
|
||||
{
|
||||
ToolbarItems.Add(_closeItem);
|
||||
}
|
||||
if (_appOptions?.ShowAccountSwitcher ?? false)
|
||||
{
|
||||
ToolbarItems.Add(_accountAvatar);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task DismissRegisterPageAndLogInAsync(string email)
|
||||
@@ -46,12 +44,6 @@ namespace Bit.App.Pages
|
||||
protected override async void OnAppearing()
|
||||
{
|
||||
base.OnAppearing();
|
||||
_mainContent.Content = _mainLayout;
|
||||
if (_appOptions?.ShowAccountSwitcher ?? false)
|
||||
{
|
||||
_appOptions.ShowAccountSwitcher = false;
|
||||
_vm.AvatarImageSource = await GetAvatarImageSourceAsync();
|
||||
}
|
||||
_broadcasterService.Subscribe(nameof(HomePage), async (message) =>
|
||||
{
|
||||
if (message.Command == "updatedTheme")
|
||||
@@ -62,6 +54,17 @@ namespace Bit.App.Pages
|
||||
});
|
||||
}
|
||||
});
|
||||
if (_appeared)
|
||||
{
|
||||
return;
|
||||
}
|
||||
_appeared = true;
|
||||
_mainContent.Content = _mainLayout;
|
||||
if (await HasMultipleAccountsAsync())
|
||||
{
|
||||
ToolbarItems.Add(_accountAvatar);
|
||||
_vm.AvatarImageSource = await GetAvatarImageSourceAsync(false);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnDisappearing()
|
||||
|
||||
@@ -17,9 +17,9 @@ namespace Bit.App.Pages
|
||||
PageTitle = AppResources.Bitwarden;
|
||||
}
|
||||
|
||||
public ExtendedObservableCollection<AccountView> Accounts
|
||||
public ExtendedObservableCollection<AccountView> AccountViews
|
||||
{
|
||||
get => _stateService.Accounts;
|
||||
get => _stateService.AccountViews;
|
||||
}
|
||||
|
||||
public Action StartLoginAction { get; set; }
|
||||
|
||||
@@ -178,7 +178,7 @@
|
||||
xct:ShadowEffect.Radius="10"
|
||||
xct:ShadowEffect.OffsetY="3">
|
||||
<ListView
|
||||
ItemsSource="{Binding Accounts}"
|
||||
ItemsSource="{Binding AccountViews}"
|
||||
ItemSelected="AccountRow_Selected"
|
||||
VerticalOptions="FillAndExpand"
|
||||
RowHeight="60">
|
||||
|
||||
@@ -27,10 +27,6 @@ namespace Bit.App.Pages
|
||||
MasterPasswordEntry = _masterPassword;
|
||||
PinEntry = _pin;
|
||||
|
||||
if (_appOptions?.ShowAccountSwitcher ?? false)
|
||||
{
|
||||
ToolbarItems.Add(_accountAvatar);
|
||||
}
|
||||
if (Device.RuntimePlatform == Device.iOS)
|
||||
{
|
||||
ToolbarItems.Add(_moreItem);
|
||||
@@ -66,9 +62,9 @@ namespace Bit.App.Pages
|
||||
}
|
||||
_appeared = true;
|
||||
_mainContent.Content = _mainLayout;
|
||||
if (_appOptions?.ShowAccountSwitcher ?? false)
|
||||
if (await HasMultipleAccountsAsync())
|
||||
{
|
||||
_appOptions.ShowAccountSwitcher = false;
|
||||
ToolbarItems.Add(_accountAvatar);
|
||||
_vm.AvatarImageSource = await GetAvatarImageSourceAsync();
|
||||
}
|
||||
await _vm.InitAsync();
|
||||
|
||||
@@ -113,9 +113,9 @@ namespace Bit.App.Pages
|
||||
set => SetProperty(ref _lockedVerifyText, value);
|
||||
}
|
||||
|
||||
public ExtendedObservableCollection<AccountView> Accounts
|
||||
public ExtendedObservableCollection<AccountView> AccountViews
|
||||
{
|
||||
get => _stateService.Accounts;
|
||||
get => _stateService.AccountViews;
|
||||
}
|
||||
|
||||
public Command SubmitCommand { get; }
|
||||
|
||||
@@ -130,7 +130,7 @@
|
||||
xct:ShadowEffect.Radius="10"
|
||||
xct:ShadowEffect.OffsetY="3">
|
||||
<ListView
|
||||
ItemsSource="{Binding Accounts}"
|
||||
ItemsSource="{Binding AccountViews}"
|
||||
ItemSelected="AccountRow_Selected"
|
||||
VerticalOptions="FillAndExpand"
|
||||
RowHeight="60">
|
||||
|
||||
@@ -12,6 +12,7 @@ namespace Bit.App.Pages
|
||||
private readonly LoginPageViewModel _vm;
|
||||
private readonly AppOptions _appOptions;
|
||||
|
||||
private bool _appeared;
|
||||
private bool _inputFocused;
|
||||
|
||||
public LoginPage(string email = null, AppOptions appOptions = null)
|
||||
@@ -34,11 +35,6 @@ namespace Bit.App.Pages
|
||||
{
|
||||
ToolbarItems.RemoveAt(0);
|
||||
}
|
||||
if (_appOptions?.ShowAccountSwitcher ?? false)
|
||||
{
|
||||
ToolbarItems.Add(_accountAvatar);
|
||||
ToolbarItems.Remove(_closeItem);
|
||||
}
|
||||
|
||||
_email.ReturnType = ReturnType.Next;
|
||||
_email.ReturnCommand = new Command(() => _masterPassword.Focus());
|
||||
@@ -58,18 +54,24 @@ namespace Bit.App.Pages
|
||||
protected override async void OnAppearing()
|
||||
{
|
||||
base.OnAppearing();
|
||||
_mainContent.Content = _mainLayout;
|
||||
if (_appOptions?.ShowAccountSwitcher ?? false)
|
||||
{
|
||||
_appOptions.ShowAccountSwitcher = false;
|
||||
_vm.AvatarImageSource = await GetAvatarImageSourceAsync();
|
||||
}
|
||||
await _vm.InitAsync();
|
||||
if (!_inputFocused)
|
||||
{
|
||||
RequestFocus(string.IsNullOrWhiteSpace(_vm.Email) ? _email : _masterPassword);
|
||||
_inputFocused = true;
|
||||
}
|
||||
if (_appeared)
|
||||
{
|
||||
return;
|
||||
}
|
||||
_appeared = true;
|
||||
_mainContent.Content = _mainLayout;
|
||||
if (await HasMultipleAccountsAsync())
|
||||
{
|
||||
ToolbarItems.Add(_accountAvatar);
|
||||
ToolbarItems.Remove(_closeItem);
|
||||
_vm.AvatarImageSource = await GetAvatarImageSourceAsync();
|
||||
}
|
||||
}
|
||||
|
||||
private async void LogIn_Clicked(object sender, EventArgs e)
|
||||
|
||||
@@ -62,9 +62,9 @@ namespace Bit.App.Pages
|
||||
set => SetProperty(ref _masterPassword, value);
|
||||
}
|
||||
|
||||
public ExtendedObservableCollection<AccountView> Accounts
|
||||
public ExtendedObservableCollection<AccountView> AccountViews
|
||||
{
|
||||
get => _stateService.Accounts;
|
||||
get => _stateService.AccountViews;
|
||||
}
|
||||
|
||||
public Command LogInCommand { get; }
|
||||
|
||||
@@ -38,6 +38,11 @@ namespace Bit.App.Pages
|
||||
await SaveActivity();
|
||||
}
|
||||
|
||||
public async Task<bool> HasMultipleAccountsAsync()
|
||||
{
|
||||
return await _stateService.HasMultipleAccountsAsync();
|
||||
}
|
||||
|
||||
public bool DoOnce(Action action = null, int milliseconds = 1000)
|
||||
{
|
||||
if (LastPageAction.HasValue && (DateTime.UtcNow - LastPageAction.Value).TotalMilliseconds < milliseconds)
|
||||
@@ -108,9 +113,9 @@ namespace Bit.App.Pages
|
||||
});
|
||||
}
|
||||
|
||||
protected async Task<AvatarImageSource> GetAvatarImageSourceAsync()
|
||||
protected async Task<AvatarImageSource> GetAvatarImageSourceAsync(bool useCurrentActiveAccount = true)
|
||||
{
|
||||
return new AvatarImageSource(await _stateService.GetEmailAsync());
|
||||
return new AvatarImageSource(useCurrentActiveAccount ? await _stateService.GetEmailAsync() : null);
|
||||
}
|
||||
|
||||
protected async Task ShowAccountListAsync(bool isVisible, View listView, View overlay, View fab = null)
|
||||
@@ -120,6 +125,9 @@ namespace Bit.App.Pages
|
||||
// Not all animations are awaited. This is intentional to allow multiple simultaneous animations.
|
||||
if (isVisible)
|
||||
{
|
||||
// Update account views to reflect current state
|
||||
await _stateService.RefreshAccountViews();
|
||||
|
||||
// start listView in default (off-screen) position
|
||||
await listView.TranslateTo(0, listView.Height * -1, 0);
|
||||
|
||||
@@ -173,13 +181,13 @@ namespace Bit.App.Pages
|
||||
await Task.Delay(100);
|
||||
await ShowAccountListAsync(false, listView, overlay, fab);
|
||||
|
||||
if (item.Account.IsAccount)
|
||||
if (item.AccountView.IsAccount)
|
||||
{
|
||||
if (item.Account.AuthStatus != AuthenticationStatus.Active)
|
||||
if (item.AccountView.AuthStatus != AuthenticationStatus.Active)
|
||||
{
|
||||
await _stateService.SetActiveUserAsync(item.Account.UserId);
|
||||
_messagingService.Send("switchedAccount");
|
||||
await _stateService.SetActiveUserAsync(item.AccountView.UserId);
|
||||
}
|
||||
_messagingService.Send("switchedAccount");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -180,7 +180,7 @@
|
||||
xct:ShadowEffect.Radius="10"
|
||||
xct:ShadowEffect.OffsetY="3">
|
||||
<ListView
|
||||
ItemsSource="{Binding Accounts}"
|
||||
ItemsSource="{Binding AccountViews}"
|
||||
ItemSelected="AccountRow_Selected"
|
||||
VerticalOptions="FillAndExpand"
|
||||
RowHeight="60">
|
||||
|
||||
@@ -133,13 +133,13 @@ namespace Bit.App.Pages
|
||||
get => _websiteIconsEnabled;
|
||||
set => SetProperty(ref _websiteIconsEnabled, value);
|
||||
}
|
||||
public ExtendedObservableCollection<AccountView> Accounts
|
||||
public ExtendedObservableCollection<AccountView> AccountViews
|
||||
{
|
||||
get
|
||||
{
|
||||
// create a separate collection that includes the "add new" row
|
||||
var accounts = new ExtendedObservableCollection<AccountView>();
|
||||
accounts.AddRange(_stateService.Accounts);
|
||||
accounts.AddRange(_stateService.AccountViews);
|
||||
accounts.Add(new AccountView());
|
||||
return accounts;
|
||||
}
|
||||
|
||||
@@ -447,7 +447,7 @@ namespace Bit.App.Utilities
|
||||
return Convert.ToBase64String(Encoding.UTF8.GetBytes(multiByteEscaped));
|
||||
}
|
||||
|
||||
public static async Task LogOutAsync(string userId)
|
||||
public static async Task LogOutAsync(string userId, bool userInitiated = false)
|
||||
{
|
||||
var syncService = ServiceContainer.Resolve<ISyncService>("syncService");
|
||||
var tokenService = ServiceContainer.Resolve<ITokenService>("tokenService");
|
||||
@@ -469,24 +469,30 @@ namespace Bit.App.Utilities
|
||||
}
|
||||
|
||||
await Task.WhenAll(
|
||||
syncService.SetLastSyncAsync(DateTime.MinValue),
|
||||
tokenService.ClearTokenAsync(userId),
|
||||
cryptoService.ClearKeysAsync(userId),
|
||||
stateService.CleanAsync(userId),
|
||||
settingsService.ClearAsync(userId),
|
||||
cipherService.ClearAsync(userId),
|
||||
folderService.ClearAsync(userId),
|
||||
collectionService.ClearAsync(userId),
|
||||
passwordGenerationService.ClearAsync(userId),
|
||||
vaultTimeoutService.ClearAsync(userId),
|
||||
deviceActionService.ClearCacheAsync());
|
||||
if (userInitiated)
|
||||
{
|
||||
await Task.WhenAll(
|
||||
syncService.SetLastSyncAsync(DateTime.MinValue),
|
||||
tokenService.ClearTokenAsync(userId),
|
||||
cryptoService.ClearKeysAsync(userId),
|
||||
settingsService.ClearAsync(userId),
|
||||
vaultTimeoutService.ClearAsync(userId),
|
||||
stateService.ClearAsync(userId));
|
||||
}
|
||||
stateService.BiometricLocked = true;
|
||||
searchService.ClearIndex();
|
||||
}
|
||||
|
||||
public static async Task ClearServiceCache()
|
||||
public static async Task OnAccountSwitchAsync()
|
||||
{
|
||||
var environmentService = ServiceContainer.Resolve<IEnvironmentService>("environmentService");
|
||||
var tokenService = ServiceContainer.Resolve<ITokenService>("tokenService");
|
||||
var cryptoService = ServiceContainer.Resolve<ICryptoService>("cryptoService");
|
||||
var cipherService = ServiceContainer.Resolve<ICipherService>("cipherService");
|
||||
var folderService = ServiceContainer.Resolve<IFolderService>("folderService");
|
||||
var collectionService = ServiceContainer.Resolve<ICollectionService>("collectionService");
|
||||
@@ -495,10 +501,13 @@ namespace Bit.App.Utilities
|
||||
var deviceActionService = ServiceContainer.Resolve<IDeviceActionService>("deviceActionService");
|
||||
var searchService = ServiceContainer.Resolve<ISearchService>("searchService");
|
||||
|
||||
await environmentService.SetUrlsFromStorageAsync();
|
||||
|
||||
await Task.WhenAll(
|
||||
cipherService.ClearCacheAsync(),
|
||||
deviceActionService.ClearCacheAsync());
|
||||
tokenService.ClearCache();
|
||||
cryptoService.ClearCache();
|
||||
folderService.ClearCache();
|
||||
collectionService.ClearCache();
|
||||
passwordGenerationService.ClearCache();
|
||||
|
||||
@@ -16,6 +16,7 @@ namespace Bit.Core.Abstractions
|
||||
Task ClearKeysAsync(string userId = null);
|
||||
Task ClearOrgKeysAsync(bool memoryOnly = false, string userId = null);
|
||||
Task ClearPinProtectedKeyAsync(string userId = null);
|
||||
void ClearCache();
|
||||
Task<byte[]> DecryptFromBytesAsync(byte[] encBytes, SymmetricCryptoKey key);
|
||||
Task<byte[]> DecryptToBytesAsync(EncString encString, SymmetricCryptoKey key = null);
|
||||
Task<string> DecryptToUtf8Async(EncString encString, SymmetricCryptoKey key = null);
|
||||
|
||||
@@ -12,162 +12,152 @@ namespace Bit.Core.Abstractions
|
||||
public interface IStateService
|
||||
{
|
||||
bool BiometricLocked { get; set; }
|
||||
ExtendedObservableCollection<AccountView> Accounts { get; set; }
|
||||
Task<string> GetActiveUserIdAsync(StorageOptions options = null);
|
||||
ExtendedObservableCollection<AccountView> AccountViews { get; set; }
|
||||
Task<List<string>> GetUserIdsAsync();
|
||||
Task<string> GetActiveUserIdAsync();
|
||||
Task SetActiveUserAsync(string userId);
|
||||
Task<bool> IsAuthenticatedAsync(StorageOptions options = null);
|
||||
Task<bool> IsAuthenticatedAsync(string userId = null);
|
||||
Task<bool> HasMultipleAccountsAsync();
|
||||
Task RefreshAccountViews();
|
||||
Task AddAccountAsync(Account account);
|
||||
// Task SetInformationAsync(string userId, string email, KdfType kdf, int? kdfIterations);
|
||||
Task CleanAsync(string userId);
|
||||
Task ClearAsync(string userId);
|
||||
Task<EnvironmentUrlData> GetPreAuthEnvironmentUrlsAsync();
|
||||
Task SetPreAuthEnvironmentUrlsAsync(EnvironmentUrlData value);
|
||||
Task<EnvironmentUrlData> GetEnvironmentUrlsAsync(StorageOptions options = null);
|
||||
Task SetEnvironmentUrlsAsync(EnvironmentUrlData value, StorageOptions options = null);
|
||||
Task<bool?> GetBiometricUnlockAsync(StorageOptions options = null);
|
||||
Task SetBiometricUnlockAsync(bool? value, StorageOptions options = null);
|
||||
Task<bool> CanAccessPremiumAsync(StorageOptions options = null);
|
||||
Task<string> GetProtectedPinAsync(StorageOptions options = null);
|
||||
Task SetProtectedPinAsync(string value, StorageOptions options = null);
|
||||
Task<string> GetPinProtectedAsync(StorageOptions options = null);
|
||||
Task SetPinProtectedAsync(string value, StorageOptions options = null);
|
||||
Task<EncString> GetPinProtectedCachedAsync(StorageOptions options = null);
|
||||
Task SetPinProtectedCachedAsync(EncString value, StorageOptions options = null);
|
||||
Task<KdfType?> GetKdfTypeAsync(StorageOptions options = null);
|
||||
Task SetKdfTypeAsync(KdfType? value, StorageOptions options = null);
|
||||
Task<int?> GetKdfIterationsAsync(StorageOptions options = null);
|
||||
Task SetKdfIterationsAsync(int? value, StorageOptions options = null);
|
||||
Task<string> GetKeyEncryptedAsync(StorageOptions options = null);
|
||||
Task SetKeyEncryptedAsync(string value, StorageOptions options = null);
|
||||
Task<SymmetricCryptoKey> GetKeyDecryptedAsync(StorageOptions options = null);
|
||||
Task SetKeyDecryptedAsync(SymmetricCryptoKey value, StorageOptions options = null);
|
||||
Task<string> GetKeyHashAsync(StorageOptions options = null);
|
||||
Task SetKeyHashAsync(string value, StorageOptions options = null);
|
||||
Task<string> GetKeyHashCachedAsync(StorageOptions options = null);
|
||||
Task SetKeyHashCachedAsync(string value, StorageOptions options = null);
|
||||
Task<string> GetEncKeyEncryptedAsync(StorageOptions options = null);
|
||||
Task SetEncKeyEncryptedAsync(string value, StorageOptions options = null);
|
||||
Task<SymmetricCryptoKey> GetEncKeyDecryptedAsync(StorageOptions options = null);
|
||||
Task SetEncKeyDecryptedAsync(SymmetricCryptoKey value, StorageOptions options = null);
|
||||
Task<Dictionary<string, string>> GetOrgKeysEncryptedAsync(StorageOptions options = null);
|
||||
Task SetOrgKeysEncryptedAsync(Dictionary<string, string> value, StorageOptions options = null);
|
||||
Task<Dictionary<string, SymmetricCryptoKey>> GetOrgKeysDecryptedAsync(StorageOptions options = null);
|
||||
Task SetOrgKeysDecryptedAsync(Dictionary<string, SymmetricCryptoKey> value, StorageOptions options = null);
|
||||
Task<byte[]> GetPublicKeyAsync(StorageOptions options = null);
|
||||
Task SetPublicKeyAsync(byte[] value, StorageOptions options = null);
|
||||
Task<string> GetPrivateKeyEncryptedAsync(StorageOptions options = null);
|
||||
Task SetPrivateKeyEncryptedAsync(string value, StorageOptions options = null);
|
||||
Task<byte[]> GetPrivateKeyDecryptedAsync(StorageOptions options = null);
|
||||
Task SetPrivateKeyDecryptedAsync(byte[] value, StorageOptions options = null);
|
||||
Task<List<string>> GetAutofillBlacklistedUrisAsync(StorageOptions options = null);
|
||||
Task SetAutofillBlacklistedUrisAsync(List<string> value, StorageOptions options = null);
|
||||
Task<bool?> GetAutofillTileAddedAsync(StorageOptions options = null);
|
||||
Task SetAutofillTileAddedAsync(bool? value, StorageOptions options = null);
|
||||
Task<string> GetEmailAsync(StorageOptions options = null);
|
||||
// Task SetEmailAsync(string value, StorageOptions options = null);
|
||||
Task<long?> GetLastActiveTimeAsync(StorageOptions options = null);
|
||||
Task SetLastActiveTimeAsync(long? value, StorageOptions options = null);
|
||||
Task<int?> GetVaultTimeoutAsync(StorageOptions options = null);
|
||||
Task SetVaultTimeoutAsync(int? value, StorageOptions options = null);
|
||||
Task<string> GetVaultTimeoutActionAsync(StorageOptions options = null);
|
||||
Task SetVaultTimeoutActionAsync(string value, StorageOptions options = null);
|
||||
Task<DateTime?> GetLastFileCacheClearAsync(StorageOptions options = null);
|
||||
Task SetLastFileCacheClearAsync(DateTime? value, StorageOptions options = null);
|
||||
Task<PreviousPageInfo> GetPreviousPageInfoAsync(StorageOptions options = null);
|
||||
Task SetPreviousPageInfoAsync(PreviousPageInfo value, StorageOptions options = null);
|
||||
Task<int> GetInvalidUnlockAttemptsAsync(StorageOptions options = null);
|
||||
Task SetInvalidUnlockAttemptsAsync(int? value, StorageOptions options = null);
|
||||
Task<string> GetLastBuildAsync(StorageOptions options = null);
|
||||
Task SetLastBuildAsync(string value, StorageOptions options = null);
|
||||
Task<bool?> GetDisableFaviconAsync(StorageOptions options = null);
|
||||
Task SetDisableFaviconAsync(bool? value, StorageOptions options = null);
|
||||
Task<bool?> GetDisableAutoTotpCopyAsync(StorageOptions options = null);
|
||||
Task SetDisableAutoTotpCopyAsync(bool? value, StorageOptions options = null);
|
||||
Task<bool?> GetInlineAutofillEnabledAsync(StorageOptions options = null);
|
||||
Task SetInlineAutofillEnabledAsync(bool? value, StorageOptions options = null);
|
||||
Task<bool?> GetAutofillDisableSavePromptAsync(StorageOptions options = null);
|
||||
Task SetAutofillDisableSavePromptAsync(bool? value, StorageOptions options = null);
|
||||
Task<Dictionary<string, Dictionary<string, object>>> GetLocalDataAsync(StorageOptions options = null);
|
||||
Task SetLocalDataAsync(Dictionary<string, Dictionary<string, object>> value, StorageOptions options = null);
|
||||
Task<Dictionary<string, CipherData>> GetEncryptedCiphersAsync(StorageOptions options = null);
|
||||
Task SetEncryptedCiphersAsync(Dictionary<string, CipherData> value, StorageOptions options = null);
|
||||
Task<int?> GetDefaultUriMatchAsync(StorageOptions options = null);
|
||||
Task SetDefaultUriMatchAsync(int? value, StorageOptions options = null);
|
||||
Task<HashSet<string>> GetNeverDomainsAsync(StorageOptions options = null);
|
||||
Task SetNeverDomainsAsync(HashSet<string> value, StorageOptions options = null);
|
||||
Task<int?> GetClearClipboardAsync(StorageOptions options = null);
|
||||
Task SetClearClipboardAsync(int? value, StorageOptions options = null);
|
||||
Task<Dictionary<string, CollectionData>> GetEncryptedCollectionsAsync(StorageOptions options = null);
|
||||
Task SetEncryptedCollectionsAsync(Dictionary<string, CollectionData> value, StorageOptions options = null);
|
||||
Task<bool> GetPasswordRepromptAutofillAsync(StorageOptions options = null);
|
||||
Task SetPasswordRepromptAutofillAsync(bool? value, StorageOptions options = null);
|
||||
Task<bool> GetPasswordVerifiedAutofillAsync(StorageOptions options = null);
|
||||
Task SetPasswordVerifiedAutofillAsync(bool? value, StorageOptions options = null);
|
||||
Task<DateTime?> GetLastSyncAsync(StorageOptions options = null);
|
||||
Task SetLastSyncAsync(DateTime? value, StorageOptions options = null);
|
||||
Task<string> GetSecurityStampAsync(StorageOptions options = null);
|
||||
Task SetSecurityStampAsync(string value, StorageOptions options = null);
|
||||
Task<bool> GetEmailVerifiedAsync(StorageOptions options = null);
|
||||
Task SetEmailVerifiedAsync(bool? value, StorageOptions options = null);
|
||||
Task<bool> GetForcePasswordReset(StorageOptions options = null);
|
||||
Task SetForcePasswordResetAsync(bool? value, StorageOptions options = null);
|
||||
Task<bool> GetSyncOnRefreshAsync(StorageOptions options = null);
|
||||
Task SetSyncOnRefreshAsync(bool? value, StorageOptions options = null);
|
||||
Task<string> GetRememberedEmailAsync(StorageOptions options = null);
|
||||
Task SetRememberedEmailAsync(string value, StorageOptions options = null);
|
||||
Task<bool?> GetRememberEmailAsync(StorageOptions options = null);
|
||||
Task SetRememberEmailAsync(bool? value, StorageOptions options = null);
|
||||
Task<string> GetRememberedOrgIdentifierAsync(StorageOptions options = null);
|
||||
Task SetRememberedOrgIdentifierAsync(string value, StorageOptions options = null);
|
||||
Task<bool?> GetRememberOrgIdentifierAsync(StorageOptions options = null);
|
||||
Task SetRememberOrgIdentifierAsync(bool? value, StorageOptions options = null);
|
||||
Task<string> GetThemeAsync(StorageOptions options = null);
|
||||
Task SetThemeAsync(string value, StorageOptions options = null);
|
||||
Task<bool?> GetAddSitePromptShownAsync(StorageOptions options = null);
|
||||
Task SetAddSitePromptShownAsync(bool? value, StorageOptions options = null);
|
||||
Task<bool?> GetMigratedFromV1Async(StorageOptions options = null);
|
||||
Task SetMigratedFromV1Async(bool? value, StorageOptions options = null);
|
||||
Task<bool?> GetMigratedFromV1AutofillPromptShownAsync(StorageOptions options = null);
|
||||
Task SetMigratedFromV1AutofillPromptShownAsync(bool? value, StorageOptions options = null);
|
||||
Task<bool?> GetTriedV1ResyncAsync(StorageOptions options = null);
|
||||
Task SetTriedV1ResyncAsync(bool? value, StorageOptions options = null);
|
||||
Task<bool?> GetPushInitialPromptShownAsync(StorageOptions options = null);
|
||||
Task SetPushInitialPromptShownAsync(bool? value, StorageOptions options = null);
|
||||
Task<DateTime?> GetPushLastRegistrationDateAsync(StorageOptions options = null);
|
||||
Task SetPushLastRegistrationDateAsync(DateTime? value, StorageOptions options = null);
|
||||
Task<string> GetPushCurrentTokenAsync(StorageOptions options = null);
|
||||
Task SetPushCurrentTokenAsync(string value, StorageOptions options = null);
|
||||
Task<List<EventData>> GetEventCollectionAsync(StorageOptions options = null);
|
||||
Task SetEventCollectionAsync(List<EventData> value, StorageOptions options = null);
|
||||
Task<Dictionary<string, FolderData>> GetEncryptedFoldersAsync(StorageOptions options = null);
|
||||
Task SetEncryptedFoldersAsync(Dictionary<string, FolderData> value, StorageOptions options = null);
|
||||
Task<Dictionary<string, PolicyData>> GetEncryptedPoliciesAsync(StorageOptions options = null);
|
||||
Task SetEncryptedPoliciesAsync(Dictionary<string, PolicyData> value, StorageOptions options = null);
|
||||
Task<string> GetPushRegisteredTokenAsync(StorageOptions options = null);
|
||||
Task SetPushRegisteredTokenAsync(string value, StorageOptions options = null);
|
||||
Task<bool?> GetAppExtensionStartedAsync(StorageOptions options = null);
|
||||
Task SetAppExtensionStartedAsync(bool? value, StorageOptions options = null);
|
||||
Task<bool?> GetAppExtensionActivatedAsync(StorageOptions options = null);
|
||||
Task SetAppExtensionActivatedAsync(bool? value, StorageOptions options = null);
|
||||
Task<string> GetAppIdAsync(StorageOptions options = null);
|
||||
Task SetAppIdAsync(string value, StorageOptions options = null);
|
||||
Task<bool> GetUsesKeyConnectorAsync(StorageOptions options = null);
|
||||
Task SetUsesKeyConnectorAsync(bool? value, StorageOptions options = null);
|
||||
Task<Dictionary<string, OrganizationData>> GetOrganizationsAsync(StorageOptions options = null);
|
||||
Task SetOrganizationsAsync(Dictionary<string, OrganizationData> organizations, StorageOptions options = null);
|
||||
Task<PasswordGenerationOptions> GetPasswordGenerationOptionsAsync(StorageOptions options = null);
|
||||
Task SetPasswordGenerationOptionsAsync(PasswordGenerationOptions value, StorageOptions options = null);
|
||||
Task<List<GeneratedPasswordHistory>> GetEncryptedPasswordGenerationHistory(StorageOptions options = null);
|
||||
Task SetEncryptedPasswordGenerationHistoryAsync(List<GeneratedPasswordHistory> value, StorageOptions options = null);
|
||||
Task<Dictionary<string, SendData>> GetEncryptedSendsAsync(StorageOptions options = null);
|
||||
Task SetEncryptedSendsAsync(Dictionary<string, SendData> value, StorageOptions options = null);
|
||||
Task<Dictionary<string, object>> GetSettingsAsync(StorageOptions options = null);
|
||||
Task SetSettingsAsync(Dictionary<string, object> value, StorageOptions options = null);
|
||||
Task<string> GetAccessTokenAsync(StorageOptions options = null);
|
||||
Task SetAccessTokenAsync(string value, StorageOptions options = null);
|
||||
Task<string> GetRefreshTokenAsync(StorageOptions options = null);
|
||||
Task SetRefreshTokenAsync(string value, StorageOptions options = null);
|
||||
Task<string> GetTwoFactorTokenAsync(StorageOptions options = null);
|
||||
Task SetTwoFactorTokenAsync(string value, StorageOptions options = null);
|
||||
Task<EnvironmentUrlData> GetEnvironmentUrlsAsync(string userId = null);
|
||||
Task<bool?> GetBiometricUnlockAsync(string userId = null);
|
||||
Task SetBiometricUnlockAsync(bool? value, string userId = null);
|
||||
Task<bool> CanAccessPremiumAsync(string userId = null);
|
||||
Task<string> GetProtectedPinAsync(string userId = null);
|
||||
Task SetProtectedPinAsync(string value, string userId = null);
|
||||
Task<string> GetPinProtectedAsync(string userId = null);
|
||||
Task SetPinProtectedAsync(string value, string userId = null);
|
||||
Task<EncString> GetPinProtectedCachedAsync(string userId = null);
|
||||
Task SetPinProtectedCachedAsync(EncString value, string userId = null);
|
||||
Task<KdfType?> GetKdfTypeAsync(string userId = null);
|
||||
Task SetKdfTypeAsync(KdfType? value, string userId = null);
|
||||
Task<int?> GetKdfIterationsAsync(string userId = null);
|
||||
Task SetKdfIterationsAsync(int? value, string userId = null);
|
||||
Task<string> GetKeyEncryptedAsync(string userId = null);
|
||||
Task SetKeyEncryptedAsync(string value, string userId = null);
|
||||
Task<SymmetricCryptoKey> GetKeyDecryptedAsync(string userId = null);
|
||||
Task SetKeyDecryptedAsync(SymmetricCryptoKey value, string userId = null);
|
||||
Task<string> GetKeyHashAsync(string userId = null);
|
||||
Task SetKeyHashAsync(string value, string userId = null);
|
||||
Task<string> GetEncKeyEncryptedAsync(string userId = null);
|
||||
Task SetEncKeyEncryptedAsync(string value, string userId = null);
|
||||
Task<Dictionary<string, string>> GetOrgKeysEncryptedAsync(string userId = null);
|
||||
Task SetOrgKeysEncryptedAsync(Dictionary<string, string> value, string userId = null);
|
||||
Task<string> GetPrivateKeyEncryptedAsync(string userId = null);
|
||||
Task SetPrivateKeyEncryptedAsync(string value, string userId = null);
|
||||
Task<List<string>> GetAutofillBlacklistedUrisAsync(string userId = null);
|
||||
Task SetAutofillBlacklistedUrisAsync(List<string> value, string userId = null);
|
||||
Task<bool?> GetAutofillTileAddedAsync(string userId = null);
|
||||
Task SetAutofillTileAddedAsync(bool? value, string userId = null);
|
||||
Task<string> GetEmailAsync(string userId = null);
|
||||
// Task SetEmailAsync(string value, string userId = null);
|
||||
Task<long?> GetLastActiveTimeAsync(string userId = null);
|
||||
Task SetLastActiveTimeAsync(long? value, string userId = null);
|
||||
Task<int?> GetVaultTimeoutAsync(string userId = null);
|
||||
Task SetVaultTimeoutAsync(int? value, string userId = null);
|
||||
Task<string> GetVaultTimeoutActionAsync(string userId = null);
|
||||
Task SetVaultTimeoutActionAsync(string value, string userId = null);
|
||||
Task<DateTime?> GetLastFileCacheClearAsync(string userId = null);
|
||||
Task SetLastFileCacheClearAsync(DateTime? value, string userId = null);
|
||||
Task<PreviousPageInfo> GetPreviousPageInfoAsync(string userId = null);
|
||||
Task SetPreviousPageInfoAsync(PreviousPageInfo value, string userId = null);
|
||||
Task<int> GetInvalidUnlockAttemptsAsync(string userId = null);
|
||||
Task SetInvalidUnlockAttemptsAsync(int? value, string userId = null);
|
||||
Task<string> GetLastBuildAsync(string userId = null);
|
||||
Task SetLastBuildAsync(string value, string userId = null);
|
||||
Task<bool?> GetDisableFaviconAsync(string userId = null);
|
||||
Task SetDisableFaviconAsync(bool? value, string userId = null);
|
||||
Task<bool?> GetDisableAutoTotpCopyAsync(string userId = null);
|
||||
Task SetDisableAutoTotpCopyAsync(bool? value, string userId = null);
|
||||
Task<bool?> GetInlineAutofillEnabledAsync(string userId = null);
|
||||
Task SetInlineAutofillEnabledAsync(bool? value, string userId = null);
|
||||
Task<bool?> GetAutofillDisableSavePromptAsync(string userId = null);
|
||||
Task SetAutofillDisableSavePromptAsync(bool? value, string userId = null);
|
||||
Task<Dictionary<string, Dictionary<string, object>>> GetLocalDataAsync(string userId = null);
|
||||
Task SetLocalDataAsync(Dictionary<string, Dictionary<string, object>> value, string userId = null);
|
||||
Task<Dictionary<string, CipherData>> GetEncryptedCiphersAsync(string userId = null);
|
||||
Task SetEncryptedCiphersAsync(Dictionary<string, CipherData> value, string userId = null);
|
||||
Task<int?> GetDefaultUriMatchAsync(string userId = null);
|
||||
Task SetDefaultUriMatchAsync(int? value, string userId = null);
|
||||
Task<HashSet<string>> GetNeverDomainsAsync(string userId = null);
|
||||
Task SetNeverDomainsAsync(HashSet<string> value, string userId = null);
|
||||
Task<int?> GetClearClipboardAsync(string userId = null);
|
||||
Task SetClearClipboardAsync(int? value, string userId = null);
|
||||
Task<Dictionary<string, CollectionData>> GetEncryptedCollectionsAsync(string userId = null);
|
||||
Task SetEncryptedCollectionsAsync(Dictionary<string, CollectionData> value, string userId = null);
|
||||
Task<bool> GetPasswordRepromptAutofillAsync(string userId = null);
|
||||
Task SetPasswordRepromptAutofillAsync(bool? value, string userId = null);
|
||||
Task<bool> GetPasswordVerifiedAutofillAsync(string userId = null);
|
||||
Task SetPasswordVerifiedAutofillAsync(bool? value, string userId = null);
|
||||
Task<DateTime?> GetLastSyncAsync(string userId = null);
|
||||
Task SetLastSyncAsync(DateTime? value, string userId = null);
|
||||
Task<string> GetSecurityStampAsync(string userId = null);
|
||||
Task SetSecurityStampAsync(string value, string userId = null);
|
||||
Task<bool> GetEmailVerifiedAsync(string userId = null);
|
||||
Task SetEmailVerifiedAsync(bool? value, string userId = null);
|
||||
Task<bool> GetForcePasswordReset(string userId = null);
|
||||
Task SetForcePasswordResetAsync(bool? value, string userId = null);
|
||||
Task<bool> GetSyncOnRefreshAsync(string userId = null);
|
||||
Task SetSyncOnRefreshAsync(bool? value, string userId = null);
|
||||
Task<string> GetRememberedEmailAsync(string userId = null);
|
||||
Task SetRememberedEmailAsync(string value, string userId = null);
|
||||
Task<bool?> GetRememberEmailAsync(string userId = null);
|
||||
Task SetRememberEmailAsync(bool? value, string userId = null);
|
||||
Task<string> GetRememberedOrgIdentifierAsync(string userId = null);
|
||||
Task SetRememberedOrgIdentifierAsync(string value, string userId = null);
|
||||
Task<bool?> GetRememberOrgIdentifierAsync(string userId = null);
|
||||
Task SetRememberOrgIdentifierAsync(bool? value, string userId = null);
|
||||
Task<string> GetThemeAsync(string userId = null);
|
||||
Task SetThemeAsync(string value, string userId = null);
|
||||
Task<bool?> GetAddSitePromptShownAsync(string userId = null);
|
||||
Task SetAddSitePromptShownAsync(bool? value, string userId = null);
|
||||
Task<bool?> GetMigratedFromV1Async(string userId = null);
|
||||
Task SetMigratedFromV1Async(bool? value, string userId = null);
|
||||
Task<bool?> GetMigratedFromV1AutofillPromptShownAsync(string userId = null);
|
||||
Task SetMigratedFromV1AutofillPromptShownAsync(bool? value, string userId = null);
|
||||
Task<bool?> GetTriedV1ResyncAsync(string userId = null);
|
||||
Task SetTriedV1ResyncAsync(bool? value, string userId = null);
|
||||
Task<bool?> GetPushInitialPromptShownAsync(string userId = null);
|
||||
Task SetPushInitialPromptShownAsync(bool? value, string userId = null);
|
||||
Task<DateTime?> GetPushLastRegistrationDateAsync(string userId = null);
|
||||
Task SetPushLastRegistrationDateAsync(DateTime? value, string userId = null);
|
||||
Task<string> GetPushCurrentTokenAsync(string userId = null);
|
||||
Task SetPushCurrentTokenAsync(string value, string userId = null);
|
||||
Task<List<EventData>> GetEventCollectionAsync(string userId = null);
|
||||
Task SetEventCollectionAsync(List<EventData> value, string userId = null);
|
||||
Task<Dictionary<string, FolderData>> GetEncryptedFoldersAsync(string userId = null);
|
||||
Task SetEncryptedFoldersAsync(Dictionary<string, FolderData> value, string userId = null);
|
||||
Task<Dictionary<string, PolicyData>> GetEncryptedPoliciesAsync(string userId = null);
|
||||
Task SetEncryptedPoliciesAsync(Dictionary<string, PolicyData> value, string userId = null);
|
||||
Task<string> GetPushRegisteredTokenAsync(string userId = null);
|
||||
Task SetPushRegisteredTokenAsync(string value, string userId = null);
|
||||
Task<bool?> GetAppExtensionStartedAsync(string userId = null);
|
||||
Task SetAppExtensionStartedAsync(bool? value, string userId = null);
|
||||
Task<bool?> GetAppExtensionActivatedAsync(string userId = null);
|
||||
Task SetAppExtensionActivatedAsync(bool? value, string userId = null);
|
||||
Task<string> GetAppIdAsync(string userId = null);
|
||||
Task SetAppIdAsync(string value, string userId = null);
|
||||
Task<bool> GetUsesKeyConnectorAsync(string userId = null);
|
||||
Task SetUsesKeyConnectorAsync(bool? value, string userId = null);
|
||||
Task<Dictionary<string, OrganizationData>> GetOrganizationsAsync(string userId = null);
|
||||
Task SetOrganizationsAsync(Dictionary<string, OrganizationData> organizations, string userId = null);
|
||||
Task<PasswordGenerationOptions> GetPasswordGenerationOptionsAsync(string userId = null);
|
||||
Task SetPasswordGenerationOptionsAsync(PasswordGenerationOptions value, string userId = null);
|
||||
Task<List<GeneratedPasswordHistory>> GetEncryptedPasswordGenerationHistory(string userId = null);
|
||||
Task SetEncryptedPasswordGenerationHistoryAsync(List<GeneratedPasswordHistory> value, string userId = null);
|
||||
Task<Dictionary<string, SendData>> GetEncryptedSendsAsync(string userId = null);
|
||||
Task SetEncryptedSendsAsync(Dictionary<string, SendData> value, string userId = null);
|
||||
Task<Dictionary<string, object>> GetSettingsAsync(string userId = null);
|
||||
Task SetSettingsAsync(Dictionary<string, object> value, string userId = null);
|
||||
Task<string> GetAccessTokenAsync(string userId = null);
|
||||
Task SetAccessTokenAsync(string value, string userId = null);
|
||||
Task<string> GetRefreshTokenAsync(string userId = null);
|
||||
Task SetRefreshTokenAsync(string value, string userId = null);
|
||||
Task<string> GetTwoFactorTokenAsync(string email = null);
|
||||
Task SetTwoFactorTokenAsync(string value, string email = null);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Models.Data;
|
||||
using Bit.Core.Models.Domain;
|
||||
|
||||
namespace Bit.Core.Abstractions
|
||||
{
|
||||
public interface IUserService
|
||||
{
|
||||
Task<bool> CanAccessPremiumAsync();
|
||||
Task ClearAsync();
|
||||
Task ClearOrganizationsAsync(string userId);
|
||||
Task<List<Organization>> GetAllOrganizationAsync();
|
||||
Task<string> GetEmailAsync();
|
||||
Task<KdfType?> GetKdfAsync();
|
||||
Task<int?> GetKdfIterationsAsync();
|
||||
Task<Organization> GetOrganizationAsync(string id);
|
||||
Task<Organization> GetOrganizationByIdentifierAsync(string identifier);
|
||||
Task<string> GetSecurityStampAsync();
|
||||
Task<bool> GetEmailVerifiedAsync();
|
||||
Task<bool> GetForcePasswordReset();
|
||||
Task<string> GetUserIdAsync();
|
||||
Task<bool> IsAuthenticatedAsync();
|
||||
Task ReplaceOrganizationsAsync(Dictionary<string, OrganizationData> organizations);
|
||||
Task SetInformationAsync(string userId, string email, KdfType kdf, int? kdfIterations);
|
||||
Task SetSecurityStampAsync(string stamp);
|
||||
Task SetEmailVerifiedAsync(bool emailVerified);
|
||||
Task SetForcePasswordReset(bool forcePasswordReset);
|
||||
}
|
||||
}
|
||||
@@ -11,7 +11,7 @@ namespace Bit.Core.Abstractions
|
||||
Task<Tuple<bool, bool>> IsPinLockSetAsync();
|
||||
Task<bool> IsBiometricLockSetAsync();
|
||||
Task LockAsync(bool allowSoftLock = false, bool userInitiated = false, string userId = null);
|
||||
Task LogOutAsync(string userId = null);
|
||||
Task LogOutAsync(bool userInitiated = true, string userId = null);
|
||||
Task SetVaultTimeoutOptionsAsync(int? timeout, string action);
|
||||
Task<int?> GetVaultTimeout(string userId = null);
|
||||
}
|
||||
|
||||
@@ -64,8 +64,6 @@
|
||||
public static string PassGenOptionsKey(string userId) => $"passwordGenerationOptions_{userId}";
|
||||
public static string PassGenHistoryKey(string userId) => $"generatedPasswordHistory_{userId}";
|
||||
public static string TwoFactorTokenKey(string email) => $"twoFactorToken_{email}";
|
||||
public static string VaultTimeoutKey(string userId) => $"vaultTimeout_{userId}";
|
||||
public static string VaultTimeoutActionKey(string userId) => $"vaultTimeoutAction_{userId}";
|
||||
public static string LastActiveTimeKey(string userId) => $"lastActiveTime_{userId}";
|
||||
public static string InvalidUnlockAttemptsKey(string userId) => $"invalidUnlockAttempts_{userId}";
|
||||
public static string InlineAutofillEnabledKey(string userId) => $"inlineAutofillEnabled_{userId}";
|
||||
@@ -83,8 +81,6 @@
|
||||
public static string SettingsKey(string userId) => $"settings_{userId}";
|
||||
public static string UsesKeyConnectorKey(string userId) => $"usesKeyConnector_{userId}";
|
||||
public static string ProtectedPinKey(string userId) => $"protectedPin_{userId}";
|
||||
public static string SecurityStampKey(string userId) => $"securityStamp_{userId}";
|
||||
public static string EmailVerifiedKey(string userId) => $"emailVerified_{userId}";
|
||||
public static string ForcePasswordResetKey(string userId) => $"forcePasswordReset_{userId}";
|
||||
public static string LastSyncKey(string userId) => $"lastSync_{userId}";
|
||||
public static string BiometricUnlockKey(string userId) => $"biometricUnlock_{userId}";
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
using System.Collections.Generic;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Models.Data;
|
||||
|
||||
namespace Bit.Core.Models.Domain
|
||||
{
|
||||
public class Account : Domain
|
||||
{
|
||||
public AuthenticationStatus? AuthStatus;
|
||||
public AccountProfile Profile;
|
||||
public AccountTokens Tokens;
|
||||
public AccountSettings Settings;
|
||||
@@ -24,6 +24,7 @@ namespace Bit.Core.Models.Domain
|
||||
public Account(Account account)
|
||||
{
|
||||
// Copy constructor excludes Keys (for storage)
|
||||
AuthStatus = account.AuthStatus;
|
||||
Profile = new AccountProfile(account.Profile);
|
||||
Tokens = new AccountTokens(account.Tokens);
|
||||
Settings = new AccountSettings(account.Settings);
|
||||
@@ -42,18 +43,20 @@ namespace Bit.Core.Models.Domain
|
||||
|
||||
UserId = copy.UserId;
|
||||
Email = copy.Email;
|
||||
AuthStatus = copy.AuthStatus;
|
||||
HasPremiumPersonally = copy.HasPremiumPersonally;
|
||||
Stamp = copy.Stamp;
|
||||
KdfType = copy.KdfType;
|
||||
KdfIterations = copy.KdfIterations;
|
||||
EmailVerified = copy.EmailVerified;
|
||||
HasPremiumPersonally = copy.HasPremiumPersonally;
|
||||
}
|
||||
|
||||
public string UserId;
|
||||
public string Email;
|
||||
public AuthenticationStatus? AuthStatus;
|
||||
public bool? HasPremiumPersonally;
|
||||
public string Stamp;
|
||||
public KdfType? KdfType;
|
||||
public int? KdfIterations;
|
||||
public bool? EmailVerified;
|
||||
public bool? HasPremiumPersonally;
|
||||
}
|
||||
|
||||
public class AccountTokens
|
||||
@@ -88,21 +91,19 @@ namespace Bit.Core.Models.Domain
|
||||
|
||||
EnvironmentUrls = copy.EnvironmentUrls;
|
||||
PinProtected = copy.PinProtected;
|
||||
VaultTimeout = copy.VaultTimeout;
|
||||
VaultTimeoutAction = copy.VaultTimeoutAction;
|
||||
}
|
||||
|
||||
public EnvironmentUrlData EnvironmentUrls;
|
||||
public EncString PinProtected;
|
||||
public int? VaultTimeout;
|
||||
public string VaultTimeoutAction;
|
||||
}
|
||||
|
||||
public class AccountKeys
|
||||
{
|
||||
public SymmetricCryptoKey Key;
|
||||
public string KeyHash;
|
||||
public SymmetricCryptoKey EncKey;
|
||||
public Dictionary<string, SymmetricCryptoKey>
|
||||
OrganizationKeys = new Dictionary<string, SymmetricCryptoKey>();
|
||||
public byte[] PrivateKey;
|
||||
public byte[] PublicKey;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,17 +15,16 @@ namespace Bit.Core.Models.View
|
||||
return;
|
||||
}
|
||||
IsAccount = true;
|
||||
|
||||
UserId = a.Profile.UserId;
|
||||
Email = a.Profile.Email;
|
||||
Hostname = a.Settings.EnvironmentUrls.Base;
|
||||
AuthStatus = a.Profile.AuthStatus;
|
||||
AuthStatus = a.AuthStatus;
|
||||
UserId = a.Profile?.UserId;
|
||||
Email = a.Profile?.Email;
|
||||
Hostname = a.Settings?.EnvironmentUrls?.Base;
|
||||
}
|
||||
|
||||
public bool IsAccount { get; set; }
|
||||
public AuthenticationStatus? AuthStatus { get; set; }
|
||||
public string UserId { get; set; }
|
||||
public string Email { get; set; }
|
||||
public string Hostname { get; set; }
|
||||
public AuthenticationStatus? AuthStatus { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,12 +24,12 @@ namespace Bit.Core.Services
|
||||
private readonly HttpClient _httpClient = new HttpClient();
|
||||
private readonly ITokenService _tokenService;
|
||||
private readonly IPlatformUtilsService _platformUtilsService;
|
||||
private readonly Func<bool, Task> _logoutCallbackAsync;
|
||||
private readonly Func<Tuple<string, bool, bool>, Task> _logoutCallbackAsync;
|
||||
|
||||
public ApiService(
|
||||
ITokenService tokenService,
|
||||
IPlatformUtilsService platformUtilsService,
|
||||
Func<bool, Task> logoutCallbackAsync,
|
||||
Func<Tuple<string, bool, bool>, Task> logoutCallbackAsync,
|
||||
string customUserAgent = null)
|
||||
{
|
||||
_tokenService = tokenService;
|
||||
@@ -698,7 +698,7 @@ namespace Bit.Core.Services
|
||||
if (authed && ((tokenError && response.StatusCode == HttpStatusCode.BadRequest) ||
|
||||
response.StatusCode == HttpStatusCode.Unauthorized || response.StatusCode == HttpStatusCode.Forbidden))
|
||||
{
|
||||
await _logoutCallbackAsync(true);
|
||||
await _logoutCallbackAsync(new Tuple<string, bool, bool>(null, false, true));
|
||||
return null;
|
||||
}
|
||||
try
|
||||
|
||||
@@ -359,9 +359,9 @@ namespace Bit.Core.Services
|
||||
{
|
||||
UserId = _tokenService.GetUserId(),
|
||||
Email = _tokenService.GetEmail(),
|
||||
HasPremiumPersonally = _tokenService.GetPremium(),
|
||||
KdfType = tokenResponse.Kdf,
|
||||
KdfIterations = tokenResponse.KdfIterations,
|
||||
HasPremiumPersonally = _tokenService.GetPremium(),
|
||||
},
|
||||
new Account.AccountTokens()
|
||||
{
|
||||
|
||||
@@ -639,7 +639,7 @@ namespace Bit.Core.Services
|
||||
|
||||
public async Task ClearAsync(string userId)
|
||||
{
|
||||
await _stateService.SetEncryptedCiphersAsync(null, new StorageOptions { UserId = userId });
|
||||
await _stateService.SetEncryptedCiphersAsync(null, userId);
|
||||
await ClearCacheAsync();
|
||||
}
|
||||
|
||||
|
||||
@@ -181,7 +181,7 @@ namespace Bit.Core.Services
|
||||
|
||||
public async Task ClearAsync(string userId)
|
||||
{
|
||||
await _stateService.SetEncryptedCollectionsAsync(null, new StorageOptions { UserId = userId });
|
||||
await _stateService.SetEncryptedCollectionsAsync(null, userId);
|
||||
_decryptedCollectionCache = null;
|
||||
}
|
||||
|
||||
|
||||
@@ -17,7 +17,12 @@ namespace Bit.Core.Services
|
||||
private readonly IStateService _stateService;
|
||||
private readonly ICryptoFunctionService _cryptoFunctionService;
|
||||
|
||||
private SymmetricCryptoKey _encKey;
|
||||
private SymmetricCryptoKey _legacyEtmKey;
|
||||
private string _keyHash;
|
||||
private byte[] _publicKey;
|
||||
private byte[] _privateKey;
|
||||
private Dictionary<string, SymmetricCryptoKey> _orgKeys;
|
||||
private Task<SymmetricCryptoKey> _getEncKeysTask;
|
||||
private Task<Dictionary<string, SymmetricCryptoKey>> _getOrgKeysTask;
|
||||
|
||||
@@ -44,7 +49,7 @@ namespace Bit.Core.Services
|
||||
|
||||
public async Task SetKeyHashAsync(string keyHash)
|
||||
{
|
||||
await _stateService.SetKeyHashCachedAsync(keyHash);
|
||||
_keyHash = keyHash;
|
||||
await _stateService.SetKeyHashAsync(keyHash);
|
||||
}
|
||||
|
||||
@@ -55,7 +60,7 @@ namespace Bit.Core.Services
|
||||
return;
|
||||
}
|
||||
await _stateService.SetEncKeyEncryptedAsync(encKey);
|
||||
await _stateService.SetEncKeyDecryptedAsync(null);
|
||||
_encKey = null;
|
||||
}
|
||||
|
||||
public async Task SetEncPrivateKeyAsync(string encPrivateKey)
|
||||
@@ -65,13 +70,13 @@ namespace Bit.Core.Services
|
||||
return;
|
||||
}
|
||||
await _stateService.SetPrivateKeyEncryptedAsync(encPrivateKey);
|
||||
await _stateService.SetPrivateKeyDecryptedAsync(null);
|
||||
_privateKey = null;
|
||||
}
|
||||
|
||||
public async Task SetOrgKeysAsync(IEnumerable<ProfileOrganizationResponse> orgs)
|
||||
{
|
||||
var orgKeys = orgs.ToDictionary(org => org.Id, org => org.Key);
|
||||
await _stateService.SetOrgKeysDecryptedAsync(null);
|
||||
_orgKeys = null;
|
||||
await _stateService.SetOrgKeysEncryptedAsync(orgKeys);
|
||||
}
|
||||
|
||||
@@ -93,25 +98,23 @@ namespace Bit.Core.Services
|
||||
|
||||
public async Task<string> GetKeyHashAsync()
|
||||
{
|
||||
var inMemoryKeyHash = await _stateService.GetKeyHashCachedAsync();
|
||||
if (inMemoryKeyHash != null)
|
||||
if (_keyHash != null)
|
||||
{
|
||||
return inMemoryKeyHash;
|
||||
return _keyHash;
|
||||
}
|
||||
var keyHash = await _stateService.GetKeyHashAsync();
|
||||
if (keyHash != null)
|
||||
{
|
||||
await _stateService.SetKeyHashCachedAsync(keyHash);
|
||||
_keyHash = keyHash;
|
||||
}
|
||||
return keyHash;
|
||||
return _keyHash;
|
||||
}
|
||||
|
||||
public Task<SymmetricCryptoKey> GetEncKeyAsync(SymmetricCryptoKey key = null)
|
||||
{
|
||||
var inMemoryKey = _stateService.GetEncKeyDecryptedAsync().GetAwaiter().GetResult();
|
||||
if (inMemoryKey != null)
|
||||
if (_encKey != null)
|
||||
{
|
||||
return Task.FromResult(inMemoryKey);
|
||||
return Task.FromResult(_encKey);
|
||||
}
|
||||
if (_getEncKeysTask != null && !_getEncKeysTask.IsCompleted && !_getEncKeysTask.IsFaulted)
|
||||
{
|
||||
@@ -156,9 +159,8 @@ namespace Bit.Core.Services
|
||||
{
|
||||
return null;
|
||||
}
|
||||
var newEncKey = new SymmetricCryptoKey(decEncKey);
|
||||
await _stateService.SetEncKeyDecryptedAsync(newEncKey);
|
||||
return newEncKey;
|
||||
_encKey = new SymmetricCryptoKey(decEncKey);
|
||||
return _encKey;
|
||||
}
|
||||
finally
|
||||
{
|
||||
@@ -171,36 +173,32 @@ namespace Bit.Core.Services
|
||||
|
||||
public async Task<byte[]> GetPublicKeyAsync()
|
||||
{
|
||||
var inMemoryKey = await _stateService.GetPublicKeyAsync();
|
||||
if (inMemoryKey != null)
|
||||
if (_publicKey != null)
|
||||
{
|
||||
return inMemoryKey;
|
||||
return _publicKey;
|
||||
}
|
||||
var privateKey = await GetPrivateKeyAsync();
|
||||
if (privateKey == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
inMemoryKey = await _cryptoFunctionService.RsaExtractPublicKeyAsync(privateKey);
|
||||
await _stateService.SetPublicKeyAsync(inMemoryKey);
|
||||
return inMemoryKey;
|
||||
_publicKey = await _cryptoFunctionService.RsaExtractPublicKeyAsync(privateKey);
|
||||
return _publicKey;
|
||||
}
|
||||
|
||||
public async Task<byte[]> GetPrivateKeyAsync()
|
||||
{
|
||||
var inMemoryKey = await _stateService.GetPrivateKeyDecryptedAsync();
|
||||
if (inMemoryKey != null)
|
||||
if (_privateKey != null)
|
||||
{
|
||||
return inMemoryKey;
|
||||
return _privateKey;
|
||||
}
|
||||
var encPrivateKey = await _stateService.GetPrivateKeyEncryptedAsync();
|
||||
if (encPrivateKey == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
inMemoryKey = await DecryptToBytesAsync(new EncString(encPrivateKey), null);
|
||||
await _stateService.SetPrivateKeyDecryptedAsync(inMemoryKey);
|
||||
return inMemoryKey;
|
||||
_privateKey = await DecryptToBytesAsync(new EncString(encPrivateKey), null);
|
||||
return _privateKey;
|
||||
}
|
||||
|
||||
public async Task<List<string>> GetFingerprintAsync(string userId, byte[] publicKey = null)
|
||||
@@ -220,10 +218,9 @@ namespace Bit.Core.Services
|
||||
|
||||
public Task<Dictionary<string, SymmetricCryptoKey>> GetOrgKeysAsync()
|
||||
{
|
||||
var inMemoryKeys = _stateService.GetOrgKeysDecryptedAsync();
|
||||
if (inMemoryKeys != null && inMemoryKeys.Result.Count > 0)
|
||||
if (_orgKeys != null && _orgKeys.Count > 0)
|
||||
{
|
||||
return inMemoryKeys;
|
||||
return Task.FromResult(_orgKeys);
|
||||
}
|
||||
if (_getOrgKeysTask != null && !_getOrgKeysTask.IsCompleted && !_getOrgKeysTask.IsFaulted)
|
||||
{
|
||||
@@ -249,9 +246,9 @@ namespace Bit.Core.Services
|
||||
|
||||
if (setKey)
|
||||
{
|
||||
await _stateService.SetOrgKeysDecryptedAsync(orgKeys);
|
||||
_orgKeys = orgKeys;
|
||||
}
|
||||
return orgKeys;
|
||||
return _orgKeys;
|
||||
}
|
||||
finally
|
||||
{
|
||||
@@ -312,48 +309,57 @@ namespace Bit.Core.Services
|
||||
|
||||
public async Task ClearKeyAsync(string userId = null)
|
||||
{
|
||||
await _stateService.SetKeyDecryptedAsync(null, new StorageOptions { UserId = userId });
|
||||
await _stateService.SetKeyDecryptedAsync(null, userId);
|
||||
_legacyEtmKey = null;
|
||||
await _stateService.SetKeyEncryptedAsync(null, new StorageOptions { UserId = userId });
|
||||
await _stateService.SetKeyEncryptedAsync(null, userId);
|
||||
}
|
||||
|
||||
public async Task ClearKeyHashAsync(string userId = null)
|
||||
{
|
||||
await _stateService.SetKeyHashCachedAsync(null, new StorageOptions { UserId = userId });
|
||||
await _stateService.SetKeyHashAsync(null, new StorageOptions { UserId = userId });
|
||||
_keyHash = null;
|
||||
await _stateService.SetKeyHashAsync(null, userId);
|
||||
}
|
||||
|
||||
public async Task ClearEncKeyAsync(bool memoryOnly = false, string userId = null)
|
||||
{
|
||||
await _stateService.SetEncKeyDecryptedAsync(null, new StorageOptions { UserId = userId });
|
||||
_encKey = null;
|
||||
if (!memoryOnly)
|
||||
{
|
||||
await _stateService.SetEncKeyEncryptedAsync(null, new StorageOptions { UserId = userId });
|
||||
await _stateService.SetEncKeyEncryptedAsync(null, userId);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task ClearKeyPairAsync(bool memoryOnly = false, string userId = null)
|
||||
{
|
||||
await _stateService.SetPublicKeyAsync(null, new StorageOptions { UserId = userId });
|
||||
await _stateService.SetPrivateKeyDecryptedAsync(null, new StorageOptions { UserId = userId });
|
||||
_publicKey = _privateKey = null;
|
||||
if (!memoryOnly)
|
||||
{
|
||||
await _stateService.SetPrivateKeyEncryptedAsync(null, new StorageOptions { UserId = userId });
|
||||
await _stateService.SetPrivateKeyEncryptedAsync(null, userId);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task ClearOrgKeysAsync(bool memoryOnly = false, string userId = null)
|
||||
{
|
||||
await _stateService.SetOrgKeysDecryptedAsync(null, new StorageOptions { UserId = userId });
|
||||
_orgKeys = null;
|
||||
if (!memoryOnly)
|
||||
{
|
||||
await _stateService.SetOrgKeysEncryptedAsync(null, new StorageOptions { UserId = userId });
|
||||
await _stateService.SetOrgKeysEncryptedAsync(null, userId);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task ClearPinProtectedKeyAsync(string userId = null)
|
||||
{
|
||||
await _stateService.SetPinProtectedAsync(null, new StorageOptions { UserId = userId });
|
||||
await _stateService.SetPinProtectedAsync(null, userId);
|
||||
}
|
||||
|
||||
public void ClearCache()
|
||||
{
|
||||
_encKey = null;
|
||||
_legacyEtmKey = null;
|
||||
_keyHash = null;
|
||||
_publicKey = null;
|
||||
_privateKey = null;
|
||||
_orgKeys = null;
|
||||
}
|
||||
|
||||
public async Task ClearKeysAsync(string userId = null)
|
||||
|
||||
@@ -192,7 +192,7 @@ namespace Bit.Core.Services
|
||||
|
||||
public async Task ClearAsync(string userId)
|
||||
{
|
||||
await _stateService.SetEncryptedFoldersAsync(null, new StorageOptions { UserId = userId });
|
||||
await _stateService.SetEncryptedFoldersAsync(null, userId);
|
||||
_decryptedFolderCache = null;
|
||||
}
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ namespace Bit.Core.Services
|
||||
|
||||
public async Task<List<Organization>> GetAllAsync(string userId = null)
|
||||
{
|
||||
var organizations = await _stateService.GetOrganizationsAsync(new StorageOptions { UserId = userId });
|
||||
var organizations = await _stateService.GetOrganizationsAsync(userId);
|
||||
return organizations?.Select(o => new Organization(o.Value)).ToList() ?? new List<Organization>();
|
||||
}
|
||||
|
||||
@@ -49,7 +49,7 @@ namespace Bit.Core.Services
|
||||
|
||||
public async Task ClearAllAsync(string userId)
|
||||
{
|
||||
await _stateService.SetOrganizationsAsync(null, new StorageOptions { UserId = userId });
|
||||
await _stateService.SetOrganizationsAsync(null, userId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -483,8 +483,7 @@ namespace Bit.Core.Services
|
||||
public async Task ClearAsync(string userId = null)
|
||||
{
|
||||
_history = new List<GeneratedPasswordHistory>();
|
||||
await _stateService.SetEncryptedPasswordGenerationHistoryAsync(null,
|
||||
new StorageOptions { UserId = userId });
|
||||
await _stateService.SetEncryptedPasswordGenerationHistoryAsync(null, userId);
|
||||
}
|
||||
|
||||
public Result PasswordStrength(string password, List<string> userInputs = null)
|
||||
|
||||
@@ -60,7 +60,7 @@ namespace Bit.Core.Services
|
||||
|
||||
public async Task Clear(string userId)
|
||||
{
|
||||
await _stateService.SetEncryptedPoliciesAsync(null, new StorageOptions { UserId = userId });
|
||||
await _stateService.SetEncryptedPoliciesAsync(null, userId);
|
||||
_policyCache = null;
|
||||
}
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@ namespace Bit.Core.Services
|
||||
|
||||
public async Task ClearAsync(string userId)
|
||||
{
|
||||
await _stateService.SetEncryptedSendsAsync(null, new StorageOptions { UserId = userId });
|
||||
await _stateService.SetEncryptedSendsAsync(null, userId);
|
||||
ClearCache();
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.Core.Models.Domain;
|
||||
|
||||
namespace Bit.Core.Services
|
||||
{
|
||||
@@ -44,7 +43,7 @@ namespace Bit.Core.Services
|
||||
|
||||
public async Task ClearAsync(string userId)
|
||||
{
|
||||
await _stateService.SetSettingsAsync(null, new StorageOptions { UserId = userId });
|
||||
await _stateService.SetSettingsAsync(null, userId);
|
||||
ClearCache();
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -24,7 +24,7 @@ namespace Bit.Core.Services
|
||||
private readonly IPolicyService _policyService;
|
||||
private readonly ISendService _sendService;
|
||||
private readonly IKeyConnectorService _keyConnectorService;
|
||||
private readonly Func<bool, Task> _logoutCallbackAsync;
|
||||
private readonly Func<Tuple<string, bool, bool>, Task> _logoutCallbackAsync;
|
||||
|
||||
public SyncService(
|
||||
IStateService stateService,
|
||||
@@ -39,7 +39,7 @@ namespace Bit.Core.Services
|
||||
IPolicyService policyService,
|
||||
ISendService sendService,
|
||||
IKeyConnectorService keyConnectorService,
|
||||
Func<bool, Task> logoutCallbackAsync)
|
||||
Func<Tuple<string, bool, bool>, Task> logoutCallbackAsync)
|
||||
{
|
||||
_stateService = stateService;
|
||||
_apiService = apiService;
|
||||
@@ -316,7 +316,7 @@ namespace Bit.Core.Services
|
||||
{
|
||||
if (_logoutCallbackAsync != null)
|
||||
{
|
||||
await _logoutCallbackAsync(true);
|
||||
await _logoutCallbackAsync(new Tuple<string, bool, bool>(response.Id, false, true));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -5,7 +5,6 @@ using System;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Linq;
|
||||
using Bit.Core.Models.Domain;
|
||||
|
||||
namespace Bit.Core.Services
|
||||
{
|
||||
@@ -94,25 +93,25 @@ namespace Bit.Core.Services
|
||||
|
||||
public async Task SetTwoFactorTokenAsync(string token, string email)
|
||||
{
|
||||
await _stateService.SetTwoFactorTokenAsync(token, new StorageOptions { Email = email });
|
||||
await _stateService.SetTwoFactorTokenAsync(token, email);
|
||||
}
|
||||
|
||||
public async Task<string> GetTwoFactorTokenAsync(string email)
|
||||
{
|
||||
return await _stateService.GetTwoFactorTokenAsync(new StorageOptions { Email = email });
|
||||
return await _stateService.GetTwoFactorTokenAsync(email);
|
||||
}
|
||||
|
||||
public async Task ClearTwoFactorTokenAsync(string email)
|
||||
{
|
||||
await _stateService.SetTwoFactorTokenAsync(null, new StorageOptions { Email = email });
|
||||
await _stateService.SetTwoFactorTokenAsync(null, email);
|
||||
}
|
||||
|
||||
public async Task ClearTokenAsync(string userId = null)
|
||||
{
|
||||
ClearCache();
|
||||
await Task.WhenAll(
|
||||
_stateService.SetAccessTokenAsync(null, new StorageOptions { UserId = userId }),
|
||||
_stateService.SetRefreshTokenAsync(null, new StorageOptions { UserId = userId }));
|
||||
_stateService.SetAccessTokenAsync(null, userId),
|
||||
_stateService.SetRefreshTokenAsync(null, userId));
|
||||
}
|
||||
|
||||
public void ClearCache()
|
||||
|
||||
@@ -1,221 +0,0 @@
|
||||
using Bit.Core.Abstractions;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Models.Data;
|
||||
using Bit.Core.Models.Domain;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Bit.Core.Services
|
||||
{
|
||||
public class UserService : IUserService
|
||||
{
|
||||
private string _userId;
|
||||
private string _email;
|
||||
private string _stamp;
|
||||
private KdfType? _kdf;
|
||||
private int? _kdfIterations;
|
||||
private bool? _emailVerified;
|
||||
private bool? _forcePasswordReset;
|
||||
|
||||
private const string Keys_UserId = "userId";
|
||||
private const string Keys_UserEmail = "userEmail";
|
||||
private const string Keys_Stamp = "securityStamp";
|
||||
private const string Keys_Kdf = "kdf";
|
||||
private const string Keys_KdfIterations = "kdfIterations";
|
||||
private const string Keys_OrganizationsFormat = "organizations_{0}";
|
||||
private const string Keys_EmailVerified = "emailVerified";
|
||||
private const string Keys_ForcePasswordReset = "forcePasswordReset";
|
||||
|
||||
private readonly IStorageService _storageService;
|
||||
private readonly ITokenService _tokenService;
|
||||
|
||||
public UserService(IStorageService storageService, ITokenService tokenService)
|
||||
{
|
||||
_storageService = storageService;
|
||||
_tokenService = tokenService;
|
||||
}
|
||||
|
||||
public async Task SetInformationAsync(string userId, string email, KdfType kdf, int? kdfIterations)
|
||||
{
|
||||
_email = email;
|
||||
_userId = userId;
|
||||
_kdf = kdf;
|
||||
_kdfIterations = kdfIterations;
|
||||
await Task.WhenAll(
|
||||
_storageService.SaveAsync(Keys_UserEmail, email),
|
||||
_storageService.SaveAsync(Keys_UserId, userId),
|
||||
_storageService.SaveAsync(Keys_Kdf, (int)kdf),
|
||||
_storageService.SaveAsync(Keys_KdfIterations, kdfIterations));
|
||||
}
|
||||
|
||||
public async Task SetSecurityStampAsync(string stamp)
|
||||
{
|
||||
_stamp = stamp;
|
||||
await _storageService.SaveAsync(Keys_Stamp, stamp);
|
||||
}
|
||||
|
||||
public async Task SetEmailVerifiedAsync(bool emailVerified)
|
||||
{
|
||||
_emailVerified = emailVerified;
|
||||
await _storageService.SaveAsync(Keys_EmailVerified, emailVerified);
|
||||
}
|
||||
|
||||
public async Task SetForcePasswordReset(bool forcePasswordReset)
|
||||
{
|
||||
_forcePasswordReset = forcePasswordReset;
|
||||
await _storageService.SaveAsync(Keys_ForcePasswordReset, forcePasswordReset);
|
||||
}
|
||||
|
||||
public async Task<string> GetUserIdAsync()
|
||||
{
|
||||
if (_userId == null)
|
||||
{
|
||||
_userId = await _storageService.GetAsync<string>(Keys_UserId);
|
||||
}
|
||||
return _userId;
|
||||
}
|
||||
|
||||
public async Task<string> GetEmailAsync()
|
||||
{
|
||||
if (_email == null)
|
||||
{
|
||||
_email = await _storageService.GetAsync<string>(Keys_UserEmail);
|
||||
}
|
||||
return _email;
|
||||
}
|
||||
|
||||
public async Task<string> GetSecurityStampAsync()
|
||||
{
|
||||
if (_stamp == null)
|
||||
{
|
||||
_stamp = await _storageService.GetAsync<string>(Keys_Stamp);
|
||||
}
|
||||
return _stamp;
|
||||
}
|
||||
|
||||
public async Task<bool> GetEmailVerifiedAsync()
|
||||
{
|
||||
if (_emailVerified == null)
|
||||
{
|
||||
_emailVerified = await _storageService.GetAsync<bool>(Keys_EmailVerified);
|
||||
}
|
||||
return _emailVerified.GetValueOrDefault();
|
||||
}
|
||||
|
||||
public async Task<KdfType?> GetKdfAsync()
|
||||
{
|
||||
if (_kdf == null)
|
||||
{
|
||||
_kdf = (KdfType?)(await _storageService.GetAsync<int?>(Keys_Kdf));
|
||||
}
|
||||
return _kdf;
|
||||
}
|
||||
|
||||
public async Task<int?> GetKdfIterationsAsync()
|
||||
{
|
||||
if (_kdfIterations == null)
|
||||
{
|
||||
_kdfIterations = await _storageService.GetAsync<int?>(Keys_KdfIterations);
|
||||
}
|
||||
return _kdfIterations;
|
||||
}
|
||||
|
||||
public async Task<bool> GetForcePasswordReset()
|
||||
{
|
||||
if (_forcePasswordReset == null)
|
||||
{
|
||||
_forcePasswordReset = await _storageService.GetAsync<bool>(Keys_ForcePasswordReset);
|
||||
}
|
||||
return _forcePasswordReset.GetValueOrDefault();
|
||||
}
|
||||
|
||||
public async Task ClearAsync()
|
||||
{
|
||||
var userId = await GetUserIdAsync();
|
||||
await Task.WhenAll(
|
||||
_storageService.RemoveAsync(Keys_UserId),
|
||||
_storageService.RemoveAsync(Keys_UserEmail),
|
||||
_storageService.RemoveAsync(Keys_Stamp),
|
||||
_storageService.RemoveAsync(Keys_Kdf),
|
||||
_storageService.RemoveAsync(Keys_KdfIterations),
|
||||
_storageService.RemoveAsync(Keys_ForcePasswordReset),
|
||||
ClearOrganizationsAsync(userId));
|
||||
_userId = _email = _stamp = null;
|
||||
_kdf = null;
|
||||
_kdfIterations = null;
|
||||
}
|
||||
|
||||
public async Task<bool> IsAuthenticatedAsync()
|
||||
{
|
||||
var token = await _tokenService.GetTokenAsync();
|
||||
if (token == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
var userId = await GetUserIdAsync();
|
||||
return userId != null;
|
||||
}
|
||||
|
||||
public async Task<bool> CanAccessPremiumAsync()
|
||||
{
|
||||
var authed = await IsAuthenticatedAsync();
|
||||
if (!authed)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var tokenPremium = _tokenService.GetPremium();
|
||||
if (tokenPremium)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
var orgs = await GetAllOrganizationAsync();
|
||||
return orgs?.Any(o => o.UsersGetPremium && o.Enabled) ?? false;
|
||||
}
|
||||
|
||||
public async Task<Organization> GetOrganizationAsync(string id)
|
||||
{
|
||||
var userId = await GetUserIdAsync();
|
||||
var organizations = await _storageService.GetAsync<Dictionary<string, OrganizationData>>(
|
||||
string.Format(Keys_OrganizationsFormat, userId));
|
||||
if (organizations == null || !organizations.ContainsKey(id))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return new Organization(organizations[id]);
|
||||
}
|
||||
|
||||
public async Task<Organization> GetOrganizationByIdentifierAsync(string identifier)
|
||||
{
|
||||
var userId = await GetUserIdAsync();
|
||||
var organizations = await GetAllOrganizationAsync();
|
||||
|
||||
if (organizations == null || organizations.Count == 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return organizations.FirstOrDefault(o => o.Identifier == identifier);
|
||||
}
|
||||
|
||||
public async Task<List<Organization>> GetAllOrganizationAsync()
|
||||
{
|
||||
var userId = await GetUserIdAsync();
|
||||
var organizations = await _storageService.GetAsync<Dictionary<string, OrganizationData>>(
|
||||
string.Format(Keys_OrganizationsFormat, userId));
|
||||
return organizations?.Select(o => new Organization(o.Value)).ToList() ?? new List<Organization>();
|
||||
}
|
||||
|
||||
public async Task ReplaceOrganizationsAsync(Dictionary<string, OrganizationData> organizations)
|
||||
{
|
||||
var userId = await GetUserIdAsync();
|
||||
await _storageService.SaveAsync(string.Format(Keys_OrganizationsFormat, userId), organizations);
|
||||
}
|
||||
|
||||
public async Task ClearOrganizationsAsync(string userId)
|
||||
{
|
||||
await _storageService.RemoveAsync(string.Format(Keys_OrganizationsFormat, userId));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,4 @@
|
||||
using Bit.Core.Abstractions;
|
||||
using Bit.Core.Models.Domain;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
@@ -21,7 +20,7 @@ namespace Bit.Core.Services
|
||||
private readonly IPolicyService _policyService;
|
||||
private readonly IKeyConnectorService _keyConnectorService;
|
||||
private readonly Action<bool> _lockedCallback;
|
||||
private readonly Func<Tuple<bool, string>, Task> _loggedOutCallback;
|
||||
private readonly Func<Tuple<string, bool, bool>, Task> _loggedOutCallback;
|
||||
|
||||
public VaultTimeoutService(
|
||||
ICryptoService cryptoService,
|
||||
@@ -36,7 +35,7 @@ namespace Bit.Core.Services
|
||||
IPolicyService policyService,
|
||||
IKeyConnectorService keyConnectorService,
|
||||
Action<bool> lockedCallback,
|
||||
Func<Tuple<bool, string>, Task> loggedOutCallback)
|
||||
Func<Tuple<string, bool, bool>, Task> loggedOutCallback)
|
||||
{
|
||||
_cryptoService = cryptoService;
|
||||
_stateService = stateService;
|
||||
@@ -74,18 +73,18 @@ namespace Bit.Core.Services
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var account in _stateService.Accounts)
|
||||
foreach (var userId in await _stateService.GetUserIdsAsync())
|
||||
{
|
||||
if (account.UserId != null && await ShouldLockAsync(account.UserId))
|
||||
if (userId != null && await ShouldLockAsync(userId))
|
||||
{
|
||||
await ExecuteTimeoutActionAsync(account.UserId);
|
||||
await ExecuteTimeoutActionAsync(userId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<bool> ShouldLockAsync(string userId)
|
||||
{
|
||||
var authed = await _stateService.IsAuthenticatedAsync(new StorageOptions { UserId = userId });
|
||||
var authed = await _stateService.IsAuthenticatedAsync(userId);
|
||||
if (!authed)
|
||||
{
|
||||
return false;
|
||||
@@ -99,7 +98,7 @@ namespace Bit.Core.Services
|
||||
{
|
||||
return false;
|
||||
}
|
||||
var lastActiveTime = await _stateService.GetLastActiveTimeAsync(new StorageOptions { UserId = userId });
|
||||
var lastActiveTime = await _stateService.GetLastActiveTimeAsync(userId);
|
||||
if (lastActiveTime == null)
|
||||
{
|
||||
return false;
|
||||
@@ -111,10 +110,10 @@ namespace Bit.Core.Services
|
||||
|
||||
private async Task ExecuteTimeoutActionAsync(string userId)
|
||||
{
|
||||
var action = await _stateService.GetVaultTimeoutActionAsync(new StorageOptions { UserId = userId });
|
||||
var action = await _stateService.GetVaultTimeoutActionAsync(userId);
|
||||
if (action == "logOut")
|
||||
{
|
||||
await LogOutAsync(userId);
|
||||
await LogOutAsync(false, userId);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -124,7 +123,7 @@ namespace Bit.Core.Services
|
||||
|
||||
public async Task LockAsync(bool allowSoftLock = false, bool userInitiated = false, string userId = null)
|
||||
{
|
||||
var authed = await _stateService.IsAuthenticatedAsync(new StorageOptions { UserId = userId });
|
||||
var authed = await _stateService.IsAuthenticatedAsync(userId);
|
||||
if (!authed)
|
||||
{
|
||||
return;
|
||||
@@ -136,7 +135,7 @@ namespace Bit.Core.Services
|
||||
|
||||
if (!pinLock && !await IsBiometricLockSetAsync())
|
||||
{
|
||||
await LogOutAsync();
|
||||
await LogOutAsync(userInitiated, userId);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -172,11 +171,11 @@ namespace Bit.Core.Services
|
||||
_lockedCallback?.Invoke(userInitiated);
|
||||
}
|
||||
|
||||
public async Task LogOutAsync(string userId = null)
|
||||
public async Task LogOutAsync(bool userInitiated = true, string userId = null)
|
||||
{
|
||||
if(_loggedOutCallback != null)
|
||||
{
|
||||
await _loggedOutCallback.Invoke(new Tuple<bool, string>(false, userId));
|
||||
await _loggedOutCallback.Invoke(new Tuple<string, bool, bool>(userId, userInitiated, false));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -203,8 +202,8 @@ namespace Bit.Core.Services
|
||||
|
||||
public async Task ClearAsync(string userId = null)
|
||||
{
|
||||
await _stateService.SetPinProtectedAsync(null, new StorageOptions { UserId = userId });
|
||||
await _stateService.SetProtectedPinAsync(null, new StorageOptions { UserId = userId });
|
||||
await _stateService.SetPinProtectedAsync(null, userId);
|
||||
await _stateService.SetProtectedPinAsync(null, userId);
|
||||
}
|
||||
|
||||
public async Task<int?> GetVaultTimeout(string userId = null) {
|
||||
|
||||
@@ -30,9 +30,9 @@ namespace Bit.Core.Utilities
|
||||
SearchService searchService = null;
|
||||
|
||||
var tokenService = new TokenService(stateService);
|
||||
var apiService = new ApiService(tokenService, platformUtilsService, (bool expired) =>
|
||||
var apiService = new ApiService(tokenService, platformUtilsService, (extras) =>
|
||||
{
|
||||
messagingService.Send("logout", expired);
|
||||
messagingService.Send("logout", extras);
|
||||
return Task.FromResult(0);
|
||||
}, customUserAgent);
|
||||
var appIdService = new AppIdService(stateService);
|
||||
@@ -59,9 +59,9 @@ namespace Bit.Core.Utilities
|
||||
});
|
||||
var syncService = new SyncService(stateService, apiService, settingsService, folderService, cipherService,
|
||||
cryptoService, collectionService, organizationService, messagingService, policyService, sendService,
|
||||
keyConnectorService, (bool expired) =>
|
||||
keyConnectorService, (extras) =>
|
||||
{
|
||||
messagingService.Send("logout", expired);
|
||||
messagingService.Send("logout", extras);
|
||||
return Task.FromResult(0);
|
||||
});
|
||||
var passwordGenerationService = new PasswordGenerationService(cryptoService, stateService,
|
||||
|
||||
@@ -145,7 +145,8 @@ namespace Bit.iOS
|
||||
{
|
||||
if (_deviceActionService.SystemMajorVersion() >= 12)
|
||||
{
|
||||
await ASCredentialIdentityStore.SharedStore?.RemoveAllCredentialIdentitiesAsync();
|
||||
// TODO make account-specific
|
||||
// await ASCredentialIdentityStore.SharedStore?.RemoveAllCredentialIdentitiesAsync();
|
||||
}
|
||||
}
|
||||
else if ((message.Command == "softDeletedCipher" || message.Command == "restoredCipher")
|
||||
|
||||
Reference in New Issue
Block a user