mirror of
https://github.com/bitwarden/mobile
synced 2026-01-09 03:53:15 +00:00
Account switching
This commit is contained in:
@@ -5,6 +5,5 @@ namespace Bit.Core.Abstractions
|
||||
public interface IAppIdService
|
||||
{
|
||||
Task<string> GetAppIdAsync();
|
||||
Task<string> GetAnonymousAppIdAsync();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,4 +22,4 @@ namespace Bit.Core.Abstractions
|
||||
Task UpsertAsync(CollectionData collection);
|
||||
Task UpsertAsync(List<CollectionData> collection);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,13 +9,13 @@ namespace Bit.Core.Abstractions
|
||||
{
|
||||
public interface ICryptoService
|
||||
{
|
||||
Task ClearEncKeyAsync(bool memoryOnly = false);
|
||||
Task ClearKeyAsync();
|
||||
Task ClearKeyHashAsync();
|
||||
Task ClearKeyPairAsync(bool memoryOnly = false);
|
||||
Task ClearKeysAsync();
|
||||
Task ClearOrgKeysAsync(bool memoryOnly = false);
|
||||
Task ClearPinProtectedKeyAsync();
|
||||
Task ClearEncKeyAsync(bool memoryOnly = false, string userId = null);
|
||||
Task ClearKeyAsync(string userId = null);
|
||||
Task ClearKeyHashAsync(string userId = null);
|
||||
Task ClearKeyPairAsync(bool memoryOnly = false, string userId = null);
|
||||
Task ClearKeysAsync(string userId = null);
|
||||
Task ClearOrgKeysAsync(bool memoryOnly = false, string userId = null);
|
||||
Task ClearPinProtectedKeyAsync(string userId = null);
|
||||
Task<byte[]> DecryptFromBytesAsync(byte[] encBytes, SymmetricCryptoKey key);
|
||||
Task<byte[]> DecryptToBytesAsync(EncString encString, SymmetricCryptoKey key = null);
|
||||
Task<string> DecryptToUtf8Async(EncString encString, SymmetricCryptoKey key = null);
|
||||
|
||||
@@ -9,4 +9,4 @@ namespace Bit.Core.Abstractions
|
||||
Task CollectAsync(EventType eventType, string cipherId = null, bool uploadImmediately = false);
|
||||
Task UploadEventsAsync();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,4 +23,4 @@ namespace Bit.Core.Abstractions
|
||||
Task UpsertAsync(FolderData folder);
|
||||
Task UpsertAsync(List<FolderData> folder);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
16
src/Core/Abstractions/IOrganizationService.cs
Normal file
16
src/Core/Abstractions/IOrganizationService.cs
Normal file
@@ -0,0 +1,16 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.Core.Models.Data;
|
||||
using Bit.Core.Models.Domain;
|
||||
|
||||
namespace Bit.Core.Abstractions
|
||||
{
|
||||
public interface IOrganizationService
|
||||
{
|
||||
Task<Organization> GetAsync(string id);
|
||||
Task<Organization> GetByIdentifierAsync(string identifier);
|
||||
Task<List<Organization>> GetAllAsync(string userId = null);
|
||||
Task ReplaceAsync(Dictionary<string, OrganizationData> organizations);
|
||||
Task ClearAllAsync(string userId);
|
||||
}
|
||||
}
|
||||
@@ -8,7 +8,8 @@ namespace Bit.Core.Abstractions
|
||||
public interface IPasswordGenerationService
|
||||
{
|
||||
Task AddHistoryAsync(string password, CancellationToken token = default(CancellationToken));
|
||||
Task ClearAsync();
|
||||
Task ClearAsync(string userId = null);
|
||||
void ClearCache();
|
||||
Task<string> GeneratePassphraseAsync(PasswordGenerationOptions options);
|
||||
Task<string> GeneratePasswordAsync(PasswordGenerationOptions options);
|
||||
Task<List<GeneratedPasswordHistory>> GetHistoryAsync();
|
||||
|
||||
@@ -10,4 +10,4 @@ namespace Bit.Core.Abstractions
|
||||
Task<List<List<string>>> GetEquivalentDomainsAsync();
|
||||
Task SetEquivalentDomainsAsync(List<List<string>> equivalentDomains);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,173 @@
|
||||
using System.Threading.Tasks;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Models.Data;
|
||||
using Bit.Core.Models.Domain;
|
||||
using Bit.Core.Models.View;
|
||||
using Bit.Core.Utilities;
|
||||
|
||||
namespace Bit.Core.Abstractions
|
||||
{
|
||||
public interface IStateService
|
||||
{
|
||||
Task<T> GetAsync<T>(string key);
|
||||
Task RemoveAsync(string key);
|
||||
Task SaveAsync<T>(string key, T obj);
|
||||
Task PurgeAsync();
|
||||
bool BiometricLocked { get; set; }
|
||||
ExtendedObservableCollection<AccountView> Accounts { get; set; }
|
||||
Task<string> GetActiveUserIdAsync(StorageOptions options = null);
|
||||
Task SetActiveUserAsync(string userId);
|
||||
Task<bool> IsAuthenticatedAsync(StorageOptions options = null);
|
||||
Task<bool> HasMultipleAccountsAsync();
|
||||
Task AddAccountAsync(Account account);
|
||||
// Task SetInformationAsync(string userId, string email, KdfType kdf, int? kdfIterations);
|
||||
Task CleanAsync(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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,15 +6,16 @@ namespace Bit.Core.Abstractions
|
||||
{
|
||||
public interface ITokenService
|
||||
{
|
||||
Task ClearTokenAsync();
|
||||
Task ClearTokenAsync(string userId = null);
|
||||
Task ClearTwoFactorTokenAsync(string email);
|
||||
void ClearCache();
|
||||
JObject DecodeToken();
|
||||
string GetEmail();
|
||||
bool GetEmailVerified();
|
||||
string GetIssuer();
|
||||
string GetName();
|
||||
bool GetPremium();
|
||||
bool GetIsExternal();
|
||||
Task<bool> GetIsExternal();
|
||||
Task<string> GetRefreshTokenAsync();
|
||||
Task<string> GetTokenAsync();
|
||||
Task ToggleTokensAsync();
|
||||
|
||||
@@ -1,22 +1,18 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.Core.Models.Domain;
|
||||
|
||||
namespace Bit.Core.Abstractions
|
||||
{
|
||||
public interface IVaultTimeoutService
|
||||
{
|
||||
EncString PinProtectedKey { get; set; }
|
||||
bool BiometricLocked { get; set; }
|
||||
|
||||
Task CheckVaultTimeoutAsync();
|
||||
Task ClearAsync();
|
||||
Task<bool> IsLockedAsync();
|
||||
Task ClearAsync(string userId = null);
|
||||
Task<bool> IsLockedAsync(string userId = null);
|
||||
Task<Tuple<bool, bool>> IsPinLockSetAsync();
|
||||
Task<bool> IsBiometricLockSetAsync();
|
||||
Task LockAsync(bool allowSoftLock = false, bool userInitiated = false);
|
||||
Task LogOutAsync();
|
||||
Task LockAsync(bool allowSoftLock = false, bool userInitiated = false, string userId = null);
|
||||
Task LogOutAsync(string userId = null);
|
||||
Task SetVaultTimeoutOptionsAsync(int? timeout, string action);
|
||||
Task<int?> GetVaultTimeout();
|
||||
Task<int?> GetVaultTimeout(string userId = null);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,29 +4,16 @@
|
||||
{
|
||||
public const string AndroidAppProtocol = "androidapp://";
|
||||
public const string iOSAppProtocol = "iosapp://";
|
||||
public static string SyncOnRefreshKey = "syncOnRefresh";
|
||||
public static string VaultTimeoutKey = "lockOption";
|
||||
public static string VaultTimeoutActionKey = "vaultTimeoutAction";
|
||||
public static string LastActiveTimeKey = "lastActiveTime";
|
||||
public static string BiometricUnlockKey = "fingerprintUnlock";
|
||||
public static string ProtectedPin = "protectedPin";
|
||||
public static string PinProtectedKey = "pinProtectedKey";
|
||||
public static string DefaultUriMatch = "defaultUriMatch";
|
||||
public static string DisableAutoTotpCopyKey = "disableAutoTotpCopy";
|
||||
public static string EnvironmentUrlsKey = "environmentUrls";
|
||||
public static string StateKey = "state";
|
||||
public static string AppIdKey = "appId";
|
||||
public static string PreAuthEnvironmentUrlsKey = "preAuthEnvironmentUrls";
|
||||
public static string LastFileCacheClearKey = "lastFileCacheClear";
|
||||
public static string AutofillDisableSavePromptKey = "autofillDisableSavePrompt";
|
||||
public static string AutofillBlacklistedUrisKey = "autofillBlacklistedUris";
|
||||
public static string AutofillTileAdded = "autofillTileAdded";
|
||||
public static string DisableFaviconKey = "disableFavicon";
|
||||
public static string PushRegisteredTokenKey = "pushRegisteredToken";
|
||||
public static string PushCurrentTokenKey = "pushCurrentToken";
|
||||
public static string PushLastRegistrationDateKey = "pushLastRegistrationDate";
|
||||
public static string PushInitialPromptShownKey = "pushInitialPromptShown";
|
||||
public static string ThemeKey = "theme";
|
||||
public static string ClearClipboardKey = "clearClipboard";
|
||||
public static string LastBuildKey = "lastBuild";
|
||||
public static string OldUserIdKey = "userId";
|
||||
public static string AddSitePromptShownKey = "addSitePromptShown";
|
||||
public static string ClearCiphersCacheKey = "clearCiphersCache";
|
||||
public static string BiometricIntegrityKey = "biometricIntegrityState";
|
||||
@@ -38,11 +25,12 @@
|
||||
public static string MigratedFromV1AutofillPromptShown = "migratedV1AutofillPromptShown";
|
||||
public static string TriedV1Resync = "triedV1Resync";
|
||||
public static string EventCollectionKey = "eventCollection";
|
||||
public static string PreviousPageKey = "previousPage";
|
||||
public static string InlineAutofillEnabledKey = "inlineAutofillEnabled";
|
||||
public static string InvalidUnlockAttempts = "invalidUnlockAttempts";
|
||||
public static string PasswordRepromptAutofillKey = "passwordRepromptAutofillKey";
|
||||
public static string PasswordVerifiedAutofillKey = "passwordVerifiedAutofillKey";
|
||||
public static string RememberEmailKey = "rememberEmail";
|
||||
public static string RememberedEmailKey = "rememberedEmail";
|
||||
public static string RememberOrgIdentifierKey = "rememberOrgIdentifier";
|
||||
public static string RememberedOrgIdentifierKey = "rememberedOrgIdentifier";
|
||||
public static string AppExtensionStartedKey = "appExtensionStarted";
|
||||
public static string AppExtensionActivatedKey = "appExtensionActivated";
|
||||
public const int SelectFileRequestCode = 42;
|
||||
public const int SelectFilePermissionRequestCode = 43;
|
||||
public const int SaveFileRequestCode = 44;
|
||||
@@ -58,5 +46,47 @@
|
||||
iOSAutoFillClearCiphersCacheKey,
|
||||
iOSExtensionClearCiphersCacheKey
|
||||
};
|
||||
|
||||
public static string CiphersKey(string userId) => $"ciphers_{userId}";
|
||||
public static string FoldersKey(string userId) => $"folders_{userId}";
|
||||
public static string CollectionsKey(string userId) => $"collections_{userId}";
|
||||
public static string OrganizationsKey(string userId) => $"organizations_{userId}";
|
||||
public static string LocalDataKey(string userId) => $"ciphersLocalData_{userId}";
|
||||
public static string NeverDomainsKey(string userId) => $"neverDomains_{userId}";
|
||||
public static string SendsKey(string userId) => $"sends_{userId}";
|
||||
public static string PoliciesKey(string userId) => $"policies_{userId}";
|
||||
public static string KeyKey(string userId) => $"key_{userId}";
|
||||
public static string EncOrgKeysKey(string userId) => $"encOrgKeys_{userId}";
|
||||
public static string EncPrivateKeyKey(string userId) => $"encPrivateKey_{userId}";
|
||||
public static string EncKeyKey(string userId) => $"encKey_{userId}";
|
||||
public static string KeyHashKey(string userId) => $"keyHash_{userId}";
|
||||
public static string PinProtectedKey(string userId) => $"pinProtectedKey_{userId}";
|
||||
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}";
|
||||
public static string AutofillDisableSavePromptKey(string userId) => $"autofillDisableSavePrompt_{userId}";
|
||||
public static string AutofillBlacklistedUrisKey(string userId) => $"autofillBlacklistedUris_{userId}";
|
||||
public static string ClearClipboardKey(string userId) => $"clearClipboard_{userId}";
|
||||
public static string SyncOnRefreshKey(string userId) => $"syncOnRefresh_{userId}";
|
||||
public static string DisableFaviconKey(string userId) => $"disableFavicon_{userId}";
|
||||
public static string DefaultUriMatchKey(string userId) => $"defaultUriMatch_{userId}";
|
||||
public static string ThemeKey(string userId) => $"theme_{userId}";
|
||||
public static string DisableAutoTotpCopyKey(string userId) => $"disableAutoTotpCopy_{userId}";
|
||||
public static string PreviousPageKey(string userId) => $"previousPage_{userId}";
|
||||
public static string PasswordRepromptAutofillKey(string userId) => $"passwordRepromptAutofillKey_{userId}";
|
||||
public static string PasswordVerifiedAutofillKey(string userId) => $"passwordVerifiedAutofillKey_{userId}";
|
||||
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}";
|
||||
}
|
||||
}
|
||||
|
||||
10
src/Core/Enums/AuthenticationStatus.cs
Normal file
10
src/Core/Enums/AuthenticationStatus.cs
Normal file
@@ -0,0 +1,10 @@
|
||||
namespace Bit.Core.Enums
|
||||
{
|
||||
public enum AuthenticationStatus : byte
|
||||
{
|
||||
LoggedOut = 0,
|
||||
Locked = 1,
|
||||
Unlocked = 2,
|
||||
Active = 3,
|
||||
}
|
||||
}
|
||||
9
src/Core/Enums/DiskStorageLocation.cs
Normal file
9
src/Core/Enums/DiskStorageLocation.cs
Normal file
@@ -0,0 +1,9 @@
|
||||
namespace Bit.Core.Enums
|
||||
{
|
||||
public enum DiskStorageLocation
|
||||
{
|
||||
Default = 1,
|
||||
Preferences = 2,
|
||||
SecureStorage = 3
|
||||
}
|
||||
}
|
||||
9
src/Core/Enums/StorageLocation.cs
Normal file
9
src/Core/Enums/StorageLocation.cs
Normal file
@@ -0,0 +1,9 @@
|
||||
namespace Bit.Core.Enums
|
||||
{
|
||||
public enum StorageLocation
|
||||
{
|
||||
Both = 0,
|
||||
Disk = 1,
|
||||
Memory = 2
|
||||
}
|
||||
}
|
||||
10
src/Core/Models/Data/PreviousPageInfo.cs
Normal file
10
src/Core/Models/Data/PreviousPageInfo.cs
Normal file
@@ -0,0 +1,10 @@
|
||||
namespace Bit.Core.Models.Data
|
||||
{
|
||||
public class PreviousPageInfo
|
||||
{
|
||||
public string Page { get; set; }
|
||||
public string CipherId { get; set; }
|
||||
public string SendId { get; set; }
|
||||
public string SearchText { get; set; }
|
||||
}
|
||||
}
|
||||
99
src/Core/Models/Domain/Account.cs
Normal file
99
src/Core/Models/Domain/Account.cs
Normal file
@@ -0,0 +1,99 @@
|
||||
using System.Collections.Generic;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Models.Data;
|
||||
|
||||
namespace Bit.Core.Models.Domain
|
||||
{
|
||||
public class Account : Domain
|
||||
{
|
||||
public AccountProfile Profile;
|
||||
public AccountTokens Tokens;
|
||||
public AccountSettings Settings;
|
||||
public AccountKeys Keys;
|
||||
|
||||
public Account() { }
|
||||
|
||||
public Account(AccountProfile profile, AccountTokens tokens)
|
||||
{
|
||||
Profile = profile;
|
||||
Tokens = tokens;
|
||||
Settings = new AccountSettings();
|
||||
Keys = new AccountKeys();
|
||||
}
|
||||
|
||||
public Account(Account account)
|
||||
{
|
||||
// Copy constructor excludes Keys (for storage)
|
||||
Profile = new AccountProfile(account.Profile);
|
||||
Tokens = new AccountTokens(account.Tokens);
|
||||
Settings = new AccountSettings(account.Settings);
|
||||
}
|
||||
|
||||
public class AccountProfile
|
||||
{
|
||||
public AccountProfile() { }
|
||||
|
||||
public AccountProfile(AccountProfile copy)
|
||||
{
|
||||
if (copy == null) { return;}
|
||||
|
||||
UserId = copy.UserId;
|
||||
Email = copy.Email;
|
||||
AuthStatus = copy.AuthStatus;
|
||||
HasPremiumPersonally = copy.HasPremiumPersonally;
|
||||
KdfType = copy.KdfType;
|
||||
KdfIterations = copy.KdfIterations;
|
||||
}
|
||||
|
||||
public string UserId;
|
||||
public string Email;
|
||||
public AuthenticationStatus? AuthStatus;
|
||||
public bool? HasPremiumPersonally;
|
||||
public KdfType? KdfType;
|
||||
public int? KdfIterations;
|
||||
}
|
||||
|
||||
public class AccountTokens
|
||||
{
|
||||
public AccountTokens() {}
|
||||
|
||||
public AccountTokens(AccountTokens copy)
|
||||
{
|
||||
if (copy == null) { return;}
|
||||
|
||||
AccessToken = copy.AccessToken;
|
||||
RefreshToken = copy.RefreshToken;
|
||||
}
|
||||
|
||||
public string AccessToken;
|
||||
public string RefreshToken;
|
||||
}
|
||||
|
||||
public class AccountSettings
|
||||
{
|
||||
public AccountSettings() {}
|
||||
|
||||
public AccountSettings(AccountSettings copy)
|
||||
{
|
||||
if (copy == null) { return;}
|
||||
|
||||
EnvironmentUrls = copy.EnvironmentUrls;
|
||||
PinProtected = copy.PinProtected;
|
||||
}
|
||||
|
||||
public EnvironmentUrlData EnvironmentUrls;
|
||||
public EncString PinProtected;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
10
src/Core/Models/Domain/GlobalState.cs
Normal file
10
src/Core/Models/Domain/GlobalState.cs
Normal file
@@ -0,0 +1,10 @@
|
||||
using System;
|
||||
|
||||
namespace Bit.Core.Models.Domain
|
||||
{
|
||||
public class GlobalState : Domain
|
||||
{
|
||||
public int? StateVersion { get; set; }
|
||||
public bool EnableBiometrics { get; set; }
|
||||
}
|
||||
}
|
||||
10
src/Core/Models/Domain/State.cs
Normal file
10
src/Core/Models/Domain/State.cs
Normal file
@@ -0,0 +1,10 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Bit.Core.Models.Domain
|
||||
{
|
||||
public class State : Domain
|
||||
{
|
||||
public Dictionary<string, Account> Accounts { get; set; }
|
||||
public string ActiveUserId { get; set; }
|
||||
}
|
||||
}
|
||||
12
src/Core/Models/Domain/StorageOptions.cs
Normal file
12
src/Core/Models/Domain/StorageOptions.cs
Normal file
@@ -0,0 +1,12 @@
|
||||
using Bit.Core.Enums;
|
||||
|
||||
namespace Bit.Core.Models.Domain
|
||||
{
|
||||
public class StorageOptions : Domain
|
||||
{
|
||||
public StorageLocation? StorageLocation { get; set; }
|
||||
public bool? UseSecureStorage { get; set; }
|
||||
public string UserId { get; set; }
|
||||
public string Email { get; set; }
|
||||
}
|
||||
}
|
||||
31
src/Core/Models/View/AccountView.cs
Normal file
31
src/Core/Models/View/AccountView.cs
Normal file
@@ -0,0 +1,31 @@
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Models.Domain;
|
||||
|
||||
namespace Bit.Core.Models.View
|
||||
{
|
||||
public class AccountView : View
|
||||
{
|
||||
public AccountView() { }
|
||||
|
||||
public AccountView(Account a = null)
|
||||
{
|
||||
if (a == null)
|
||||
{
|
||||
// null will render as "Add Account" row
|
||||
return;
|
||||
}
|
||||
IsAccount = true;
|
||||
|
||||
UserId = a.Profile.UserId;
|
||||
Email = a.Profile.Email;
|
||||
Hostname = a.Settings.EnvironmentUrls.Base;
|
||||
AuthStatus = a.Profile.AuthStatus;
|
||||
}
|
||||
|
||||
public bool IsAccount { get; set; }
|
||||
public string UserId { get; set; }
|
||||
public string Email { get; set; }
|
||||
public string Hostname { get; set; }
|
||||
public AuthenticationStatus? AuthStatus { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -6,33 +6,28 @@ namespace Bit.Core.Services
|
||||
{
|
||||
public class AppIdService : IAppIdService
|
||||
{
|
||||
private readonly IStorageService _storageService;
|
||||
private readonly IStateService _stateService;
|
||||
|
||||
public AppIdService(IStorageService storageService)
|
||||
public AppIdService(IStateService stateService)
|
||||
{
|
||||
_storageService = storageService;
|
||||
_stateService = stateService;
|
||||
}
|
||||
|
||||
public Task<string> GetAppIdAsync()
|
||||
public async Task<string> GetAppIdAsync()
|
||||
{
|
||||
return MakeAndGetAppIdAsync("appId");
|
||||
}
|
||||
|
||||
public Task<string> GetAnonymousAppIdAsync()
|
||||
{
|
||||
return MakeAndGetAppIdAsync("anonymousAppId");
|
||||
}
|
||||
|
||||
private async Task<string> MakeAndGetAppIdAsync(string key)
|
||||
{
|
||||
var existingId = await _storageService.GetAsync<string>(key);
|
||||
if (existingId != null)
|
||||
var appId = await _stateService.GetAppIdAsync();
|
||||
if (appId != null)
|
||||
{
|
||||
return existingId;
|
||||
return appId;
|
||||
}
|
||||
var guid = Guid.NewGuid().ToString();
|
||||
await _storageService.SaveAsync(key, guid);
|
||||
return guid;
|
||||
appId = MakeAppId();
|
||||
await _stateService.SetAppIdAsync(appId);
|
||||
return appId;
|
||||
}
|
||||
|
||||
private string MakeAppId()
|
||||
{
|
||||
return Guid.NewGuid().ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,13 +14,12 @@ namespace Bit.Core.Services
|
||||
private readonly ICryptoService _cryptoService;
|
||||
private readonly ICryptoFunctionService _cryptoFunctionService;
|
||||
private readonly IApiService _apiService;
|
||||
private readonly IUserService _userService;
|
||||
private readonly IStateService _stateService;
|
||||
private readonly ITokenService _tokenService;
|
||||
private readonly IAppIdService _appIdService;
|
||||
private readonly II18nService _i18nService;
|
||||
private readonly IPlatformUtilsService _platformUtilsService;
|
||||
private readonly IMessagingService _messagingService;
|
||||
private readonly IVaultTimeoutService _vaultTimeoutService;
|
||||
private readonly IKeyConnectorService _keyConnectorService;
|
||||
private readonly bool _setCryptoKeys;
|
||||
|
||||
@@ -30,7 +29,7 @@ namespace Bit.Core.Services
|
||||
ICryptoService cryptoService,
|
||||
ICryptoFunctionService cryptoFunctionService,
|
||||
IApiService apiService,
|
||||
IUserService userService,
|
||||
IStateService stateService,
|
||||
ITokenService tokenService,
|
||||
IAppIdService appIdService,
|
||||
II18nService i18nService,
|
||||
@@ -43,13 +42,12 @@ namespace Bit.Core.Services
|
||||
_cryptoService = cryptoService;
|
||||
_cryptoFunctionService = cryptoFunctionService;
|
||||
_apiService = apiService;
|
||||
_userService = userService;
|
||||
_stateService = stateService;
|
||||
_tokenService = tokenService;
|
||||
_appIdService = appIdService;
|
||||
_i18nService = i18nService;
|
||||
_platformUtilsService = platformUtilsService;
|
||||
_messagingService = messagingService;
|
||||
_vaultTimeoutService = vaultTimeoutService;
|
||||
_keyConnectorService = keyConnectorService;
|
||||
_setCryptoKeys = setCryptoKeys;
|
||||
|
||||
@@ -355,8 +353,23 @@ namespace Bit.Core.Services
|
||||
await _tokenService.SetTwoFactorTokenAsync(tokenResponse.TwoFactorToken, email);
|
||||
}
|
||||
await _tokenService.SetTokensAsync(tokenResponse.AccessToken, tokenResponse.RefreshToken);
|
||||
await _userService.SetInformationAsync(_tokenService.GetUserId(), _tokenService.GetEmail(),
|
||||
tokenResponse.Kdf, tokenResponse.KdfIterations);
|
||||
await _stateService.AddAccountAsync(
|
||||
new Account(
|
||||
new Account.AccountProfile()
|
||||
{
|
||||
UserId = _tokenService.GetUserId(),
|
||||
Email = _tokenService.GetEmail(),
|
||||
HasPremiumPersonally = _tokenService.GetPremium(),
|
||||
KdfType = tokenResponse.Kdf,
|
||||
KdfIterations = tokenResponse.KdfIterations,
|
||||
},
|
||||
new Account.AccountTokens()
|
||||
{
|
||||
AccessToken = tokenResponse.AccessToken,
|
||||
RefreshToken = tokenResponse.RefreshToken,
|
||||
}
|
||||
)
|
||||
);
|
||||
if (_setCryptoKeys)
|
||||
{
|
||||
if (key != null)
|
||||
@@ -430,7 +443,7 @@ namespace Bit.Core.Services
|
||||
|
||||
}
|
||||
|
||||
_vaultTimeoutService.BiometricLocked = false;
|
||||
_stateService.BiometricLocked = false;
|
||||
_messagingService.Send("loggedIn");
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -19,15 +19,11 @@ namespace Bit.Core.Services
|
||||
{
|
||||
public class CipherService : ICipherService
|
||||
{
|
||||
private const string Keys_CiphersFormat = "ciphers_{0}";
|
||||
private const string Keys_LocalData = "ciphersLocalData";
|
||||
private const string Keys_NeverDomains = "neverDomains";
|
||||
|
||||
private readonly string[] _ignoredSearchTerms = new string[] { "com", "net", "org", "android",
|
||||
"io", "co", "uk", "au", "nz", "fr", "de", "tv", "info", "app", "apps", "eu", "me", "dev", "jp", "mobile" };
|
||||
private List<CipherView> _decryptedCipherCache;
|
||||
private readonly ICryptoService _cryptoService;
|
||||
private readonly IUserService _userService;
|
||||
private readonly IStateService _stateService;
|
||||
private readonly ISettingsService _settingsService;
|
||||
private readonly IApiService _apiService;
|
||||
private readonly IFileUploadService _fileUploadService;
|
||||
@@ -45,7 +41,7 @@ namespace Bit.Core.Services
|
||||
|
||||
public CipherService(
|
||||
ICryptoService cryptoService,
|
||||
IUserService userService,
|
||||
IStateService stateService,
|
||||
ISettingsService settingsService,
|
||||
IApiService apiService,
|
||||
IFileUploadService fileUploadService,
|
||||
@@ -56,7 +52,7 @@ namespace Bit.Core.Services
|
||||
string[] allClearCipherCacheKeys)
|
||||
{
|
||||
_cryptoService = cryptoService;
|
||||
_userService = userService;
|
||||
_stateService = stateService;
|
||||
_settingsService = settingsService;
|
||||
_apiService = apiService;
|
||||
_fileUploadService = fileUploadService;
|
||||
@@ -211,11 +207,8 @@ namespace Bit.Core.Services
|
||||
|
||||
public async Task<Cipher> GetAsync(string id)
|
||||
{
|
||||
var userId = await _userService.GetUserIdAsync();
|
||||
var localData = await _storageService.GetAsync<Dictionary<string, Dictionary<string, object>>>(
|
||||
Keys_LocalData);
|
||||
var ciphers = await _storageService.GetAsync<Dictionary<string, CipherData>>(
|
||||
string.Format(Keys_CiphersFormat, userId));
|
||||
var localData = await _stateService.GetLocalDataAsync();
|
||||
var ciphers = await _stateService.GetEncryptedCiphersAsync();
|
||||
if (!ciphers?.ContainsKey(id) ?? true)
|
||||
{
|
||||
return null;
|
||||
@@ -226,11 +219,8 @@ namespace Bit.Core.Services
|
||||
|
||||
public async Task<List<Cipher>> GetAllAsync()
|
||||
{
|
||||
var userId = await _userService.GetUserIdAsync();
|
||||
var localData = await _storageService.GetAsync<Dictionary<string, Dictionary<string, object>>>(
|
||||
Keys_LocalData);
|
||||
var ciphers = await _storageService.GetAsync<Dictionary<string, CipherData>>(
|
||||
string.Format(Keys_CiphersFormat, userId));
|
||||
var localData = await _stateService.GetLocalDataAsync();
|
||||
var ciphers = await _stateService.GetEncryptedCiphersAsync();
|
||||
var response = ciphers?.Select(c => new Cipher(c.Value, false,
|
||||
localData?.ContainsKey(c.Key) ?? false ? localData[c.Key] : null));
|
||||
return response?.ToList() ?? new List<Cipher>();
|
||||
@@ -347,7 +337,7 @@ namespace Bit.Core.Services
|
||||
var others = new List<CipherView>();
|
||||
var ciphers = await ciphersTask;
|
||||
|
||||
var defaultMatch = (UriMatchType?)(await _storageService.GetAsync<int?>(Constants.DefaultUriMatch));
|
||||
var defaultMatch = (UriMatchType?)(await _stateService.GetDefaultUriMatchAsync());
|
||||
if (defaultMatch == null)
|
||||
{
|
||||
defaultMatch = UriMatchType.Domain;
|
||||
@@ -457,8 +447,7 @@ namespace Bit.Core.Services
|
||||
|
||||
public async Task UpdateLastUsedDateAsync(string id)
|
||||
{
|
||||
var ciphersLocalData = await _storageService.GetAsync<Dictionary<string, Dictionary<string, object>>>(
|
||||
Keys_LocalData);
|
||||
var ciphersLocalData = await _stateService.GetLocalDataAsync();
|
||||
if (ciphersLocalData == null)
|
||||
{
|
||||
ciphersLocalData = new Dictionary<string, Dictionary<string, object>>();
|
||||
@@ -476,7 +465,7 @@ namespace Bit.Core.Services
|
||||
ciphersLocalData[id].Add("lastUsedDate", DateTime.UtcNow);
|
||||
}
|
||||
|
||||
await _storageService.SaveAsync(Keys_LocalData, ciphersLocalData);
|
||||
await _stateService.SetLocalDataAsync(ciphersLocalData);
|
||||
// Update cache
|
||||
if (DecryptedCipherCache == null)
|
||||
{
|
||||
@@ -495,13 +484,13 @@ namespace Bit.Core.Services
|
||||
{
|
||||
return;
|
||||
}
|
||||
var domains = await _storageService.GetAsync<HashSet<string>>(Keys_NeverDomains);
|
||||
var domains = await _stateService.GetNeverDomainsAsync();
|
||||
if (domains == null)
|
||||
{
|
||||
domains = new HashSet<string>();
|
||||
}
|
||||
domains.Add(domain);
|
||||
await _storageService.SaveAsync(Keys_NeverDomains, domains);
|
||||
await _stateService.SetNeverDomainsAsync(domains);
|
||||
}
|
||||
|
||||
public async Task SaveWithServerAsync(Cipher cipher)
|
||||
@@ -526,7 +515,7 @@ namespace Bit.Core.Services
|
||||
var request = new CipherRequest(cipher);
|
||||
response = await _apiService.PutCipherAsync(cipher.Id, request);
|
||||
}
|
||||
var userId = await _userService.GetUserIdAsync();
|
||||
var userId = await _stateService.GetActiveUserIdAsync();
|
||||
var data = new CipherData(response, userId, cipher.CollectionIds);
|
||||
await UpsertAsync(data);
|
||||
}
|
||||
@@ -550,7 +539,7 @@ namespace Bit.Core.Services
|
||||
var encCipher = await EncryptAsync(cipher);
|
||||
var request = new CipherShareRequest(encCipher);
|
||||
var response = await _apiService.PutShareCipherAsync(cipher.Id, request);
|
||||
var userId = await _userService.GetUserIdAsync();
|
||||
var userId = await _stateService.GetActiveUserIdAsync();
|
||||
var data = new CipherData(response, userId, collectionIds);
|
||||
await UpsertAsync(data);
|
||||
}
|
||||
@@ -581,7 +570,7 @@ namespace Bit.Core.Services
|
||||
response = await LegacyServerAttachmentFileUploadAsync(cipher.Id, encFileName, encFileData, orgEncAttachmentKey);
|
||||
}
|
||||
|
||||
var userId = await _userService.GetUserIdAsync();
|
||||
var userId = await _stateService.GetActiveUserIdAsync();
|
||||
var cData = new CipherData(response, userId, cipher.CollectionIds);
|
||||
await UpsertAsync(cData);
|
||||
return new Cipher(cData);
|
||||
@@ -602,16 +591,14 @@ namespace Bit.Core.Services
|
||||
{
|
||||
var request = new CipherCollectionsRequest(cipher.CollectionIds?.ToList());
|
||||
await _apiService.PutCipherCollectionsAsync(cipher.Id, request);
|
||||
var userId = await _userService.GetUserIdAsync();
|
||||
var userId = await _stateService.GetActiveUserIdAsync();
|
||||
var data = cipher.ToCipherData(userId);
|
||||
await UpsertAsync(data);
|
||||
}
|
||||
|
||||
public async Task UpsertAsync(CipherData cipher)
|
||||
{
|
||||
var userId = await _userService.GetUserIdAsync();
|
||||
var storageKey = string.Format(Keys_CiphersFormat, userId);
|
||||
var ciphers = await _storageService.GetAsync<Dictionary<string, CipherData>>(storageKey);
|
||||
var ciphers = await _stateService.GetEncryptedCiphersAsync();
|
||||
if (ciphers == null)
|
||||
{
|
||||
ciphers = new Dictionary<string, CipherData>();
|
||||
@@ -621,15 +608,13 @@ namespace Bit.Core.Services
|
||||
ciphers.Add(cipher.Id, null);
|
||||
}
|
||||
ciphers[cipher.Id] = cipher;
|
||||
await _storageService.SaveAsync(storageKey, ciphers);
|
||||
await _stateService.SetEncryptedCiphersAsync(ciphers);
|
||||
await ClearCacheAsync();
|
||||
}
|
||||
|
||||
public async Task UpsertAsync(List<CipherData> cipher)
|
||||
{
|
||||
var userId = await _userService.GetUserIdAsync();
|
||||
var storageKey = string.Format(Keys_CiphersFormat, userId);
|
||||
var ciphers = await _storageService.GetAsync<Dictionary<string, CipherData>>(storageKey);
|
||||
var ciphers = await _stateService.GetEncryptedCiphersAsync();
|
||||
if (ciphers == null)
|
||||
{
|
||||
ciphers = new Dictionary<string, CipherData>();
|
||||
@@ -642,28 +627,25 @@ namespace Bit.Core.Services
|
||||
}
|
||||
ciphers[c.Id] = c;
|
||||
}
|
||||
await _storageService.SaveAsync(storageKey, ciphers);
|
||||
await _stateService.SetEncryptedCiphersAsync(ciphers);
|
||||
await ClearCacheAsync();
|
||||
}
|
||||
|
||||
public async Task ReplaceAsync(Dictionary<string, CipherData> ciphers)
|
||||
{
|
||||
var userId = await _userService.GetUserIdAsync();
|
||||
await _storageService.SaveAsync(string.Format(Keys_CiphersFormat, userId), ciphers);
|
||||
await _stateService.SetEncryptedCiphersAsync(ciphers);
|
||||
await ClearCacheAsync();
|
||||
}
|
||||
|
||||
public async Task ClearAsync(string userId)
|
||||
{
|
||||
await _storageService.RemoveAsync(string.Format(Keys_CiphersFormat, userId));
|
||||
await _stateService.SetEncryptedCiphersAsync(null, new StorageOptions { UserId = userId });
|
||||
await ClearCacheAsync();
|
||||
}
|
||||
|
||||
public async Task DeleteAsync(string id)
|
||||
{
|
||||
var userId = await _userService.GetUserIdAsync();
|
||||
var cipherKey = string.Format(Keys_CiphersFormat, userId);
|
||||
var ciphers = await _storageService.GetAsync<Dictionary<string, CipherData>>(cipherKey);
|
||||
var ciphers = await _stateService.GetEncryptedCiphersAsync();
|
||||
if (ciphers == null)
|
||||
{
|
||||
return;
|
||||
@@ -673,15 +655,13 @@ namespace Bit.Core.Services
|
||||
return;
|
||||
}
|
||||
ciphers.Remove(id);
|
||||
await _storageService.SaveAsync(cipherKey, ciphers);
|
||||
await _stateService.SetEncryptedCiphersAsync(ciphers);
|
||||
await ClearCacheAsync();
|
||||
}
|
||||
|
||||
public async Task DeleteAsync(List<string> ids)
|
||||
{
|
||||
var userId = await _userService.GetUserIdAsync();
|
||||
var cipherKey = string.Format(Keys_CiphersFormat, userId);
|
||||
var ciphers = await _storageService.GetAsync<Dictionary<string, CipherData>>(cipherKey);
|
||||
var ciphers = await _stateService.GetEncryptedCiphersAsync();
|
||||
if (ciphers == null)
|
||||
{
|
||||
return;
|
||||
@@ -694,7 +674,7 @@ namespace Bit.Core.Services
|
||||
}
|
||||
ciphers.Remove(id);
|
||||
}
|
||||
await _storageService.SaveAsync(cipherKey, ciphers);
|
||||
await _stateService.SetEncryptedCiphersAsync(ciphers);
|
||||
await ClearCacheAsync();
|
||||
}
|
||||
|
||||
@@ -706,9 +686,7 @@ namespace Bit.Core.Services
|
||||
|
||||
public async Task DeleteAttachmentAsync(string id, string attachmentId)
|
||||
{
|
||||
var userId = await _userService.GetUserIdAsync();
|
||||
var cipherKey = string.Format(Keys_CiphersFormat, userId);
|
||||
var ciphers = await _storageService.GetAsync<Dictionary<string, CipherData>>(cipherKey);
|
||||
var ciphers = await _stateService.GetEncryptedCiphersAsync();
|
||||
if (ciphers == null || !ciphers.ContainsKey(id) || ciphers[id].Attachments == null)
|
||||
{
|
||||
return;
|
||||
@@ -718,7 +696,7 @@ namespace Bit.Core.Services
|
||||
{
|
||||
ciphers[id].Attachments.Remove(attachment);
|
||||
}
|
||||
await _storageService.SaveAsync(cipherKey, ciphers);
|
||||
await _stateService.SetEncryptedCiphersAsync(ciphers);
|
||||
await ClearCacheAsync();
|
||||
}
|
||||
|
||||
@@ -771,9 +749,7 @@ namespace Bit.Core.Services
|
||||
|
||||
public async Task SoftDeleteWithServerAsync(string id)
|
||||
{
|
||||
var userId = await _userService.GetUserIdAsync();
|
||||
var cipherKey = string.Format(Keys_CiphersFormat, userId);
|
||||
var ciphers = await _storageService.GetAsync<Dictionary<string, CipherData>>(cipherKey);
|
||||
var ciphers = await _stateService.GetEncryptedCiphersAsync();
|
||||
if (ciphers == null)
|
||||
{
|
||||
return;
|
||||
@@ -785,15 +761,13 @@ namespace Bit.Core.Services
|
||||
|
||||
await _apiService.PutDeleteCipherAsync(id);
|
||||
ciphers[id].DeletedDate = DateTime.UtcNow;
|
||||
await _storageService.SaveAsync(cipherKey, ciphers);
|
||||
await _stateService.SetEncryptedCiphersAsync(ciphers);
|
||||
await ClearCacheAsync();
|
||||
}
|
||||
|
||||
public async Task RestoreWithServerAsync(string id)
|
||||
{
|
||||
var userId = await _userService.GetUserIdAsync();
|
||||
var cipherKey = string.Format(Keys_CiphersFormat, userId);
|
||||
var ciphers = await _storageService.GetAsync<Dictionary<string, CipherData>>(cipherKey);
|
||||
var ciphers = await _stateService.GetEncryptedCiphersAsync();
|
||||
if (ciphers == null)
|
||||
{
|
||||
return;
|
||||
@@ -805,7 +779,7 @@ namespace Bit.Core.Services
|
||||
var response = await _apiService.PutRestoreCipherAsync(id);
|
||||
ciphers[id].DeletedDate = null;
|
||||
ciphers[id].RevisionDate = response.RevisionDate;
|
||||
await _storageService.SaveAsync(cipherKey, ciphers);
|
||||
await _stateService.SetEncryptedCiphersAsync(ciphers);
|
||||
await ClearCacheAsync();
|
||||
}
|
||||
|
||||
|
||||
@@ -13,24 +13,20 @@ namespace Bit.Core.Services
|
||||
{
|
||||
public class CollectionService : ICollectionService
|
||||
{
|
||||
private const string Keys_CollectionsFormat = "collections_{0}";
|
||||
private const char NestingDelimiter = '/';
|
||||
|
||||
private List<CollectionView> _decryptedCollectionCache;
|
||||
private readonly ICryptoService _cryptoService;
|
||||
private readonly IUserService _userService;
|
||||
private readonly IStorageService _storageService;
|
||||
private readonly IStateService _stateService;
|
||||
private readonly II18nService _i18nService;
|
||||
|
||||
public CollectionService(
|
||||
ICryptoService cryptoService,
|
||||
IUserService userService,
|
||||
IStorageService storageService,
|
||||
IStateService stateService,
|
||||
II18nService i18nService)
|
||||
{
|
||||
_cryptoService = cryptoService;
|
||||
_userService = userService;
|
||||
_storageService = storageService;
|
||||
_stateService = stateService;
|
||||
_i18nService = i18nService;
|
||||
}
|
||||
|
||||
@@ -83,9 +79,7 @@ namespace Bit.Core.Services
|
||||
|
||||
public async Task<Collection> GetAsync(string id)
|
||||
{
|
||||
var userId = await _userService.GetUserIdAsync();
|
||||
var collections = await _storageService.GetAsync<Dictionary<string, CollectionData>>(
|
||||
string.Format(Keys_CollectionsFormat, userId));
|
||||
var collections = await _stateService.GetEncryptedCollectionsAsync();
|
||||
if (!collections?.ContainsKey(id) ?? true)
|
||||
{
|
||||
return null;
|
||||
@@ -95,9 +89,7 @@ namespace Bit.Core.Services
|
||||
|
||||
public async Task<List<Collection>> GetAllAsync()
|
||||
{
|
||||
var userId = await _userService.GetUserIdAsync();
|
||||
var collections = await _storageService.GetAsync<Dictionary<string, CollectionData>>(
|
||||
string.Format(Keys_CollectionsFormat, userId));
|
||||
var collections = await _stateService.GetEncryptedCollectionsAsync();
|
||||
var response = collections?.Select(c => new Collection(c.Value));
|
||||
return response?.ToList() ?? new List<Collection>();
|
||||
}
|
||||
@@ -148,9 +140,7 @@ namespace Bit.Core.Services
|
||||
|
||||
public async Task UpsertAsync(CollectionData collection)
|
||||
{
|
||||
var userId = await _userService.GetUserIdAsync();
|
||||
var storageKey = string.Format(Keys_CollectionsFormat, userId);
|
||||
var collections = await _storageService.GetAsync<Dictionary<string, CollectionData>>(storageKey);
|
||||
var collections = await _stateService.GetEncryptedCollectionsAsync();
|
||||
if (collections == null)
|
||||
{
|
||||
collections = new Dictionary<string, CollectionData>();
|
||||
@@ -160,15 +150,13 @@ namespace Bit.Core.Services
|
||||
collections.Add(collection.Id, null);
|
||||
}
|
||||
collections[collection.Id] = collection;
|
||||
await _storageService.SaveAsync(storageKey, collections);
|
||||
await _stateService.SetEncryptedCollectionsAsync(collections);
|
||||
_decryptedCollectionCache = null;
|
||||
}
|
||||
|
||||
public async Task UpsertAsync(List<CollectionData> collection)
|
||||
{
|
||||
var userId = await _userService.GetUserIdAsync();
|
||||
var storageKey = string.Format(Keys_CollectionsFormat, userId);
|
||||
var collections = await _storageService.GetAsync<Dictionary<string, CollectionData>>(storageKey);
|
||||
var collections = await _stateService.GetEncryptedCollectionsAsync();
|
||||
if (collections == null)
|
||||
{
|
||||
collections = new Dictionary<string, CollectionData>();
|
||||
@@ -181,34 +169,31 @@ namespace Bit.Core.Services
|
||||
}
|
||||
collections[c.Id] = c;
|
||||
}
|
||||
await _storageService.SaveAsync(storageKey, collections);
|
||||
await _stateService.SetEncryptedCollectionsAsync(collections);
|
||||
_decryptedCollectionCache = null;
|
||||
}
|
||||
|
||||
public async Task ReplaceAsync(Dictionary<string, CollectionData> collections)
|
||||
{
|
||||
var userId = await _userService.GetUserIdAsync();
|
||||
await _storageService.SaveAsync(string.Format(Keys_CollectionsFormat, userId), collections);
|
||||
await _stateService.SetEncryptedCollectionsAsync(collections);
|
||||
_decryptedCollectionCache = null;
|
||||
}
|
||||
|
||||
public async Task ClearAsync(string userId)
|
||||
{
|
||||
await _storageService.RemoveAsync(string.Format(Keys_CollectionsFormat, userId));
|
||||
await _stateService.SetEncryptedCollectionsAsync(null, new StorageOptions { UserId = userId });
|
||||
_decryptedCollectionCache = null;
|
||||
}
|
||||
|
||||
public async Task DeleteAsync(string id)
|
||||
{
|
||||
var userId = await _userService.GetUserIdAsync();
|
||||
var collectionKey = string.Format(Keys_CollectionsFormat, userId);
|
||||
var collections = await _storageService.GetAsync<Dictionary<string, CollectionData>>(collectionKey);
|
||||
var collections = await _stateService.GetEncryptedCollectionsAsync();
|
||||
if (collections == null || !collections.ContainsKey(id))
|
||||
{
|
||||
return;
|
||||
}
|
||||
collections.Remove(id);
|
||||
await _storageService.SaveAsync(collectionKey, collections);
|
||||
await _stateService.SetEncryptedCollectionsAsync(collections);
|
||||
_decryptedCollectionCache = null;
|
||||
}
|
||||
|
||||
|
||||
@@ -14,53 +14,38 @@ namespace Bit.Core.Services
|
||||
{
|
||||
public class CryptoService : ICryptoService
|
||||
{
|
||||
private readonly IStorageService _storageService;
|
||||
private readonly IStorageService _secureStorageService;
|
||||
private readonly IStateService _stateService;
|
||||
private readonly ICryptoFunctionService _cryptoFunctionService;
|
||||
|
||||
private SymmetricCryptoKey _key;
|
||||
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;
|
||||
|
||||
private const string Keys_Key = "key";
|
||||
private const string Keys_EncOrgKeys = "encOrgKeys";
|
||||
private const string Keys_EncPrivateKey = "encPrivateKey";
|
||||
private const string Keys_EncKey = "encKey";
|
||||
private const string Keys_KeyHash = "keyHash";
|
||||
|
||||
public CryptoService(
|
||||
IStorageService storageService,
|
||||
IStorageService secureStorageService,
|
||||
IStateService stateService,
|
||||
ICryptoFunctionService cryptoFunctionService)
|
||||
{
|
||||
_storageService = storageService;
|
||||
_secureStorageService = secureStorageService;
|
||||
_stateService = stateService;
|
||||
_cryptoFunctionService = cryptoFunctionService;
|
||||
}
|
||||
|
||||
public async Task SetKeyAsync(SymmetricCryptoKey key)
|
||||
{
|
||||
_key = key;
|
||||
var option = await _storageService.GetAsync<int?>(Constants.VaultTimeoutKey);
|
||||
var biometric = await _storageService.GetAsync<bool?>(Constants.BiometricUnlockKey);
|
||||
await _stateService.SetKeyDecryptedAsync(key);
|
||||
var option = await _stateService.GetVaultTimeoutAsync();
|
||||
var biometric = await _stateService.GetBiometricUnlockAsync();
|
||||
if (option.HasValue && !biometric.GetValueOrDefault())
|
||||
{
|
||||
// If we have a lock option set, we do not store the key
|
||||
return;
|
||||
}
|
||||
await _secureStorageService.SaveAsync(Keys_Key, key?.KeyB64);
|
||||
await _stateService.SetKeyEncryptedAsync(key?.KeyB64);
|
||||
}
|
||||
|
||||
public async Task SetKeyHashAsync(string keyHash)
|
||||
{
|
||||
_keyHash = keyHash;
|
||||
await _storageService.SaveAsync(Keys_KeyHash, keyHash);
|
||||
await _stateService.SetKeyHashCachedAsync(keyHash);
|
||||
await _stateService.SetKeyHashAsync(keyHash);
|
||||
}
|
||||
|
||||
public async Task SetEncKeyAsync(string encKey)
|
||||
@@ -69,8 +54,8 @@ namespace Bit.Core.Services
|
||||
{
|
||||
return;
|
||||
}
|
||||
await _storageService.SaveAsync(Keys_EncKey, encKey);
|
||||
_encKey = null;
|
||||
await _stateService.SetEncKeyEncryptedAsync(encKey);
|
||||
await _stateService.SetEncKeyDecryptedAsync(null);
|
||||
}
|
||||
|
||||
public async Task SetEncPrivateKeyAsync(string encPrivateKey)
|
||||
@@ -79,50 +64,54 @@ namespace Bit.Core.Services
|
||||
{
|
||||
return;
|
||||
}
|
||||
await _storageService.SaveAsync(Keys_EncPrivateKey, encPrivateKey);
|
||||
_privateKey = null;
|
||||
await _stateService.SetPrivateKeyEncryptedAsync(encPrivateKey);
|
||||
await _stateService.SetPrivateKeyDecryptedAsync(null);
|
||||
}
|
||||
|
||||
public async Task SetOrgKeysAsync(IEnumerable<ProfileOrganizationResponse> orgs)
|
||||
{
|
||||
var orgKeys = orgs.ToDictionary(org => org.Id, org => org.Key);
|
||||
_orgKeys = null;
|
||||
await _storageService.SaveAsync(Keys_EncOrgKeys, orgKeys);
|
||||
await _stateService.SetOrgKeysDecryptedAsync(null);
|
||||
await _stateService.SetOrgKeysEncryptedAsync(orgKeys);
|
||||
}
|
||||
|
||||
public async Task<SymmetricCryptoKey> GetKeyAsync()
|
||||
{
|
||||
if (_key != null)
|
||||
var inMemoryKey = await _stateService.GetKeyDecryptedAsync();
|
||||
if (inMemoryKey != null)
|
||||
{
|
||||
return _key;
|
||||
return inMemoryKey;
|
||||
}
|
||||
var key = await _secureStorageService.GetAsync<string>(Keys_Key);
|
||||
var key = await _stateService.GetKeyEncryptedAsync();
|
||||
if (key != null)
|
||||
{
|
||||
_key = new SymmetricCryptoKey(Convert.FromBase64String(key));
|
||||
inMemoryKey = new SymmetricCryptoKey(Convert.FromBase64String(key));
|
||||
await _stateService.SetKeyDecryptedAsync(inMemoryKey);
|
||||
}
|
||||
return _key;
|
||||
return inMemoryKey;
|
||||
}
|
||||
|
||||
public async Task<string> GetKeyHashAsync()
|
||||
{
|
||||
if (_keyHash != null)
|
||||
var inMemoryKeyHash = await _stateService.GetKeyHashCachedAsync();
|
||||
if (inMemoryKeyHash != null)
|
||||
{
|
||||
return _keyHash;
|
||||
return inMemoryKeyHash;
|
||||
}
|
||||
var keyHash = await _storageService.GetAsync<string>(Keys_KeyHash);
|
||||
var keyHash = await _stateService.GetKeyHashAsync();
|
||||
if (keyHash != null)
|
||||
{
|
||||
_keyHash = keyHash;
|
||||
await _stateService.SetKeyHashCachedAsync(keyHash);
|
||||
}
|
||||
return _keyHash;
|
||||
return keyHash;
|
||||
}
|
||||
|
||||
public Task<SymmetricCryptoKey> GetEncKeyAsync(SymmetricCryptoKey key = null)
|
||||
{
|
||||
if (_encKey != null)
|
||||
var inMemoryKey = _stateService.GetEncKeyDecryptedAsync().GetAwaiter().GetResult();
|
||||
if (inMemoryKey != null)
|
||||
{
|
||||
return Task.FromResult(_encKey);
|
||||
return Task.FromResult(inMemoryKey);
|
||||
}
|
||||
if (_getEncKeysTask != null && !_getEncKeysTask.IsCompleted && !_getEncKeysTask.IsFaulted)
|
||||
{
|
||||
@@ -132,7 +121,7 @@ namespace Bit.Core.Services
|
||||
{
|
||||
try
|
||||
{
|
||||
var encKey = await _storageService.GetAsync<string>(Keys_EncKey);
|
||||
var encKey = await _stateService.GetEncKeyEncryptedAsync();
|
||||
if (encKey == null)
|
||||
{
|
||||
return null;
|
||||
@@ -167,8 +156,9 @@ namespace Bit.Core.Services
|
||||
{
|
||||
return null;
|
||||
}
|
||||
_encKey = new SymmetricCryptoKey(decEncKey);
|
||||
return _encKey;
|
||||
var newEncKey = new SymmetricCryptoKey(decEncKey);
|
||||
await _stateService.SetEncKeyDecryptedAsync(newEncKey);
|
||||
return newEncKey;
|
||||
}
|
||||
finally
|
||||
{
|
||||
@@ -181,32 +171,36 @@ namespace Bit.Core.Services
|
||||
|
||||
public async Task<byte[]> GetPublicKeyAsync()
|
||||
{
|
||||
if (_publicKey != null)
|
||||
var inMemoryKey = await _stateService.GetPublicKeyAsync();
|
||||
if (inMemoryKey != null)
|
||||
{
|
||||
return _publicKey;
|
||||
return inMemoryKey;
|
||||
}
|
||||
var privateKey = await GetPrivateKeyAsync();
|
||||
if (privateKey == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
_publicKey = await _cryptoFunctionService.RsaExtractPublicKeyAsync(privateKey);
|
||||
return _publicKey;
|
||||
inMemoryKey = await _cryptoFunctionService.RsaExtractPublicKeyAsync(privateKey);
|
||||
await _stateService.SetPublicKeyAsync(inMemoryKey);
|
||||
return inMemoryKey;
|
||||
}
|
||||
|
||||
public async Task<byte[]> GetPrivateKeyAsync()
|
||||
{
|
||||
if (_privateKey != null)
|
||||
var inMemoryKey = await _stateService.GetPrivateKeyDecryptedAsync();
|
||||
if (inMemoryKey != null)
|
||||
{
|
||||
return _privateKey;
|
||||
return inMemoryKey;
|
||||
}
|
||||
var encPrivateKey = await _storageService.GetAsync<string>(Keys_EncPrivateKey);
|
||||
var encPrivateKey = await _stateService.GetPrivateKeyEncryptedAsync();
|
||||
if (encPrivateKey == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
_privateKey = await DecryptToBytesAsync(new EncString(encPrivateKey), null);
|
||||
return _privateKey;
|
||||
inMemoryKey = await DecryptToBytesAsync(new EncString(encPrivateKey), null);
|
||||
await _stateService.SetPrivateKeyDecryptedAsync(inMemoryKey);
|
||||
return inMemoryKey;
|
||||
}
|
||||
|
||||
public async Task<List<string>> GetFingerprintAsync(string userId, byte[] publicKey = null)
|
||||
@@ -226,9 +220,10 @@ namespace Bit.Core.Services
|
||||
|
||||
public Task<Dictionary<string, SymmetricCryptoKey>> GetOrgKeysAsync()
|
||||
{
|
||||
if (_orgKeys != null && _orgKeys.Count > 0)
|
||||
var inMemoryKeys = _stateService.GetOrgKeysDecryptedAsync();
|
||||
if (inMemoryKeys != null && inMemoryKeys.Result.Count > 0)
|
||||
{
|
||||
return Task.FromResult(_orgKeys);
|
||||
return inMemoryKeys;
|
||||
}
|
||||
if (_getOrgKeysTask != null && !_getOrgKeysTask.IsCompleted && !_getOrgKeysTask.IsFaulted)
|
||||
{
|
||||
@@ -238,7 +233,7 @@ namespace Bit.Core.Services
|
||||
{
|
||||
try
|
||||
{
|
||||
var encOrgKeys = await _storageService.GetAsync<Dictionary<string, string>>(Keys_EncOrgKeys);
|
||||
var encOrgKeys = await _stateService.GetOrgKeysEncryptedAsync();
|
||||
if (encOrgKeys == null)
|
||||
{
|
||||
return null;
|
||||
@@ -254,9 +249,9 @@ namespace Bit.Core.Services
|
||||
|
||||
if (setKey)
|
||||
{
|
||||
_orgKeys = orgKeys;
|
||||
await _stateService.SetOrgKeysDecryptedAsync(orgKeys);
|
||||
}
|
||||
return _orgKeys;
|
||||
return orgKeys;
|
||||
}
|
||||
finally
|
||||
{
|
||||
@@ -311,76 +306,78 @@ namespace Bit.Core.Services
|
||||
|
||||
public async Task<bool> HasEncKeyAsync()
|
||||
{
|
||||
var encKey = await _storageService.GetAsync<string>(Keys_EncKey);
|
||||
var encKey = await _stateService.GetEncKeyEncryptedAsync();
|
||||
return encKey != null;
|
||||
}
|
||||
|
||||
public async Task ClearKeyAsync()
|
||||
public async Task ClearKeyAsync(string userId = null)
|
||||
{
|
||||
_key = _legacyEtmKey = null;
|
||||
await _secureStorageService.RemoveAsync(Keys_Key);
|
||||
await _stateService.SetKeyDecryptedAsync(null, new StorageOptions { UserId = userId });
|
||||
_legacyEtmKey = null;
|
||||
await _stateService.SetKeyEncryptedAsync(null, new StorageOptions { UserId = userId });
|
||||
}
|
||||
|
||||
public async Task ClearKeyHashAsync()
|
||||
public async Task ClearKeyHashAsync(string userId = null)
|
||||
{
|
||||
_keyHash = null;
|
||||
await _storageService.RemoveAsync(Keys_KeyHash);
|
||||
await _stateService.SetKeyHashCachedAsync(null, new StorageOptions { UserId = userId });
|
||||
await _stateService.SetKeyHashAsync(null, new StorageOptions { UserId = userId });
|
||||
}
|
||||
|
||||
public async Task ClearEncKeyAsync(bool memoryOnly = false)
|
||||
public async Task ClearEncKeyAsync(bool memoryOnly = false, string userId = null)
|
||||
{
|
||||
_encKey = null;
|
||||
await _stateService.SetEncKeyDecryptedAsync(null, new StorageOptions { UserId = userId });
|
||||
if (!memoryOnly)
|
||||
{
|
||||
await _storageService.RemoveAsync(Keys_EncKey);
|
||||
await _stateService.SetEncKeyEncryptedAsync(null, new StorageOptions { UserId = userId });
|
||||
}
|
||||
}
|
||||
|
||||
public async Task ClearKeyPairAsync(bool memoryOnly = false)
|
||||
public async Task ClearKeyPairAsync(bool memoryOnly = false, string userId = null)
|
||||
{
|
||||
_publicKey = _privateKey = null;
|
||||
await _stateService.SetPublicKeyAsync(null, new StorageOptions { UserId = userId });
|
||||
await _stateService.SetPrivateKeyDecryptedAsync(null, new StorageOptions { UserId = userId });
|
||||
if (!memoryOnly)
|
||||
{
|
||||
await _storageService.RemoveAsync(Keys_EncPrivateKey);
|
||||
await _stateService.SetPrivateKeyEncryptedAsync(null, new StorageOptions { UserId = userId });
|
||||
}
|
||||
}
|
||||
|
||||
public async Task ClearOrgKeysAsync(bool memoryOnly = false)
|
||||
public async Task ClearOrgKeysAsync(bool memoryOnly = false, string userId = null)
|
||||
{
|
||||
_orgKeys = null;
|
||||
await _stateService.SetOrgKeysDecryptedAsync(null, new StorageOptions { UserId = userId });
|
||||
if (!memoryOnly)
|
||||
{
|
||||
await _storageService.RemoveAsync(Keys_EncOrgKeys);
|
||||
await _stateService.SetOrgKeysEncryptedAsync(null, new StorageOptions { UserId = userId });
|
||||
}
|
||||
}
|
||||
|
||||
public async Task ClearPinProtectedKeyAsync()
|
||||
public async Task ClearPinProtectedKeyAsync(string userId = null)
|
||||
{
|
||||
await _storageService.RemoveAsync(Constants.PinProtectedKey);
|
||||
await _stateService.SetPinProtectedAsync(null, new StorageOptions { UserId = userId });
|
||||
}
|
||||
|
||||
public async Task ClearKeysAsync()
|
||||
public async Task ClearKeysAsync(string userId = null)
|
||||
{
|
||||
await Task.WhenAll(new Task[]
|
||||
{
|
||||
ClearKeyAsync(),
|
||||
ClearKeyHashAsync(),
|
||||
ClearOrgKeysAsync(),
|
||||
ClearEncKeyAsync(),
|
||||
ClearKeyPairAsync(),
|
||||
ClearPinProtectedKeyAsync()
|
||||
ClearKeyAsync(userId),
|
||||
ClearKeyHashAsync(userId),
|
||||
ClearOrgKeysAsync(false, userId),
|
||||
ClearEncKeyAsync(false, userId),
|
||||
ClearKeyPairAsync(false, userId),
|
||||
ClearPinProtectedKeyAsync(userId)
|
||||
});
|
||||
}
|
||||
|
||||
public async Task ToggleKeyAsync()
|
||||
{
|
||||
var key = await GetKeyAsync();
|
||||
var option = await _storageService.GetAsync<int?>(Constants.VaultTimeoutKey);
|
||||
var biometric = await _storageService.GetAsync<bool?>(Constants.BiometricUnlockKey);
|
||||
var option = await _stateService.GetVaultTimeoutAsync();
|
||||
var biometric = await _stateService.GetBiometricUnlockAsync();
|
||||
if (!biometric.GetValueOrDefault() && (option != null || option == 0))
|
||||
{
|
||||
await ClearKeyAsync();
|
||||
_key = key;
|
||||
await _stateService.SetKeyDecryptedAsync(key);
|
||||
return;
|
||||
}
|
||||
await SetKeyAsync(key);
|
||||
@@ -415,7 +412,7 @@ namespace Bit.Core.Services
|
||||
{
|
||||
if (protectedKeyCs == null)
|
||||
{
|
||||
var pinProtectedKey = await _storageService.GetAsync<string>(Constants.PinProtectedKey);
|
||||
var pinProtectedKey = await _stateService.GetPinProtectedAsync();
|
||||
if (pinProtectedKey == null)
|
||||
{
|
||||
throw new Exception("No PIN protected key found.");
|
||||
|
||||
@@ -9,14 +9,14 @@ namespace Bit.Core.Services
|
||||
public class EnvironmentService : IEnvironmentService
|
||||
{
|
||||
private readonly IApiService _apiService;
|
||||
private readonly IStorageService _storageService;
|
||||
private readonly IStateService _stateService;
|
||||
|
||||
public EnvironmentService(
|
||||
IApiService apiService,
|
||||
IStorageService storageService)
|
||||
IStateService stateService)
|
||||
{
|
||||
_apiService = apiService;
|
||||
_storageService = storageService;
|
||||
_stateService = stateService;
|
||||
}
|
||||
|
||||
public string BaseUrl { get; set; }
|
||||
@@ -42,7 +42,11 @@ namespace Bit.Core.Services
|
||||
|
||||
public async Task SetUrlsFromStorageAsync()
|
||||
{
|
||||
var urls = await _storageService.GetAsync<EnvironmentUrlData>(Constants.EnvironmentUrlsKey);
|
||||
var urls = await _stateService.GetEnvironmentUrlsAsync();
|
||||
if (urls == null)
|
||||
{
|
||||
urls = await _stateService.GetPreAuthEnvironmentUrlsAsync();
|
||||
}
|
||||
if (urls == null)
|
||||
{
|
||||
urls = new EnvironmentUrlData();
|
||||
@@ -72,7 +76,7 @@ namespace Bit.Core.Services
|
||||
urls.Icons = FormatUrl(urls.Icons);
|
||||
urls.Notifications = FormatUrl(urls.Notifications);
|
||||
urls.Events = FormatUrl(urls.Events);
|
||||
await _storageService.SaveAsync(Constants.EnvironmentUrlsKey, urls);
|
||||
await _stateService.SetPreAuthEnvironmentUrlsAsync(urls);
|
||||
BaseUrl = urls.Base;
|
||||
WebVaultUrl = urls.WebVault;
|
||||
ApiUrl = urls.Api;
|
||||
|
||||
@@ -12,31 +12,31 @@ namespace Bit.Core.Services
|
||||
{
|
||||
public class EventService : IEventService
|
||||
{
|
||||
private readonly IStorageService _storageService;
|
||||
private readonly IApiService _apiService;
|
||||
private readonly IUserService _userService;
|
||||
private readonly IStateService _stateService;
|
||||
private readonly IOrganizationService _organizationService;
|
||||
private readonly ICipherService _cipherService;
|
||||
|
||||
public EventService(
|
||||
IStorageService storageService,
|
||||
IApiService apiService,
|
||||
IUserService userService,
|
||||
IStateService stateService,
|
||||
IOrganizationService organizationService,
|
||||
ICipherService cipherService)
|
||||
{
|
||||
_storageService = storageService;
|
||||
_apiService = apiService;
|
||||
_userService = userService;
|
||||
_stateService = stateService;
|
||||
_organizationService = organizationService;
|
||||
_cipherService = cipherService;
|
||||
}
|
||||
|
||||
public async Task CollectAsync(EventType eventType, string cipherId = null, bool uploadImmediately = false)
|
||||
{
|
||||
var authed = await _userService.IsAuthenticatedAsync();
|
||||
var authed = await _stateService.IsAuthenticatedAsync();
|
||||
if (!authed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
var organizations = await _userService.GetAllOrganizationAsync();
|
||||
var organizations = await _organizationService.GetAllAsync();
|
||||
if (organizations == null)
|
||||
{
|
||||
return;
|
||||
@@ -54,7 +54,7 @@ namespace Bit.Core.Services
|
||||
return;
|
||||
}
|
||||
}
|
||||
var eventCollection = await _storageService.GetAsync<List<EventData>>(Constants.EventCollectionKey);
|
||||
var eventCollection = await _stateService.GetEventCollectionAsync();
|
||||
if (eventCollection == null)
|
||||
{
|
||||
eventCollection = new List<EventData>();
|
||||
@@ -65,7 +65,7 @@ namespace Bit.Core.Services
|
||||
CipherId = cipherId,
|
||||
Date = DateTime.UtcNow
|
||||
});
|
||||
await _storageService.SaveAsync(Constants.EventCollectionKey, eventCollection);
|
||||
await _stateService.SetEventCollectionAsync(eventCollection);
|
||||
if (uploadImmediately)
|
||||
{
|
||||
await UploadEventsAsync();
|
||||
@@ -74,12 +74,12 @@ namespace Bit.Core.Services
|
||||
|
||||
public async Task UploadEventsAsync()
|
||||
{
|
||||
var authed = await _userService.IsAuthenticatedAsync();
|
||||
var authed = await _stateService.IsAuthenticatedAsync();
|
||||
if (!authed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
var eventCollection = await _storageService.GetAsync<List<EventData>>(Constants.EventCollectionKey);
|
||||
var eventCollection = await _stateService.GetEventCollectionAsync();
|
||||
if (eventCollection == null || !eventCollection.Any())
|
||||
{
|
||||
return;
|
||||
@@ -100,7 +100,7 @@ namespace Bit.Core.Services
|
||||
|
||||
public async Task ClearEventsAsync()
|
||||
{
|
||||
await _storageService.RemoveAsync(Constants.EventCollectionKey);
|
||||
await _stateService.SetEventCollectionAsync(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,30 +15,25 @@ namespace Bit.Core.Services
|
||||
{
|
||||
public class FolderService : IFolderService
|
||||
{
|
||||
private const string Keys_CiphersFormat = "ciphers_{0}";
|
||||
private const string Keys_FoldersFormat = "folders_{0}";
|
||||
private const char NestingDelimiter = '/';
|
||||
|
||||
private List<FolderView> _decryptedFolderCache;
|
||||
private readonly ICryptoService _cryptoService;
|
||||
private readonly IUserService _userService;
|
||||
private readonly IStateService _stateService;
|
||||
private readonly IApiService _apiService;
|
||||
private readonly IStorageService _storageService;
|
||||
private readonly II18nService _i18nService;
|
||||
private readonly ICipherService _cipherService;
|
||||
|
||||
public FolderService(
|
||||
ICryptoService cryptoService,
|
||||
IUserService userService,
|
||||
IStateService stateService,
|
||||
IApiService apiService,
|
||||
IStorageService storageService,
|
||||
II18nService i18nService,
|
||||
ICipherService cipherService)
|
||||
{
|
||||
_cryptoService = cryptoService;
|
||||
_userService = userService;
|
||||
_stateService = stateService;
|
||||
_apiService = apiService;
|
||||
_storageService = storageService;
|
||||
_i18nService = i18nService;
|
||||
_cipherService = cipherService;
|
||||
}
|
||||
@@ -60,9 +55,7 @@ namespace Bit.Core.Services
|
||||
|
||||
public async Task<Folder> GetAsync(string id)
|
||||
{
|
||||
var userId = await _userService.GetUserIdAsync();
|
||||
var folders = await _storageService.GetAsync<Dictionary<string, FolderData>>(
|
||||
string.Format(Keys_FoldersFormat, userId));
|
||||
var folders = await _stateService.GetEncryptedFoldersAsync();
|
||||
if (!folders?.ContainsKey(id) ?? true)
|
||||
{
|
||||
return null;
|
||||
@@ -72,9 +65,7 @@ namespace Bit.Core.Services
|
||||
|
||||
public async Task<List<Folder>> GetAllAsync()
|
||||
{
|
||||
var userId = await _userService.GetUserIdAsync();
|
||||
var folders = await _storageService.GetAsync<Dictionary<string, FolderData>>(
|
||||
string.Format(Keys_FoldersFormat, userId));
|
||||
var folders = await _stateService.GetEncryptedFoldersAsync();
|
||||
var response = folders?.Select(f => new Folder(f.Value));
|
||||
return response?.ToList() ?? new List<Folder>();
|
||||
}
|
||||
@@ -153,16 +144,14 @@ namespace Bit.Core.Services
|
||||
{
|
||||
response = await _apiService.PutFolderAsync(folder.Id, request);
|
||||
}
|
||||
var userId = await _userService.GetUserIdAsync();
|
||||
var userId = await _stateService.GetActiveUserIdAsync();
|
||||
var data = new FolderData(response, userId);
|
||||
await UpsertAsync(data);
|
||||
}
|
||||
|
||||
public async Task UpsertAsync(FolderData folder)
|
||||
{
|
||||
var userId = await _userService.GetUserIdAsync();
|
||||
var storageKey = string.Format(Keys_FoldersFormat, userId);
|
||||
var folders = await _storageService.GetAsync<Dictionary<string, FolderData>>(storageKey);
|
||||
var folders = await _stateService.GetEncryptedFoldersAsync();
|
||||
if (folders == null)
|
||||
{
|
||||
folders = new Dictionary<string, FolderData>();
|
||||
@@ -172,15 +161,13 @@ namespace Bit.Core.Services
|
||||
folders.Add(folder.Id, null);
|
||||
}
|
||||
folders[folder.Id] = folder;
|
||||
await _storageService.SaveAsync(storageKey, folders);
|
||||
await _stateService.SetEncryptedFoldersAsync(folders);
|
||||
_decryptedFolderCache = null;
|
||||
}
|
||||
|
||||
public async Task UpsertAsync(List<FolderData> folder)
|
||||
{
|
||||
var userId = await _userService.GetUserIdAsync();
|
||||
var storageKey = string.Format(Keys_FoldersFormat, userId);
|
||||
var folders = await _storageService.GetAsync<Dictionary<string, FolderData>>(storageKey);
|
||||
var folders = await _stateService.GetEncryptedFoldersAsync();
|
||||
if (folders == null)
|
||||
{
|
||||
folders = new Dictionary<string, FolderData>();
|
||||
@@ -193,39 +180,35 @@ namespace Bit.Core.Services
|
||||
}
|
||||
folders[f.Id] = f;
|
||||
}
|
||||
await _storageService.SaveAsync(storageKey, folders);
|
||||
await _stateService.SetEncryptedFoldersAsync(folders);
|
||||
_decryptedFolderCache = null;
|
||||
}
|
||||
|
||||
public async Task ReplaceAsync(Dictionary<string, FolderData> folders)
|
||||
{
|
||||
var userId = await _userService.GetUserIdAsync();
|
||||
await _storageService.SaveAsync(string.Format(Keys_FoldersFormat, userId), folders);
|
||||
await _stateService.SetEncryptedFoldersAsync(folders);
|
||||
_decryptedFolderCache = null;
|
||||
}
|
||||
|
||||
public async Task ClearAsync(string userId)
|
||||
{
|
||||
await _storageService.RemoveAsync(string.Format(Keys_FoldersFormat, userId));
|
||||
await _stateService.SetEncryptedFoldersAsync(null, new StorageOptions { UserId = userId });
|
||||
_decryptedFolderCache = null;
|
||||
}
|
||||
|
||||
public async Task DeleteAsync(string id)
|
||||
{
|
||||
var userId = await _userService.GetUserIdAsync();
|
||||
var folderKey = string.Format(Keys_FoldersFormat, userId);
|
||||
var folders = await _storageService.GetAsync<Dictionary<string, FolderData>>(folderKey);
|
||||
var folders = await _stateService.GetEncryptedFoldersAsync();
|
||||
if (folders == null || !folders.ContainsKey(id))
|
||||
{
|
||||
return;
|
||||
}
|
||||
folders.Remove(id);
|
||||
await _storageService.SaveAsync(folderKey, folders);
|
||||
await _stateService.SetEncryptedFoldersAsync(folders);
|
||||
_decryptedFolderCache = null;
|
||||
|
||||
// Items in a deleted folder are re-assigned to "No Folder"
|
||||
var ciphers = await _storageService.GetAsync<Dictionary<string, CipherData>>(
|
||||
string.Format(Keys_CiphersFormat, userId));
|
||||
var ciphers = await _stateService.GetEncryptedCiphersAsync();
|
||||
if (ciphers != null)
|
||||
{
|
||||
var updates = new List<CipherData>();
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.Core.Abstractions;
|
||||
using Bit.Core.Exceptions;
|
||||
using Bit.Core.Models.Domain;
|
||||
using Bit.Core.Models.Request;
|
||||
|
||||
@@ -9,24 +8,20 @@ namespace Bit.Core.Services
|
||||
{
|
||||
public class KeyConnectorService : IKeyConnectorService
|
||||
{
|
||||
private const string Keys_UsesKeyConnector = "usesKeyConnector";
|
||||
|
||||
private readonly IUserService _userService;
|
||||
private readonly IStateService _stateService;
|
||||
private readonly ICryptoService _cryptoService;
|
||||
private readonly IStorageService _storageService;
|
||||
private readonly ITokenService _tokenService;
|
||||
private readonly IApiService _apiService;
|
||||
private readonly IOrganizationService _organizationService;
|
||||
|
||||
private bool? _usesKeyConnector;
|
||||
|
||||
public KeyConnectorService(IUserService userService, ICryptoService cryptoService,
|
||||
IStorageService storageService, ITokenService tokenService, IApiService apiService)
|
||||
public KeyConnectorService(IStateService stateService, ICryptoService cryptoService,
|
||||
ITokenService tokenService, IApiService apiService, OrganizationService organizationService)
|
||||
{
|
||||
_userService = userService;
|
||||
_stateService = stateService;
|
||||
_cryptoService = cryptoService;
|
||||
_storageService = storageService;
|
||||
_tokenService = tokenService;
|
||||
_apiService = apiService;
|
||||
_organizationService = organizationService;
|
||||
}
|
||||
|
||||
public async Task GetAndSetKey(string url)
|
||||
@@ -46,23 +41,17 @@ namespace Bit.Core.Services
|
||||
|
||||
public async Task SetUsesKeyConnector(bool usesKeyConnector)
|
||||
{
|
||||
_usesKeyConnector = usesKeyConnector;
|
||||
await _storageService.SaveAsync(Keys_UsesKeyConnector, usesKeyConnector);
|
||||
await _stateService.SetUsesKeyConnectorAsync(usesKeyConnector);
|
||||
}
|
||||
|
||||
public async Task<bool> GetUsesKeyConnector()
|
||||
{
|
||||
if (!_usesKeyConnector.HasValue)
|
||||
{
|
||||
_usesKeyConnector = await _storageService.GetAsync<bool>(Keys_UsesKeyConnector);
|
||||
}
|
||||
|
||||
return _usesKeyConnector.Value;
|
||||
return await _stateService.GetUsesKeyConnectorAsync();
|
||||
}
|
||||
|
||||
public async Task<Organization> GetManagingOrganization()
|
||||
{
|
||||
var orgs = await _userService.GetAllOrganizationAsync();
|
||||
var orgs = await _organizationService.GetAllAsync();
|
||||
return orgs.Find(o =>
|
||||
o.UsesKeyConnector &&
|
||||
!o.IsAdmin);
|
||||
@@ -88,7 +77,7 @@ namespace Bit.Core.Services
|
||||
|
||||
public async Task<bool> UserNeedsMigration()
|
||||
{
|
||||
var loggedInUsingSso = _tokenService.GetIsExternal();
|
||||
var loggedInUsingSso = await _tokenService.GetIsExternal();
|
||||
var requiredByOrganization = await GetManagingOrganization() != null;
|
||||
var userIsNotUsingKeyConnector = !await GetUsesKeyConnector();
|
||||
|
||||
|
||||
55
src/Core/Services/OrganizationService.cs
Normal file
55
src/Core/Services/OrganizationService.cs
Normal file
@@ -0,0 +1,55 @@
|
||||
using Bit.Core.Abstractions;
|
||||
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 OrganizationService : IOrganizationService
|
||||
{
|
||||
private readonly IStateService _stateService;
|
||||
|
||||
public OrganizationService(IStateService stateService)
|
||||
{
|
||||
_stateService = stateService;
|
||||
}
|
||||
|
||||
public async Task<Organization> GetAsync(string id)
|
||||
{
|
||||
var organizations = await _stateService.GetOrganizationsAsync();
|
||||
if (organizations == null || !organizations.ContainsKey(id))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return new Organization(organizations[id]);
|
||||
}
|
||||
|
||||
public async Task<Organization> GetByIdentifierAsync(string identifier)
|
||||
{
|
||||
var organizations = await GetAllAsync();
|
||||
if (organizations == null || organizations.Count == 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return organizations.FirstOrDefault(o => o.Identifier == identifier);
|
||||
}
|
||||
|
||||
public async Task<List<Organization>> GetAllAsync(string userId = null)
|
||||
{
|
||||
var organizations = await _stateService.GetOrganizationsAsync(new StorageOptions { UserId = userId });
|
||||
return organizations?.Select(o => new Organization(o.Value)).ToList() ?? new List<Organization>();
|
||||
}
|
||||
|
||||
public async Task ReplaceAsync(Dictionary<string, OrganizationData> organizations)
|
||||
{
|
||||
await _stateService.SetOrganizationsAsync(organizations);
|
||||
}
|
||||
|
||||
public async Task ClearAllAsync(string userId)
|
||||
{
|
||||
await _stateService.SetOrganizationsAsync(null, new StorageOptions { UserId = userId });
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -14,8 +14,6 @@ namespace Bit.Core.Services
|
||||
{
|
||||
public class PasswordGenerationService : IPasswordGenerationService
|
||||
{
|
||||
private const string Keys_Options = "passwordGenerationOptions";
|
||||
private const string Keys_History = "generatedPasswordHistory";
|
||||
private const int MaxPasswordsInHistory = 100;
|
||||
private const string LowercaseCharSet = "abcdefghijkmnopqrstuvwxyz";
|
||||
private const string UppercaseCharSet = "ABCDEFGHJKLMNPQRSTUVWXYZ";
|
||||
@@ -23,7 +21,7 @@ namespace Bit.Core.Services
|
||||
private const string SpecialCharSet = "!@#$%^&*";
|
||||
|
||||
private readonly ICryptoService _cryptoService;
|
||||
private readonly IStorageService _storageService;
|
||||
private readonly IStateService _stateService;
|
||||
private readonly ICryptoFunctionService _cryptoFunctionService;
|
||||
private readonly IPolicyService _policyService;
|
||||
private PasswordGenerationOptions _defaultOptions = new PasswordGenerationOptions(true);
|
||||
@@ -32,12 +30,12 @@ namespace Bit.Core.Services
|
||||
|
||||
public PasswordGenerationService(
|
||||
ICryptoService cryptoService,
|
||||
IStorageService storageService,
|
||||
IStateService stateService,
|
||||
ICryptoFunctionService cryptoFunctionService,
|
||||
IPolicyService policyService)
|
||||
{
|
||||
_cryptoService = cryptoService;
|
||||
_storageService = storageService;
|
||||
_stateService = stateService;
|
||||
_cryptoFunctionService = cryptoFunctionService;
|
||||
_policyService = policyService;
|
||||
}
|
||||
@@ -160,6 +158,12 @@ namespace Bit.Core.Services
|
||||
return password.ToString();
|
||||
}
|
||||
|
||||
public void ClearCache()
|
||||
{
|
||||
_optionsCache = null;
|
||||
_history = null;
|
||||
}
|
||||
|
||||
public async Task<string> GeneratePassphraseAsync(PasswordGenerationOptions options)
|
||||
{
|
||||
options.Merge(_defaultOptions);
|
||||
@@ -204,7 +208,7 @@ namespace Bit.Core.Services
|
||||
{
|
||||
if (_optionsCache == null)
|
||||
{
|
||||
var options = await _storageService.GetAsync<PasswordGenerationOptions>(Keys_Options);
|
||||
var options = await _stateService.GetPasswordGenerationOptionsAsync();
|
||||
if (options == null)
|
||||
{
|
||||
_optionsCache = _defaultOptions;
|
||||
@@ -432,7 +436,7 @@ namespace Bit.Core.Services
|
||||
|
||||
public async Task SaveOptionsAsync(PasswordGenerationOptions options)
|
||||
{
|
||||
await _storageService.SaveAsync(Keys_Options, options);
|
||||
await _stateService.SetPasswordGenerationOptionsAsync(options);
|
||||
_optionsCache = options;
|
||||
}
|
||||
|
||||
@@ -445,7 +449,7 @@ namespace Bit.Core.Services
|
||||
}
|
||||
if (_history == null)
|
||||
{
|
||||
var encrypted = await _storageService.GetAsync<List<GeneratedPasswordHistory>>(Keys_History);
|
||||
var encrypted = await _stateService.GetEncryptedPasswordGenerationHistory();
|
||||
_history = await DecryptHistoryAsync(encrypted);
|
||||
}
|
||||
return _history ?? new List<GeneratedPasswordHistory>();
|
||||
@@ -473,13 +477,15 @@ namespace Bit.Core.Services
|
||||
}
|
||||
var newHistory = await EncryptHistoryAsync(currentHistory);
|
||||
token.ThrowIfCancellationRequested();
|
||||
await _storageService.SaveAsync(Keys_History, newHistory);
|
||||
var userId = await _stateService.GetActiveUserIdAsync();
|
||||
await _stateService.SetEncryptedPasswordGenerationHistoryAsync(newHistory);
|
||||
}
|
||||
|
||||
public async Task ClearAsync()
|
||||
public async Task ClearAsync(string userId = null)
|
||||
{
|
||||
_history = new List<GeneratedPasswordHistory>();
|
||||
await _storageService.RemoveAsync(Keys_History);
|
||||
await _stateService.SetEncryptedPasswordGenerationHistoryAsync(null,
|
||||
new StorageOptions { UserId = userId });
|
||||
}
|
||||
|
||||
public Result PasswordStrength(string password, List<string> userInputs = null)
|
||||
|
||||
@@ -12,19 +12,17 @@ namespace Bit.Core.Services
|
||||
{
|
||||
public class PolicyService : IPolicyService
|
||||
{
|
||||
private const string Keys_PoliciesPrefix = "policies_{0}";
|
||||
|
||||
private readonly IStorageService _storageService;
|
||||
private readonly IUserService _userService;
|
||||
private readonly IStateService _stateService;
|
||||
private readonly IOrganizationService _organizationService;
|
||||
|
||||
private IEnumerable<Policy> _policyCache;
|
||||
|
||||
public PolicyService(
|
||||
IStorageService storageService,
|
||||
IUserService userService)
|
||||
IStateService stateService,
|
||||
IOrganizationService organizationService)
|
||||
{
|
||||
_storageService = storageService;
|
||||
_userService = userService;
|
||||
_stateService = stateService;
|
||||
_organizationService = organizationService;
|
||||
}
|
||||
|
||||
public void ClearCache()
|
||||
@@ -36,9 +34,7 @@ namespace Bit.Core.Services
|
||||
{
|
||||
if (_policyCache == null)
|
||||
{
|
||||
var userId = await _userService.GetUserIdAsync();
|
||||
var policies = await _storageService.GetAsync<Dictionary<string, PolicyData>>(
|
||||
string.Format(Keys_PoliciesPrefix, userId));
|
||||
var policies = await _stateService.GetEncryptedPoliciesAsync();
|
||||
if (policies == null)
|
||||
{
|
||||
return null;
|
||||
@@ -58,14 +54,13 @@ namespace Bit.Core.Services
|
||||
|
||||
public async Task Replace(Dictionary<string, PolicyData> policies)
|
||||
{
|
||||
var userId = await _userService.GetUserIdAsync();
|
||||
await _storageService.SaveAsync(string.Format(Keys_PoliciesPrefix, userId), policies);
|
||||
await _stateService.SetEncryptedPoliciesAsync(policies);
|
||||
_policyCache = null;
|
||||
}
|
||||
|
||||
public async Task Clear(string userId)
|
||||
{
|
||||
await _storageService.RemoveAsync(string.Format(Keys_PoliciesPrefix, userId));
|
||||
await _stateService.SetEncryptedPoliciesAsync(null, new StorageOptions { UserId = userId });
|
||||
_policyCache = null;
|
||||
}
|
||||
|
||||
@@ -205,7 +200,7 @@ namespace Bit.Core.Services
|
||||
{
|
||||
return false;
|
||||
}
|
||||
var organizations = await _userService.GetAllOrganizationAsync();
|
||||
var organizations = await _organizationService.GetAllAsync();
|
||||
|
||||
IEnumerable<Policy> filteredPolicies;
|
||||
|
||||
|
||||
@@ -20,9 +20,8 @@ namespace Bit.Core.Services
|
||||
{
|
||||
private List<SendView> _decryptedSendsCache;
|
||||
private readonly ICryptoService _cryptoService;
|
||||
private readonly IUserService _userService;
|
||||
private readonly IStateService _stateService;
|
||||
private readonly IApiService _apiService;
|
||||
private readonly IStorageService _storageService;
|
||||
private readonly II18nService _i18nService;
|
||||
private readonly ICryptoFunctionService _cryptoFunctionService;
|
||||
private Task<List<SendView>> _getAllDecryptedTask;
|
||||
@@ -30,27 +29,23 @@ namespace Bit.Core.Services
|
||||
|
||||
public SendService(
|
||||
ICryptoService cryptoService,
|
||||
IUserService userService,
|
||||
IStateService stateService,
|
||||
IApiService apiService,
|
||||
IFileUploadService fileUploadService,
|
||||
IStorageService storageService,
|
||||
II18nService i18nService,
|
||||
ICryptoFunctionService cryptoFunctionService)
|
||||
{
|
||||
_cryptoService = cryptoService;
|
||||
_userService = userService;
|
||||
_stateService = stateService;
|
||||
_apiService = apiService;
|
||||
_fileUploadService = fileUploadService;
|
||||
_storageService = storageService;
|
||||
_i18nService = i18nService;
|
||||
_cryptoFunctionService = cryptoFunctionService;
|
||||
}
|
||||
|
||||
public static string GetSendKey(string userId) => string.Format("sends_{0}", userId);
|
||||
|
||||
public async Task ClearAsync(string userId)
|
||||
{
|
||||
await _storageService.RemoveAsync(GetSendKey(userId));
|
||||
await _stateService.SetEncryptedSendsAsync(null, new StorageOptions { UserId = userId });
|
||||
ClearCache();
|
||||
}
|
||||
|
||||
@@ -58,8 +53,7 @@ namespace Bit.Core.Services
|
||||
|
||||
public async Task DeleteAsync(params string[] ids)
|
||||
{
|
||||
var userId = await _userService.GetUserIdAsync();
|
||||
var sends = await _storageService.GetAsync<Dictionary<string, SendData>>(GetSendKey(userId));
|
||||
var sends = await _stateService.GetEncryptedSendsAsync();
|
||||
|
||||
if (sends == null)
|
||||
{
|
||||
@@ -71,7 +65,7 @@ namespace Bit.Core.Services
|
||||
sends.Remove(id);
|
||||
}
|
||||
|
||||
await _storageService.SaveAsync(GetSendKey(userId), sends);
|
||||
await _stateService.SetEncryptedSendsAsync(sends);
|
||||
ClearCache();
|
||||
}
|
||||
|
||||
@@ -138,8 +132,7 @@ namespace Bit.Core.Services
|
||||
|
||||
public async Task<List<Send>> GetAllAsync()
|
||||
{
|
||||
var userId = await _userService.GetUserIdAsync();
|
||||
var sends = await _storageService.GetAsync<Dictionary<string, SendData>>(GetSendKey(userId));
|
||||
var sends = await _stateService.GetEncryptedSendsAsync();
|
||||
return sends?.Select(kvp => new Send(kvp.Value)).ToList() ?? new List<Send>();
|
||||
}
|
||||
|
||||
@@ -179,8 +172,7 @@ namespace Bit.Core.Services
|
||||
|
||||
public async Task<Send> GetAsync(string id)
|
||||
{
|
||||
var userId = await _userService.GetUserIdAsync();
|
||||
var sends = await _storageService.GetAsync<Dictionary<string, SendData>>(GetSendKey(userId));
|
||||
var sends = await _stateService.GetEncryptedSendsAsync();
|
||||
|
||||
if (sends == null || !sends.ContainsKey(id))
|
||||
{
|
||||
@@ -192,8 +184,7 @@ namespace Bit.Core.Services
|
||||
|
||||
public async Task ReplaceAsync(Dictionary<string, SendData> sends)
|
||||
{
|
||||
var userId = await _userService.GetUserIdAsync();
|
||||
await _storageService.SaveAsync(GetSendKey(userId), sends);
|
||||
await _stateService.SetEncryptedSendsAsync(sends);
|
||||
_decryptedSendsCache = null;
|
||||
}
|
||||
|
||||
@@ -237,7 +228,7 @@ namespace Bit.Core.Services
|
||||
response = await _apiService.PutSendAsync(send.Id, request);
|
||||
}
|
||||
|
||||
var userId = await _userService.GetUserIdAsync();
|
||||
var userId = await _stateService.GetActiveUserIdAsync();
|
||||
await UpsertAsync(new SendData(response, userId));
|
||||
return response.Id;
|
||||
}
|
||||
@@ -255,8 +246,7 @@ namespace Bit.Core.Services
|
||||
|
||||
public async Task UpsertAsync(params SendData[] sends)
|
||||
{
|
||||
var userId = await _userService.GetUserIdAsync();
|
||||
var knownSends = await _storageService.GetAsync<Dictionary<string, SendData>>(GetSendKey(userId)) ??
|
||||
var knownSends = await _stateService.GetEncryptedSendsAsync() ??
|
||||
new Dictionary<string, SendData>();
|
||||
|
||||
foreach (var send in sends)
|
||||
@@ -264,14 +254,14 @@ namespace Bit.Core.Services
|
||||
knownSends[send.Id] = send;
|
||||
}
|
||||
|
||||
await _storageService.SaveAsync(GetSendKey(userId), knownSends);
|
||||
await _stateService.SetEncryptedSendsAsync(knownSends);
|
||||
_decryptedSendsCache = null;
|
||||
}
|
||||
|
||||
public async Task RemovePasswordWithServerAsync(string id)
|
||||
{
|
||||
var response = await _apiService.PutSendRemovePasswordAsync(id);
|
||||
var userId = await _userService.GetUserIdAsync();
|
||||
var userId = await _stateService.GetActiveUserIdAsync();
|
||||
await UpsertAsync(new SendData(response, userId));
|
||||
}
|
||||
|
||||
|
||||
@@ -1,28 +1,23 @@
|
||||
using Bit.Core.Abstractions;
|
||||
using Bit.Core.Utilities;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.Core.Models.Domain;
|
||||
|
||||
namespace Bit.Core.Services
|
||||
{
|
||||
public class SettingsService : ISettingsService
|
||||
{
|
||||
private const string Keys_SettingsFormat = "settings_{0}";
|
||||
private const string Keys_EquivalentDomains = "equivalentDomains";
|
||||
|
||||
private readonly IUserService _userService;
|
||||
private readonly IStorageService _storageService;
|
||||
private readonly IStateService _stateService;
|
||||
|
||||
private Dictionary<string, object> _settingsCache;
|
||||
|
||||
public SettingsService(
|
||||
IUserService userService,
|
||||
IStorageService storageService)
|
||||
IStateService stateService)
|
||||
{
|
||||
_userService = userService;
|
||||
_storageService = storageService;
|
||||
_stateService = stateService;
|
||||
}
|
||||
|
||||
public void ClearCache()
|
||||
@@ -49,7 +44,7 @@ namespace Bit.Core.Services
|
||||
|
||||
public async Task ClearAsync(string userId)
|
||||
{
|
||||
await _storageService.RemoveAsync(string.Format(Keys_SettingsFormat, userId));
|
||||
await _stateService.SetSettingsAsync(null, new StorageOptions { UserId = userId });
|
||||
ClearCache();
|
||||
}
|
||||
|
||||
@@ -59,16 +54,13 @@ namespace Bit.Core.Services
|
||||
{
|
||||
if (_settingsCache == null)
|
||||
{
|
||||
var userId = await _userService.GetUserIdAsync();
|
||||
_settingsCache = await _storageService.GetAsync<Dictionary<string, object>>(
|
||||
string.Format(Keys_SettingsFormat, userId));
|
||||
_settingsCache = await _stateService.GetSettingsAsync();
|
||||
}
|
||||
return _settingsCache;
|
||||
}
|
||||
|
||||
private async Task SetSettingsKeyAsync<T>(string key, T value)
|
||||
{
|
||||
var userId = await _userService.GetUserIdAsync();
|
||||
var settings = await GetSettingsAsync();
|
||||
if (settings == null)
|
||||
{
|
||||
@@ -82,7 +74,7 @@ namespace Bit.Core.Services
|
||||
{
|
||||
settings.Add(key, value);
|
||||
}
|
||||
await _storageService.SaveAsync(string.Format(Keys_SettingsFormat, userId), settings);
|
||||
await _stateService.SetSettingsAsync(settings);
|
||||
_settingsCache = settings;
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -12,16 +12,14 @@ namespace Bit.Core.Services
|
||||
{
|
||||
public class SyncService : ISyncService
|
||||
{
|
||||
private const string Keys_LastSyncFormat = "lastSync_{0}";
|
||||
|
||||
private readonly IUserService _userService;
|
||||
private readonly IStateService _stateService;
|
||||
private readonly IApiService _apiService;
|
||||
private readonly ISettingsService _settingsService;
|
||||
private readonly IFolderService _folderService;
|
||||
private readonly ICipherService _cipherService;
|
||||
private readonly ICryptoService _cryptoService;
|
||||
private readonly ICollectionService _collectionService;
|
||||
private readonly IStorageService _storageService;
|
||||
private readonly IOrganizationService _organizationService;
|
||||
private readonly IMessagingService _messagingService;
|
||||
private readonly IPolicyService _policyService;
|
||||
private readonly ISendService _sendService;
|
||||
@@ -29,28 +27,28 @@ namespace Bit.Core.Services
|
||||
private readonly Func<bool, Task> _logoutCallbackAsync;
|
||||
|
||||
public SyncService(
|
||||
IUserService userService,
|
||||
IStateService stateService,
|
||||
IApiService apiService,
|
||||
ISettingsService settingsService,
|
||||
IFolderService folderService,
|
||||
ICipherService cipherService,
|
||||
ICryptoService cryptoService,
|
||||
ICollectionService collectionService,
|
||||
IStorageService storageService,
|
||||
IOrganizationService organizationService,
|
||||
IMessagingService messagingService,
|
||||
IPolicyService policyService,
|
||||
ISendService sendService,
|
||||
IKeyConnectorService keyConnectorService,
|
||||
Func<bool, Task> logoutCallbackAsync)
|
||||
{
|
||||
_userService = userService;
|
||||
_stateService = stateService;
|
||||
_apiService = apiService;
|
||||
_settingsService = settingsService;
|
||||
_folderService = folderService;
|
||||
_cipherService = cipherService;
|
||||
_cryptoService = cryptoService;
|
||||
_collectionService = collectionService;
|
||||
_storageService = storageService;
|
||||
_organizationService = organizationService;
|
||||
_messagingService = messagingService;
|
||||
_policyService = policyService;
|
||||
_sendService = sendService;
|
||||
@@ -62,28 +60,26 @@ namespace Bit.Core.Services
|
||||
|
||||
public async Task<DateTime?> GetLastSyncAsync()
|
||||
{
|
||||
var userId = await _userService.GetUserIdAsync();
|
||||
if (userId == null)
|
||||
if (await _stateService.GetActiveUserIdAsync() == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return await _storageService.GetAsync<DateTime?>(string.Format(Keys_LastSyncFormat, userId));
|
||||
return await _stateService.GetLastSyncAsync();
|
||||
}
|
||||
|
||||
public async Task SetLastSyncAsync(DateTime date)
|
||||
{
|
||||
var userId = await _userService.GetUserIdAsync();
|
||||
if (userId == null)
|
||||
if (await _stateService.GetActiveUserIdAsync() == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
await _storageService.SaveAsync(string.Format(Keys_LastSyncFormat, userId), date);
|
||||
await _stateService.SetLastSyncAsync(date);
|
||||
}
|
||||
|
||||
public async Task<bool> FullSyncAsync(bool forceSync, bool allowThrowOnError = false)
|
||||
{
|
||||
SyncStarted();
|
||||
var isAuthenticated = await _userService.IsAuthenticatedAsync();
|
||||
var isAuthenticated = await _stateService.IsAuthenticatedAsync();
|
||||
if (!isAuthenticated)
|
||||
{
|
||||
return SyncCompleted(false);
|
||||
@@ -101,7 +97,7 @@ namespace Bit.Core.Services
|
||||
await SetLastSyncAsync(now);
|
||||
return SyncCompleted(false);
|
||||
}
|
||||
var userId = await _userService.GetUserIdAsync();
|
||||
var userId = await _stateService.GetActiveUserIdAsync();
|
||||
try
|
||||
{
|
||||
var response = await _apiService.GetSyncAsync();
|
||||
@@ -131,7 +127,7 @@ namespace Bit.Core.Services
|
||||
public async Task<bool> SyncUpsertFolderAsync(SyncFolderNotification notification, bool isEdit)
|
||||
{
|
||||
SyncStarted();
|
||||
if (await _userService.IsAuthenticatedAsync())
|
||||
if (await _stateService.IsAuthenticatedAsync())
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -142,7 +138,7 @@ namespace Bit.Core.Services
|
||||
var remoteFolder = await _apiService.GetFolderAsync(notification.Id);
|
||||
if (remoteFolder != null)
|
||||
{
|
||||
var userId = await _userService.GetUserIdAsync();
|
||||
var userId = await _stateService.GetActiveUserIdAsync();
|
||||
await _folderService.UpsertAsync(new FolderData(remoteFolder, userId));
|
||||
_messagingService.Send("syncedUpsertedFolder", new Dictionary<string, string>
|
||||
{
|
||||
@@ -160,7 +156,7 @@ namespace Bit.Core.Services
|
||||
public async Task<bool> SyncDeleteFolderAsync(SyncFolderNotification notification)
|
||||
{
|
||||
SyncStarted();
|
||||
if (await _userService.IsAuthenticatedAsync())
|
||||
if (await _stateService.IsAuthenticatedAsync())
|
||||
{
|
||||
await _folderService.DeleteAsync(notification.Id);
|
||||
_messagingService.Send("syncedDeletedFolder", new Dictionary<string, string>
|
||||
@@ -175,7 +171,7 @@ namespace Bit.Core.Services
|
||||
public async Task<bool> SyncUpsertCipherAsync(SyncCipherNotification notification, bool isEdit)
|
||||
{
|
||||
SyncStarted();
|
||||
if (await _userService.IsAuthenticatedAsync())
|
||||
if (await _stateService.IsAuthenticatedAsync())
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -230,7 +226,7 @@ namespace Bit.Core.Services
|
||||
var remoteCipher = await _apiService.GetCipherAsync(notification.Id);
|
||||
if (remoteCipher != null)
|
||||
{
|
||||
var userId = await _userService.GetUserIdAsync();
|
||||
var userId = await _stateService.GetActiveUserIdAsync();
|
||||
await _cipherService.UpsertAsync(new CipherData(remoteCipher, userId));
|
||||
_messagingService.Send("syncedUpsertedCipher", new Dictionary<string, string>
|
||||
{
|
||||
@@ -259,7 +255,7 @@ namespace Bit.Core.Services
|
||||
public async Task<bool> SyncDeleteCipherAsync(SyncCipherNotification notification)
|
||||
{
|
||||
SyncStarted();
|
||||
if (await _userService.IsAuthenticatedAsync())
|
||||
if (await _stateService.IsAuthenticatedAsync())
|
||||
{
|
||||
await _cipherService.DeleteAsync(notification.Id);
|
||||
_messagingService.Send("syncedDeletedCipher", new Dictionary<string, string>
|
||||
@@ -315,7 +311,7 @@ namespace Bit.Core.Services
|
||||
|
||||
private async Task SyncProfileAsync(ProfileResponse response)
|
||||
{
|
||||
var stamp = await _userService.GetSecurityStampAsync();
|
||||
var stamp = await _stateService.GetSecurityStampAsync();
|
||||
if (stamp != null && stamp != response.SecurityStamp)
|
||||
{
|
||||
if (_logoutCallbackAsync != null)
|
||||
@@ -327,11 +323,11 @@ namespace Bit.Core.Services
|
||||
await _cryptoService.SetEncKeyAsync(response.Key);
|
||||
await _cryptoService.SetEncPrivateKeyAsync(response.PrivateKey);
|
||||
await _cryptoService.SetOrgKeysAsync(response.Organizations);
|
||||
await _userService.SetSecurityStampAsync(response.SecurityStamp);
|
||||
await _stateService.SetSecurityStampAsync(response.SecurityStamp);
|
||||
var organizations = response.Organizations.ToDictionary(o => o.Id, o => new OrganizationData(o));
|
||||
await _userService.ReplaceOrganizationsAsync(organizations);
|
||||
await _userService.SetEmailVerifiedAsync(response.EmailVerified);
|
||||
await _userService.SetForcePasswordReset(response.ForcePasswordReset);
|
||||
await _organizationService.ReplaceAsync(organizations);
|
||||
await _stateService.SetEmailVerifiedAsync(response.EmailVerified);
|
||||
await _stateService.SetForcePasswordResetAsync(response.ForcePasswordReset);
|
||||
await _keyConnectorService.SetUsesKeyConnector(response.UsesKeyConnector);
|
||||
}
|
||||
|
||||
|
||||
@@ -5,24 +5,21 @@ using System;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Linq;
|
||||
using Bit.Core.Models.Domain;
|
||||
|
||||
namespace Bit.Core.Services
|
||||
{
|
||||
public class TokenService : ITokenService
|
||||
{
|
||||
private readonly IStorageService _storageService;
|
||||
private readonly IStateService _stateService;
|
||||
|
||||
private string _token;
|
||||
private JObject _decodedToken;
|
||||
private string _refreshToken;
|
||||
|
||||
private const string Keys_AccessToken = "accessToken";
|
||||
private const string Keys_RefreshToken = "refreshToken";
|
||||
private const string Keys_TwoFactorTokenFormat = "twoFactorToken_{0}";
|
||||
|
||||
public TokenService(IStorageService storageService)
|
||||
public TokenService(IStateService stateService)
|
||||
{
|
||||
_storageService = storageService;
|
||||
_stateService = stateService;
|
||||
}
|
||||
|
||||
public async Task SetTokensAsync(string accessToken, string refreshToken)
|
||||
@@ -43,7 +40,7 @@ namespace Bit.Core.Services
|
||||
return;
|
||||
}
|
||||
|
||||
await _storageService.SaveAsync(Keys_AccessToken, token);
|
||||
// await _stateService.SetAccessTokenAsync(token);
|
||||
}
|
||||
|
||||
public async Task<string> GetTokenAsync()
|
||||
@@ -52,7 +49,7 @@ namespace Bit.Core.Services
|
||||
{
|
||||
return _token;
|
||||
}
|
||||
_token = await _storageService.GetAsync<string>(Keys_AccessToken);
|
||||
_token = await _stateService.GetAccessTokenAsync();
|
||||
return _token;
|
||||
}
|
||||
|
||||
@@ -66,7 +63,7 @@ namespace Bit.Core.Services
|
||||
return;
|
||||
}
|
||||
|
||||
await _storageService.SaveAsync(Keys_RefreshToken, refreshToken);
|
||||
// await _stateService.SetRefreshTokenAsync(refreshToken);
|
||||
}
|
||||
|
||||
public async Task<string> GetRefreshTokenAsync()
|
||||
@@ -75,7 +72,7 @@ namespace Bit.Core.Services
|
||||
{
|
||||
return _refreshToken;
|
||||
}
|
||||
_refreshToken = await _storageService.GetAsync<string>(Keys_RefreshToken);
|
||||
_refreshToken = await _stateService.GetRefreshTokenAsync();
|
||||
return _refreshToken;
|
||||
}
|
||||
|
||||
@@ -97,27 +94,32 @@ namespace Bit.Core.Services
|
||||
|
||||
public async Task SetTwoFactorTokenAsync(string token, string email)
|
||||
{
|
||||
await _storageService.SaveAsync(string.Format(Keys_TwoFactorTokenFormat, email), token);
|
||||
await _stateService.SetTwoFactorTokenAsync(token, new StorageOptions { Email = email });
|
||||
}
|
||||
|
||||
public async Task<string> GetTwoFactorTokenAsync(string email)
|
||||
{
|
||||
return await _storageService.GetAsync<string>(string.Format(Keys_TwoFactorTokenFormat, email));
|
||||
return await _stateService.GetTwoFactorTokenAsync(new StorageOptions { Email = email });
|
||||
}
|
||||
|
||||
public async Task ClearTwoFactorTokenAsync(string email)
|
||||
{
|
||||
await _storageService.RemoveAsync(string.Format(Keys_TwoFactorTokenFormat, email));
|
||||
await _stateService.SetTwoFactorTokenAsync(null, new StorageOptions { Email = email });
|
||||
}
|
||||
|
||||
public async Task ClearTokenAsync()
|
||||
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 }));
|
||||
}
|
||||
|
||||
public void ClearCache()
|
||||
{
|
||||
_token = null;
|
||||
_decodedToken = null;
|
||||
_refreshToken = null;
|
||||
await Task.WhenAll(
|
||||
_storageService.RemoveAsync(Keys_AccessToken),
|
||||
_storageService.RemoveAsync(Keys_RefreshToken));
|
||||
}
|
||||
|
||||
public JObject DecodeToken()
|
||||
@@ -231,8 +233,12 @@ namespace Bit.Core.Services
|
||||
return decoded["iss"].Value<string>();
|
||||
}
|
||||
|
||||
public bool GetIsExternal()
|
||||
public async Task<bool> GetIsExternal()
|
||||
{
|
||||
if (_token == null)
|
||||
{
|
||||
await GetTokenAsync();
|
||||
}
|
||||
var decoded = DecodeToken();
|
||||
if (decoded?["amr"] == null)
|
||||
{
|
||||
@@ -243,8 +249,8 @@ namespace Bit.Core.Services
|
||||
|
||||
private async Task<bool> SkipTokenStorage()
|
||||
{
|
||||
var timeout = await _storageService.GetAsync<int?>(Constants.VaultTimeoutKey);
|
||||
var action = await _storageService.GetAsync<string>(Constants.VaultTimeoutActionKey);
|
||||
var timeout = await _stateService.GetVaultTimeoutAsync();
|
||||
var action = await _stateService.GetVaultTimeoutActionAsync();
|
||||
return timeout.HasValue && action == "logOut";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,14 +10,14 @@ namespace Bit.Core.Services
|
||||
{
|
||||
private const string SteamChars = "23456789BCDFGHJKMNPQRTVWXY";
|
||||
|
||||
private readonly IStorageService _storageService;
|
||||
private readonly IStateService _stateService;
|
||||
private readonly ICryptoFunctionService _cryptoFunctionService;
|
||||
|
||||
public TotpService(
|
||||
IStorageService storageService,
|
||||
IStateService stateService,
|
||||
ICryptoFunctionService cryptoFunctionService)
|
||||
{
|
||||
_storageService = storageService;
|
||||
_stateService = stateService;
|
||||
_cryptoFunctionService = cryptoFunctionService;
|
||||
}
|
||||
|
||||
@@ -135,7 +135,7 @@ namespace Bit.Core.Services
|
||||
|
||||
public async Task<bool> IsAutoCopyEnabledAsync()
|
||||
{
|
||||
var disabled = await _storageService.GetAsync<bool?>(Constants.DisableAutoTotpCopyKey);
|
||||
var disabled = await _stateService.GetDisableAutoTotpCopyAsync();
|
||||
return !disabled.GetValueOrDefault();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,9 +10,8 @@ namespace Bit.Core.Services
|
||||
public class VaultTimeoutService : IVaultTimeoutService
|
||||
{
|
||||
private readonly ICryptoService _cryptoService;
|
||||
private readonly IUserService _userService;
|
||||
private readonly IStateService _stateService;
|
||||
private readonly IPlatformUtilsService _platformUtilsService;
|
||||
private readonly IStorageService _storageService;
|
||||
private readonly IFolderService _folderService;
|
||||
private readonly ICipherService _cipherService;
|
||||
private readonly ICollectionService _collectionService;
|
||||
@@ -22,13 +21,12 @@ namespace Bit.Core.Services
|
||||
private readonly IPolicyService _policyService;
|
||||
private readonly IKeyConnectorService _keyConnectorService;
|
||||
private readonly Action<bool> _lockedCallback;
|
||||
private readonly Func<bool, Task> _loggedOutCallback;
|
||||
private readonly Func<Tuple<bool, string>, Task> _loggedOutCallback;
|
||||
|
||||
public VaultTimeoutService(
|
||||
ICryptoService cryptoService,
|
||||
IUserService userService,
|
||||
IStateService stateService,
|
||||
IPlatformUtilsService platformUtilsService,
|
||||
IStorageService storageService,
|
||||
IFolderService folderService,
|
||||
ICipherService cipherService,
|
||||
ICollectionService collectionService,
|
||||
@@ -38,12 +36,11 @@ namespace Bit.Core.Services
|
||||
IPolicyService policyService,
|
||||
IKeyConnectorService keyConnectorService,
|
||||
Action<bool> lockedCallback,
|
||||
Func<bool, Task> loggedOutCallback)
|
||||
Func<Tuple<bool, string>, Task> loggedOutCallback)
|
||||
{
|
||||
_cryptoService = cryptoService;
|
||||
_userService = userService;
|
||||
_stateService = stateService;
|
||||
_platformUtilsService = platformUtilsService;
|
||||
_storageService = storageService;
|
||||
_folderService = folderService;
|
||||
_cipherService = cipherService;
|
||||
_collectionService = collectionService;
|
||||
@@ -56,16 +53,13 @@ namespace Bit.Core.Services
|
||||
_loggedOutCallback = loggedOutCallback;
|
||||
}
|
||||
|
||||
public EncString PinProtectedKey { get; set; } = null;
|
||||
public bool BiometricLocked { get; set; } = true;
|
||||
|
||||
public async Task<bool> IsLockedAsync()
|
||||
public async Task<bool> IsLockedAsync(string userId = null)
|
||||
{
|
||||
var hasKey = await _cryptoService.HasKeyAsync();
|
||||
if (hasKey)
|
||||
{
|
||||
var biometricSet = await IsBiometricLockSetAsync();
|
||||
if (biometricSet && BiometricLocked)
|
||||
if (biometricSet && _stateService.BiometricLocked)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@@ -79,45 +73,58 @@ namespace Bit.Core.Services
|
||||
{
|
||||
return;
|
||||
}
|
||||
var authed = await _userService.IsAuthenticatedAsync();
|
||||
if (!authed)
|
||||
|
||||
foreach (var account in _stateService.Accounts)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (await IsLockedAsync())
|
||||
{
|
||||
return;
|
||||
}
|
||||
var vaultTimeoutMinutes = await GetVaultTimeout();
|
||||
if (vaultTimeoutMinutes < 0 || vaultTimeoutMinutes == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
var lastActiveTime = await _storageService.GetAsync<long?>(Constants.LastActiveTimeKey);
|
||||
if (lastActiveTime == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
var diffMs = _platformUtilsService.GetActiveTime() - lastActiveTime;
|
||||
var vaultTimeoutMs = vaultTimeoutMinutes * 60000;
|
||||
if (diffMs >= vaultTimeoutMs)
|
||||
{
|
||||
// Pivot based on saved action
|
||||
var action = await _storageService.GetAsync<string>(Constants.VaultTimeoutActionKey);
|
||||
if (action == "logOut")
|
||||
if (account.UserId != null && await ShouldLockAsync(account.UserId))
|
||||
{
|
||||
await LogOutAsync();
|
||||
}
|
||||
else
|
||||
{
|
||||
await LockAsync(true);
|
||||
await ExecuteTimeoutActionAsync(account.UserId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public async Task LockAsync(bool allowSoftLock = false, bool userInitiated = false)
|
||||
private async Task<bool> ShouldLockAsync(string userId)
|
||||
{
|
||||
var authed = await _userService.IsAuthenticatedAsync();
|
||||
var authed = await _stateService.IsAuthenticatedAsync(new StorageOptions { UserId = userId });
|
||||
if (!authed)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (await IsLockedAsync(userId))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
var vaultTimeoutMinutes = await GetVaultTimeout(userId);
|
||||
if (vaultTimeoutMinutes < 0 || vaultTimeoutMinutes == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
var lastActiveTime = await _stateService.GetLastActiveTimeAsync(new StorageOptions { UserId = userId });
|
||||
if (lastActiveTime == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
var diffMs = _platformUtilsService.GetActiveTime() - lastActiveTime;
|
||||
var vaultTimeoutMs = vaultTimeoutMinutes * 60000;
|
||||
return diffMs >= vaultTimeoutMs;
|
||||
}
|
||||
|
||||
private async Task ExecuteTimeoutActionAsync(string userId)
|
||||
{
|
||||
var action = await _stateService.GetVaultTimeoutActionAsync(new StorageOptions { UserId = userId });
|
||||
if (action == "logOut")
|
||||
{
|
||||
await LogOutAsync(userId);
|
||||
}
|
||||
else
|
||||
{
|
||||
await LockAsync(true, false, userId);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task LockAsync(bool allowSoftLock = false, bool userInitiated = false, string userId = null)
|
||||
{
|
||||
var authed = await _stateService.IsAuthenticatedAsync(new StorageOptions { UserId = userId });
|
||||
if (!authed)
|
||||
{
|
||||
return;
|
||||
@@ -125,7 +132,7 @@ namespace Bit.Core.Services
|
||||
|
||||
if (await _keyConnectorService.GetUsesKeyConnector()) {
|
||||
var pinSet = await IsPinLockSetAsync();
|
||||
var pinLock = (pinSet.Item1 && PinProtectedKey != null) || pinSet.Item2;
|
||||
var pinLock = (pinSet.Item1 && _stateService.GetPinProtectedAsync() != null) || pinSet.Item2;
|
||||
|
||||
if (!pinLock && !await IsBiometricLockSetAsync())
|
||||
{
|
||||
@@ -136,19 +143,26 @@ namespace Bit.Core.Services
|
||||
|
||||
if (allowSoftLock)
|
||||
{
|
||||
BiometricLocked = await IsBiometricLockSetAsync();
|
||||
if (BiometricLocked)
|
||||
var biometricLocked = await IsBiometricLockSetAsync();
|
||||
_stateService.BiometricLocked = biometricLocked;
|
||||
if (biometricLocked)
|
||||
{
|
||||
_messagingService.Send("locked", userInitiated);
|
||||
_lockedCallback?.Invoke(userInitiated);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (userId == null || userId == await _stateService.GetActiveUserIdAsync())
|
||||
{
|
||||
_searchService.ClearIndex();
|
||||
}
|
||||
|
||||
await Task.WhenAll(
|
||||
_cryptoService.ClearKeyAsync(),
|
||||
_cryptoService.ClearOrgKeysAsync(true),
|
||||
_cryptoService.ClearKeyPairAsync(true),
|
||||
_cryptoService.ClearEncKeyAsync(true));
|
||||
_cryptoService.ClearKeyAsync(userId),
|
||||
_cryptoService.ClearOrgKeysAsync(true, userId),
|
||||
_cryptoService.ClearKeyPairAsync(true, userId),
|
||||
_cryptoService.ClearEncKeyAsync(true, userId));
|
||||
|
||||
_folderService.ClearCache();
|
||||
await _cipherService.ClearCacheAsync();
|
||||
@@ -158,43 +172,43 @@ namespace Bit.Core.Services
|
||||
_lockedCallback?.Invoke(userInitiated);
|
||||
}
|
||||
|
||||
public async Task LogOutAsync()
|
||||
public async Task LogOutAsync(string userId = null)
|
||||
{
|
||||
if(_loggedOutCallback != null)
|
||||
{
|
||||
await _loggedOutCallback.Invoke(false);
|
||||
await _loggedOutCallback.Invoke(new Tuple<bool, string>(false, userId));
|
||||
}
|
||||
}
|
||||
|
||||
public async Task SetVaultTimeoutOptionsAsync(int? timeout, string action)
|
||||
{
|
||||
await _storageService.SaveAsync(Constants.VaultTimeoutKey, timeout);
|
||||
await _storageService.SaveAsync(Constants.VaultTimeoutActionKey, action);
|
||||
await _stateService.SetVaultTimeoutAsync(timeout);
|
||||
await _stateService.SetVaultTimeoutActionAsync(action);
|
||||
await _cryptoService.ToggleKeyAsync();
|
||||
await _tokenService.ToggleTokensAsync();
|
||||
}
|
||||
|
||||
public async Task<Tuple<bool, bool>> IsPinLockSetAsync()
|
||||
{
|
||||
var protectedPin = await _storageService.GetAsync<string>(Constants.ProtectedPin);
|
||||
var pinProtectedKey = await _storageService.GetAsync<string>(Constants.PinProtectedKey);
|
||||
var protectedPin = await _stateService.GetProtectedPinAsync();
|
||||
var pinProtectedKey = await _stateService.GetPinProtectedAsync();
|
||||
return new Tuple<bool, bool>(protectedPin != null, pinProtectedKey != null);
|
||||
}
|
||||
|
||||
public async Task<bool> IsBiometricLockSetAsync()
|
||||
{
|
||||
var biometricLock = await _storageService.GetAsync<bool?>(Constants.BiometricUnlockKey);
|
||||
var biometricLock = await _stateService.GetBiometricUnlockAsync();
|
||||
return biometricLock.GetValueOrDefault();
|
||||
}
|
||||
|
||||
public async Task ClearAsync()
|
||||
public async Task ClearAsync(string userId = null)
|
||||
{
|
||||
PinProtectedKey = null;
|
||||
await _storageService.RemoveAsync(Constants.ProtectedPin);
|
||||
await _stateService.SetPinProtectedAsync(null, new StorageOptions { UserId = userId });
|
||||
await _stateService.SetProtectedPinAsync(null, new StorageOptions { UserId = userId });
|
||||
}
|
||||
|
||||
public async Task<int?> GetVaultTimeout() {
|
||||
var vaultTimeout = await _storageService.GetAsync<int?>(Constants.VaultTimeoutKey);
|
||||
public async Task<int?> GetVaultTimeout(string userId = null) {
|
||||
var vaultTimeout = await _stateService.GetVaultTimeoutAsync();
|
||||
|
||||
if (await _policyService.PolicyAppliesToUser(PolicyType.MaximumVaultTimeout)) {
|
||||
var policy = (await _policyService.GetAll(PolicyType.MaximumVaultTimeout)).First();
|
||||
@@ -213,7 +227,7 @@ namespace Bit.Core.Services
|
||||
|
||||
// We really shouldn't need to set the value here, but multiple services relies on this value being correct.
|
||||
if (vaultTimeout != timeout) {
|
||||
await _storageService.SaveAsync(Constants.VaultTimeoutKey, timeout);
|
||||
await _stateService.SetVaultTimeoutAsync(timeout);
|
||||
}
|
||||
|
||||
return timeout;
|
||||
|
||||
@@ -22,64 +22,65 @@ namespace Bit.Core.Utilities
|
||||
|
||||
var platformUtilsService = Resolve<IPlatformUtilsService>("platformUtilsService");
|
||||
var storageService = Resolve<IStorageService>("storageService");
|
||||
var secureStorageService = Resolve<IStorageService>("secureStorageService");
|
||||
var stateService = Resolve<IStateService>("stateService");
|
||||
var i18nService = Resolve<II18nService>("i18nService");
|
||||
var messagingService = Resolve<IMessagingService>("messagingService");
|
||||
var cryptoFunctionService = Resolve<ICryptoFunctionService>("cryptoFunctionService");
|
||||
var cryptoService = Resolve<ICryptoService>("cryptoService");
|
||||
SearchService searchService = null;
|
||||
|
||||
var stateService = new StateService();
|
||||
var tokenService = new TokenService(storageService);
|
||||
var tokenService = new TokenService(stateService);
|
||||
var apiService = new ApiService(tokenService, platformUtilsService, (bool expired) =>
|
||||
{
|
||||
messagingService.Send("logout", expired);
|
||||
return Task.FromResult(0);
|
||||
}, customUserAgent);
|
||||
var appIdService = new AppIdService(storageService);
|
||||
var userService = new UserService(storageService, tokenService);
|
||||
var settingsService = new SettingsService(userService, storageService);
|
||||
var appIdService = new AppIdService(stateService);
|
||||
var organizationService = new OrganizationService(stateService);
|
||||
var settingsService = new SettingsService(stateService);
|
||||
var fileUploadService = new FileUploadService(apiService);
|
||||
var cipherService = new CipherService(cryptoService, userService, settingsService, apiService, fileUploadService,
|
||||
storageService, i18nService, () => searchService, clearCipherCacheKey, allClearCipherCacheKeys);
|
||||
var folderService = new FolderService(cryptoService, userService, apiService, storageService,
|
||||
i18nService, cipherService);
|
||||
var collectionService = new CollectionService(cryptoService, userService, storageService, i18nService);
|
||||
var sendService = new SendService(cryptoService, userService, apiService, fileUploadService, storageService,
|
||||
i18nService, cryptoFunctionService);
|
||||
var cipherService = new CipherService(cryptoService, stateService, settingsService, apiService,
|
||||
fileUploadService, storageService, i18nService, () => searchService, clearCipherCacheKey,
|
||||
allClearCipherCacheKeys);
|
||||
var folderService = new FolderService(cryptoService, stateService, apiService, i18nService, cipherService);
|
||||
var collectionService = new CollectionService(cryptoService, stateService, i18nService);
|
||||
var sendService = new SendService(cryptoService, stateService, apiService, fileUploadService, i18nService,
|
||||
cryptoFunctionService);
|
||||
searchService = new SearchService(cipherService, sendService);
|
||||
var policyService = new PolicyService(storageService, userService);
|
||||
var keyConnectorService = new KeyConnectorService(userService, cryptoService, storageService, tokenService, apiService);
|
||||
var vaultTimeoutService = new VaultTimeoutService(cryptoService, userService, platformUtilsService,
|
||||
storageService, folderService, cipherService, collectionService, searchService, messagingService, tokenService,
|
||||
policyService, keyConnectorService, null, (expired) =>
|
||||
var policyService = new PolicyService(stateService, organizationService);
|
||||
var keyConnectorService = new KeyConnectorService(stateService, cryptoService, tokenService, apiService,
|
||||
organizationService);
|
||||
var vaultTimeoutService = new VaultTimeoutService(cryptoService, stateService, platformUtilsService,
|
||||
folderService, cipherService, collectionService, searchService, messagingService, tokenService,
|
||||
policyService, keyConnectorService, null, (extras) =>
|
||||
{
|
||||
messagingService.Send("logout", expired);
|
||||
messagingService.Send("logout", extras);
|
||||
return Task.FromResult(0);
|
||||
});
|
||||
var syncService = new SyncService(userService, apiService, settingsService, folderService,
|
||||
cipherService, cryptoService, collectionService, storageService, messagingService, policyService, sendService,
|
||||
var syncService = new SyncService(stateService, apiService, settingsService, folderService, cipherService,
|
||||
cryptoService, collectionService, organizationService, messagingService, policyService, sendService,
|
||||
keyConnectorService, (bool expired) =>
|
||||
{
|
||||
messagingService.Send("logout", expired);
|
||||
return Task.FromResult(0);
|
||||
});
|
||||
var passwordGenerationService = new PasswordGenerationService(cryptoService, storageService,
|
||||
var passwordGenerationService = new PasswordGenerationService(cryptoService, stateService,
|
||||
cryptoFunctionService, policyService);
|
||||
var totpService = new TotpService(storageService, cryptoFunctionService);
|
||||
var authService = new AuthService(cryptoService, cryptoFunctionService, apiService, userService, tokenService, appIdService,
|
||||
i18nService, platformUtilsService, messagingService, vaultTimeoutService, keyConnectorService);
|
||||
var totpService = new TotpService(stateService, cryptoFunctionService);
|
||||
var authService = new AuthService(cryptoService, cryptoFunctionService, apiService, stateService,
|
||||
tokenService, appIdService, i18nService, platformUtilsService, messagingService, vaultTimeoutService,
|
||||
keyConnectorService);
|
||||
var exportService = new ExportService(folderService, cipherService, cryptoService);
|
||||
var auditService = new AuditService(cryptoFunctionService, apiService);
|
||||
var environmentService = new EnvironmentService(apiService, storageService);
|
||||
var eventService = new EventService(storageService, apiService, userService, cipherService);
|
||||
var userVerificationService = new UserVerificationService(apiService, platformUtilsService, i18nService, cryptoService);
|
||||
var environmentService = new EnvironmentService(apiService, stateService);
|
||||
var eventService = new EventService(apiService, stateService, organizationService, cipherService);
|
||||
var userVerificationService = new UserVerificationService(apiService, platformUtilsService, i18nService,
|
||||
cryptoService);
|
||||
|
||||
Register<IStateService>("stateService", stateService);
|
||||
Register<ITokenService>("tokenService", tokenService);
|
||||
Register<IApiService>("apiService", apiService);
|
||||
Register<IAppIdService>("appIdService", appIdService);
|
||||
Register<IUserService>("userService", userService);
|
||||
Register<IOrganizationService>("organizationService", organizationService);
|
||||
Register<ISettingsService>("settingsService", settingsService);
|
||||
Register<ICipherService>("cipherService", cipherService);
|
||||
Register<IFolderService>("folderService", folderService);
|
||||
|
||||
Reference in New Issue
Block a user