1
0
mirror of https://github.com/bitwarden/mobile.git synced 2024-11-24 11:55:38 +01:00

State migration storage key refinement (#2379)

This commit is contained in:
mp-bw 2023-02-16 14:44:45 -05:00 committed by GitHub
parent bf7d9b5646
commit c5d72ad7cb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 259 additions and 313 deletions

View File

@ -7,29 +7,29 @@
public const string AndroidAppProtocol = "androidapp://"; public const string AndroidAppProtocol = "androidapp://";
public const string iOSAppProtocol = "iosapp://"; public const string iOSAppProtocol = "iosapp://";
public const string DefaultUsernameGenerated = "-"; public const string DefaultUsernameGenerated = "-";
public static string StateVersionKey = "stateVersion"; public const string StateVersionKey = "stateVersion";
public static string StateKey = "state"; public const string StateKey = "state";
public static string PreAuthEnvironmentUrlsKey = "preAuthEnvironmentUrls"; public const string PreAuthEnvironmentUrlsKey = "preAuthEnvironmentUrls";
public static string LastFileCacheClearKey = "lastFileCacheClear"; public const string LastFileCacheClearKey = "lastFileCacheClear";
public static string AutofillTileAdded = "autofillTileAdded"; public const string AutofillTileAdded = "autofillTileAdded";
public static string PushRegisteredTokenKey = "pushRegisteredToken"; public const string PushRegisteredTokenKey = "pushRegisteredToken";
public static string PushInitialPromptShownKey = "pushInitialPromptShown"; public const string PushInitialPromptShownKey = "pushInitialPromptShown";
public static string PushInstallationRegistrationErrorKey = "pushInstallationRegistrationError"; public const string PushInstallationRegistrationErrorKey = "pushInstallationRegistrationError";
public static string LastBuildKey = "lastBuild"; public const string LastBuildKey = "lastBuild";
public static string AddSitePromptShownKey = "addSitePromptShown"; public const string AddSitePromptShownKey = "addSitePromptShown";
public static string ClearCiphersCacheKey = "clearCiphersCache"; public const string ClearCiphersCacheKey = "clearCiphersCache";
public static string BiometricIntegrityKey = "biometricIntegrityState"; public const string BiometricIntegrityKey = "biometricIntegrityState";
public static string iOSAutoFillClearCiphersCacheKey = "iOSAutoFillClearCiphersCache"; public const string iOSAutoFillClearCiphersCacheKey = "iOSAutoFillClearCiphersCache";
public static string iOSAutoFillBiometricIntegrityKey = "iOSAutoFillBiometricIntegrityState"; public const string iOSAutoFillBiometricIntegrityKey = "iOSAutoFillBiometricIntegrityState";
public static string iOSExtensionClearCiphersCacheKey = "iOSExtensionClearCiphersCache"; public const string iOSExtensionClearCiphersCacheKey = "iOSExtensionClearCiphersCache";
public static string iOSExtensionBiometricIntegrityKey = "iOSExtensionBiometricIntegrityState"; public const string iOSExtensionBiometricIntegrityKey = "iOSExtensionBiometricIntegrityState";
public static string iOSShareExtensionClearCiphersCacheKey = "iOSShareExtensionClearCiphersCache"; public const string iOSShareExtensionClearCiphersCacheKey = "iOSShareExtensionClearCiphersCache";
public static string iOSShareExtensionBiometricIntegrityKey = "iOSShareExtensionBiometricIntegrityState"; public const string iOSShareExtensionBiometricIntegrityKey = "iOSShareExtensionBiometricIntegrityState";
public static string iOSExtensionActiveUserIdKey = "iOSExtensionActiveUserId"; public const string iOSExtensionActiveUserIdKey = "iOSExtensionActiveUserId";
public static string EventCollectionKey = "eventCollection"; public const string EventCollectionKey = "eventCollection";
public static string RememberedEmailKey = "rememberedEmail"; public const string RememberedEmailKey = "rememberedEmail";
public static string RememberedOrgIdentifierKey = "rememberedOrgIdentifier"; public const string RememberedOrgIdentifierKey = "rememberedOrgIdentifier";
public static string PasswordlessLoginNotificationKey = "passwordlessLoginNotificationKey"; public const string PasswordlessLoginNotificationKey = "passwordlessLoginNotificationKey";
public const string ThemeKey = "theme"; public const string ThemeKey = "theme";
public const string AutoDarkThemeKey = "autoDarkTheme"; public const string AutoDarkThemeKey = "autoDarkTheme";
public const string DisableFaviconKey = "disableFavicon"; public const string DisableFaviconKey = "disableFavicon";

View File

@ -62,12 +62,11 @@ namespace Bit.Core.Services
} }
} }
// v1 to v2 Migration #region v1 to v2 Migration
private class V1Keys private class V1Keys
{ {
internal const string EnvironmentUrlsKey = "environmentUrls"; internal const string EnvironmentUrlsKey = "environmentUrls";
} }
private async Task MigrateFrom1To2Async() private async Task MigrateFrom1To2Async()
@ -87,7 +86,9 @@ namespace Bit.Core.Services
await RemoveValueAsync(Storage.LiteDb, V1Keys.EnvironmentUrlsKey); await RemoveValueAsync(Storage.LiteDb, V1Keys.EnvironmentUrlsKey);
} }
// v2 to v3 Migration #endregion
#region v2 to v3 Migration
private class V2Keys private class V2Keys
{ {
@ -203,72 +204,72 @@ namespace Bit.Core.Services
// migrate user-specific non-state data // migrate user-specific non-state data
var syncOnRefresh = await GetValueAsync<bool?>(Storage.LiteDb, V2Keys.SyncOnRefreshKey); var syncOnRefresh = await GetValueAsync<bool?>(Storage.LiteDb, V2Keys.SyncOnRefreshKey);
await SetValueAsync(Storage.LiteDb, Constants.SyncOnRefreshKey(userId), syncOnRefresh); await SetValueAsync(Storage.LiteDb, V3Keys.SyncOnRefreshKey(userId), syncOnRefresh);
var lastActiveTime = await GetValueAsync<long?>(Storage.Prefs, V2Keys.LastActiveTimeKey); var lastActiveTime = await GetValueAsync<long?>(Storage.Prefs, V2Keys.LastActiveTimeKey);
await SetValueAsync(Storage.LiteDb, Constants.LastActiveTimeKey(userId), lastActiveTime); await SetValueAsync(Storage.LiteDb, V3Keys.LastActiveTimeKey(userId), lastActiveTime);
var biometricUnlock = await GetValueAsync<bool?>(Storage.LiteDb, V2Keys.BiometricUnlockKey); var biometricUnlock = await GetValueAsync<bool?>(Storage.LiteDb, V2Keys.BiometricUnlockKey);
await SetValueAsync(Storage.LiteDb, Constants.BiometricUnlockKey(userId), biometricUnlock); await SetValueAsync(Storage.LiteDb, V3Keys.BiometricUnlockKey(userId), biometricUnlock);
var protectedPin = await GetValueAsync<string>(Storage.LiteDb, V2Keys.ProtectedPin); var protectedPin = await GetValueAsync<string>(Storage.LiteDb, V2Keys.ProtectedPin);
await SetValueAsync(Storage.LiteDb, Constants.ProtectedPinKey(userId), protectedPin); await SetValueAsync(Storage.LiteDb, V3Keys.ProtectedPinKey(userId), protectedPin);
var pinProtectedKey = await GetValueAsync<string>(Storage.LiteDb, V2Keys.PinProtectedKey); var pinProtectedKey = await GetValueAsync<string>(Storage.LiteDb, V2Keys.PinProtectedKey);
await SetValueAsync(Storage.LiteDb, Constants.PinProtectedKey(userId), pinProtectedKey); await SetValueAsync(Storage.LiteDb, V3Keys.PinProtectedKey(userId), pinProtectedKey);
var defaultUriMatch = await GetValueAsync<int?>(Storage.Prefs, V2Keys.DefaultUriMatch); var defaultUriMatch = await GetValueAsync<int?>(Storage.Prefs, V2Keys.DefaultUriMatch);
await SetValueAsync(Storage.LiteDb, Constants.DefaultUriMatchKey(userId), defaultUriMatch); await SetValueAsync(Storage.LiteDb, V3Keys.DefaultUriMatchKey(userId), defaultUriMatch);
var disableAutoTotpCopy = await GetValueAsync<bool?>(Storage.Prefs, V2Keys.DisableAutoTotpCopyKey); var disableAutoTotpCopy = await GetValueAsync<bool?>(Storage.Prefs, V2Keys.DisableAutoTotpCopyKey);
await SetValueAsync(Storage.LiteDb, Constants.DisableAutoTotpCopyKey(userId), disableAutoTotpCopy); await SetValueAsync(Storage.LiteDb, V3Keys.DisableAutoTotpCopyKey(userId), disableAutoTotpCopy);
var autofillDisableSavePrompt = var autofillDisableSavePrompt =
await GetValueAsync<bool?>(Storage.Prefs, V2Keys.AutofillDisableSavePromptKey); await GetValueAsync<bool?>(Storage.Prefs, V2Keys.AutofillDisableSavePromptKey);
await SetValueAsync(Storage.LiteDb, Constants.AutofillDisableSavePromptKey(userId), await SetValueAsync(Storage.LiteDb, V3Keys.AutofillDisableSavePromptKey(userId),
autofillDisableSavePrompt); autofillDisableSavePrompt);
var autofillBlacklistedUris = var autofillBlacklistedUris =
await GetValueAsync<List<string>>(Storage.LiteDb, V2Keys.AutofillBlacklistedUrisKey); await GetValueAsync<List<string>>(Storage.LiteDb, V2Keys.AutofillBlacklistedUrisKey);
await SetValueAsync(Storage.LiteDb, Constants.AutofillBlacklistedUrisKey(userId), autofillBlacklistedUris); await SetValueAsync(Storage.LiteDb, V3Keys.AutofillBlacklistedUrisKey(userId), autofillBlacklistedUris);
var disableFavicon = await GetValueAsync<bool?>(Storage.Prefs, V2Keys.DisableFaviconKey); var disableFavicon = await GetValueAsync<bool?>(Storage.Prefs, V2Keys.DisableFaviconKey);
await SetValueAsync(Storage.LiteDb, V3Keys.DisableFaviconKey(userId), disableFavicon); await SetValueAsync(Storage.LiteDb, V3Keys.DisableFaviconKey(userId), disableFavicon);
var theme = await GetValueAsync<string>(Storage.Prefs, V2Keys.ThemeKey); var theme = await GetValueAsync<string>(Storage.Prefs, V2Keys.ThemeKey);
await SetValueAsync(Storage.LiteDb, V3Keys.ThemeKey(userId), theme); await SetValueAsync(Storage.LiteDb, V3Keys.ThemeKey(userId), theme);
var clearClipboard = await GetValueAsync<int?>(Storage.Prefs, V2Keys.ClearClipboardKey); var clearClipboard = await GetValueAsync<int?>(Storage.Prefs, V2Keys.ClearClipboardKey);
await SetValueAsync(Storage.LiteDb, Constants.ClearClipboardKey(userId), clearClipboard); await SetValueAsync(Storage.LiteDb, V3Keys.ClearClipboardKey(userId), clearClipboard);
var previousPage = await GetValueAsync<PreviousPageInfo>(Storage.LiteDb, V2Keys.PreviousPageKey); var previousPage = await GetValueAsync<PreviousPageInfo>(Storage.LiteDb, V2Keys.PreviousPageKey);
await SetValueAsync(Storage.LiteDb, Constants.PreviousPageKey(userId), previousPage); await SetValueAsync(Storage.LiteDb, V3Keys.PreviousPageKey(userId), previousPage);
var inlineAutofillEnabled = await GetValueAsync<bool?>(Storage.Prefs, V2Keys.InlineAutofillEnabledKey); var inlineAutofillEnabled = await GetValueAsync<bool?>(Storage.Prefs, V2Keys.InlineAutofillEnabledKey);
await SetValueAsync(Storage.LiteDb, Constants.InlineAutofillEnabledKey(userId), inlineAutofillEnabled); await SetValueAsync(Storage.LiteDb, V3Keys.InlineAutofillEnabledKey(userId), inlineAutofillEnabled);
var invalidUnlockAttempts = await GetValueAsync<int?>(Storage.Prefs, V2Keys.InvalidUnlockAttempts); var invalidUnlockAttempts = await GetValueAsync<int?>(Storage.Prefs, V2Keys.InvalidUnlockAttempts);
await SetValueAsync(Storage.LiteDb, Constants.InvalidUnlockAttemptsKey(userId), invalidUnlockAttempts); await SetValueAsync(Storage.LiteDb, V3Keys.InvalidUnlockAttemptsKey(userId), invalidUnlockAttempts);
var passwordRepromptAutofill = var passwordRepromptAutofill =
await GetValueAsync<bool?>(Storage.LiteDb, V2Keys.PasswordRepromptAutofillKey); await GetValueAsync<bool?>(Storage.LiteDb, V2Keys.PasswordRepromptAutofillKey);
await SetValueAsync(Storage.LiteDb, Constants.PasswordRepromptAutofillKey(userId), await SetValueAsync(Storage.LiteDb, V3Keys.PasswordRepromptAutofillKey(userId),
passwordRepromptAutofill); passwordRepromptAutofill);
var passwordVerifiedAutofill = var passwordVerifiedAutofill =
await GetValueAsync<bool?>(Storage.LiteDb, V2Keys.PasswordVerifiedAutofillKey); await GetValueAsync<bool?>(Storage.LiteDb, V2Keys.PasswordVerifiedAutofillKey);
await SetValueAsync(Storage.LiteDb, Constants.PasswordVerifiedAutofillKey(userId), await SetValueAsync(Storage.LiteDb, V3Keys.PasswordVerifiedAutofillKey(userId),
passwordVerifiedAutofill); passwordVerifiedAutofill);
var cipherLocalData = await GetValueAsync<Dictionary<string, Dictionary<string, object>>>(Storage.LiteDb, var cipherLocalData = await GetValueAsync<Dictionary<string, Dictionary<string, object>>>(Storage.LiteDb,
V2Keys.Keys_LocalData); V2Keys.Keys_LocalData);
await SetValueAsync(Storage.LiteDb, Constants.LocalDataKey(userId), cipherLocalData); await SetValueAsync(Storage.LiteDb, V3Keys.LocalDataKey(userId), cipherLocalData);
var neverDomains = await GetValueAsync<HashSet<string>>(Storage.LiteDb, V2Keys.Keys_NeverDomains); var neverDomains = await GetValueAsync<HashSet<string>>(Storage.LiteDb, V2Keys.Keys_NeverDomains);
await SetValueAsync(Storage.LiteDb, Constants.NeverDomainsKey(userId), neverDomains); await SetValueAsync(Storage.LiteDb, V3Keys.NeverDomainsKey(userId), neverDomains);
var key = await GetValueAsync<string>(Storage.Secure, V2Keys.Keys_Key); var key = await GetValueAsync<string>(Storage.Secure, V2Keys.Keys_Key);
await SetValueAsync(Storage.Secure, Constants.KeyKey(userId), key); await SetValueAsync(Storage.Secure, V3Keys.KeyKey(userId), key);
var encOrgKeys = await GetValueAsync<Dictionary<string, string>>(Storage.LiteDb, V2Keys.Keys_EncOrgKeys); var encOrgKeys = await GetValueAsync<Dictionary<string, string>>(Storage.LiteDb, V2Keys.Keys_EncOrgKeys);
await SetValueAsync(Storage.LiteDb, Constants.EncOrgKeysKey(userId), encOrgKeys); await SetValueAsync(Storage.LiteDb, V3Keys.EncOrgKeysKey(userId), encOrgKeys);
var encPrivateKey = await GetValueAsync<string>(Storage.LiteDb, V2Keys.Keys_EncPrivateKey); var encPrivateKey = await GetValueAsync<string>(Storage.LiteDb, V2Keys.Keys_EncPrivateKey);
await SetValueAsync(Storage.LiteDb, Constants.EncPrivateKeyKey(userId), encPrivateKey); await SetValueAsync(Storage.LiteDb, V3Keys.EncPrivateKeyKey(userId), encPrivateKey);
var encKey = await GetValueAsync<string>(Storage.LiteDb, V2Keys.Keys_EncKey); var encKey = await GetValueAsync<string>(Storage.LiteDb, V2Keys.Keys_EncKey);
await SetValueAsync(Storage.LiteDb, Constants.EncKeyKey(userId), encKey); await SetValueAsync(Storage.LiteDb, V3Keys.EncKeyKey(userId), encKey);
var keyHash = await GetValueAsync<string>(Storage.LiteDb, V2Keys.Keys_KeyHash); var keyHash = await GetValueAsync<string>(Storage.LiteDb, V2Keys.Keys_KeyHash);
await SetValueAsync(Storage.LiteDb, Constants.KeyHashKey(userId), keyHash); await SetValueAsync(Storage.LiteDb, V3Keys.KeyHashKey(userId), keyHash);
var usesKeyConnector = await GetValueAsync<bool?>(Storage.LiteDb, V2Keys.Keys_UsesKeyConnector); var usesKeyConnector = await GetValueAsync<bool?>(Storage.LiteDb, V2Keys.Keys_UsesKeyConnector);
await SetValueAsync(Storage.LiteDb, Constants.UsesKeyConnectorKey(userId), usesKeyConnector); await SetValueAsync(Storage.LiteDb, V3Keys.UsesKeyConnectorKey(userId), usesKeyConnector);
var passGenOptions = var passGenOptions =
await GetValueAsync<PasswordGenerationOptions>(Storage.LiteDb, V2Keys.Keys_PassGenOptions); await GetValueAsync<PasswordGenerationOptions>(Storage.LiteDb, V2Keys.Keys_PassGenOptions);
await SetValueAsync(Storage.LiteDb, Constants.PassGenOptionsKey(userId), passGenOptions); await SetValueAsync(Storage.LiteDb, V3Keys.PassGenOptionsKey(userId), passGenOptions);
var passGenHistory = var passGenHistory =
await GetValueAsync<List<GeneratedPasswordHistory>>(Storage.LiteDb, V2Keys.Keys_PassGenHistory); await GetValueAsync<List<GeneratedPasswordHistory>>(Storage.LiteDb, V2Keys.Keys_PassGenHistory);
await SetValueAsync(Storage.LiteDb, Constants.PassGenHistoryKey(userId), passGenHistory); await SetValueAsync(Storage.LiteDb, V3Keys.PassGenHistoryKey(userId), passGenHistory);
// migrate global non-state data // migrate global non-state data
await SetValueAsync(Storage.Prefs, Constants.PreAuthEnvironmentUrlsKey, environmentUrls); await SetValueAsync(Storage.Prefs, V3Keys.PreAuthEnvironmentUrlsKey, environmentUrls);
// Update stored version // Update stored version
await SetLastStateVersionAsync(3); await SetLastStateVersionAsync(3);
@ -318,10 +319,43 @@ namespace Bit.Core.Services
await RemoveValueAsync(Storage.LiteDb, V2Keys.Keys_PassGenHistory); await RemoveValueAsync(Storage.LiteDb, V2Keys.Keys_PassGenHistory);
} }
// v3 to v4 Migration #endregion
#region v3 to v4 Migration
private class V3Keys private class V3Keys
{ {
internal const string PreAuthEnvironmentUrlsKey = "preAuthEnvironmentUrls";
internal static string LocalDataKey(string userId) => $"ciphersLocalData_{userId}";
internal static string NeverDomainsKey(string userId) => $"neverDomains_{userId}";
internal static string KeyKey(string userId) => $"key_{userId}";
internal static string EncOrgKeysKey(string userId) => $"encOrgKeys_{userId}";
internal static string EncPrivateKeyKey(string userId) => $"encPrivateKey_{userId}";
internal static string EncKeyKey(string userId) => $"encKey_{userId}";
internal static string KeyHashKey(string userId) => $"keyHash_{userId}";
internal static string PinProtectedKey(string userId) => $"pinProtectedKey_{userId}";
internal static string PassGenOptionsKey(string userId) => $"passwordGenerationOptions_{userId}";
internal static string PassGenHistoryKey(string userId) => $"generatedPasswordHistory_{userId}";
internal static string LastActiveTimeKey(string userId) => $"lastActiveTime_{userId}";
internal static string InvalidUnlockAttemptsKey(string userId) => $"invalidUnlockAttempts_{userId}";
internal static string InlineAutofillEnabledKey(string userId) => $"inlineAutofillEnabled_{userId}";
internal static string AutofillDisableSavePromptKey(string userId) => $"autofillDisableSavePrompt_{userId}";
internal static string AutofillBlacklistedUrisKey(string userId) => $"autofillBlacklistedUris_{userId}";
internal static string ClearClipboardKey(string userId) => $"clearClipboard_{userId}";
internal static string SyncOnRefreshKey(string userId) => $"syncOnRefresh_{userId}";
internal static string DefaultUriMatchKey(string userId) => $"defaultUriMatch_{userId}";
internal static string DisableAutoTotpCopyKey(string userId) => $"disableAutoTotpCopy_{userId}";
internal static string PreviousPageKey(string userId) => $"previousPage_{userId}";
internal static string PasswordRepromptAutofillKey(string userId) =>
$"passwordRepromptAutofillKey_{userId}";
internal static string PasswordVerifiedAutofillKey(string userId) =>
$"passwordVerifiedAutofillKey_{userId}";
internal static string UsesKeyConnectorKey(string userId) => $"usesKeyConnector_{userId}";
internal static string ProtectedPinKey(string userId) => $"protectedPin_{userId}";
internal static string BiometricUnlockKey(string userId) => $"biometricUnlock_{userId}";
internal static string ThemeKey(string userId) => $"theme_{userId}"; internal static string ThemeKey(string userId) => $"theme_{userId}";
internal static string AutoDarkThemeKey(string userId) => $"autoDarkTheme_{userId}"; internal static string AutoDarkThemeKey(string userId) => $"autoDarkTheme_{userId}";
internal static string DisableFaviconKey(string userId) => $"disableFavicon_{userId}"; internal static string DisableFaviconKey(string userId) => $"disableFavicon_{userId}";
@ -398,6 +432,8 @@ namespace Bit.Core.Services
internal const string DisableFaviconKey = "disableFavicon"; internal const string DisableFaviconKey = "disableFavicon";
} }
#endregion
// Helpers // Helpers
private async Task<int> GetLastStateVersionAsync() private async Task<int> GetLastStateVersionAsync()

File diff suppressed because it is too large Load Diff