mirror of
https://github.com/bitwarden/mobile.git
synced 2024-12-27 17:08:00 +01:00
clear cipher cache when replacing ios autofill identities (#1112)
* clear cipher cache when replacing ios autofill identities * changed to be service-centric * support for multiple cache keys * async suffix * added cache keys for android
This commit is contained in:
parent
37e19d9a60
commit
0b7e07ebab
@ -41,7 +41,8 @@ namespace Bit.Droid
|
||||
{
|
||||
RegisterLocalServices();
|
||||
var deviceActionService = ServiceContainer.Resolve<IDeviceActionService>("deviceActionService");
|
||||
ServiceContainer.Init(deviceActionService.DeviceUserAgent);
|
||||
ServiceContainer.Init(deviceActionService.DeviceUserAgent, Constants.ClearCiphersCacheKey,
|
||||
Constants.AndroidAllClearCipherCacheKeys);
|
||||
}
|
||||
#if !FDROID
|
||||
if (Build.VERSION.SdkInt <= BuildVersionCodes.Kitkat)
|
||||
|
@ -163,7 +163,6 @@ namespace Bit.App
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine("XF App: OnStart");
|
||||
await ClearCacheIfNeededAsync();
|
||||
await TryClearCiphersCacheAsync();
|
||||
Prime();
|
||||
if (string.IsNullOrWhiteSpace(Options.Uri))
|
||||
{
|
||||
@ -214,7 +213,6 @@ namespace Bit.App
|
||||
_messagingService.Send("cancelVaultTimeoutTimer");
|
||||
_messagingService.Send("startEventTimer");
|
||||
await ClearCacheIfNeededAsync();
|
||||
await TryClearCiphersCacheAsync();
|
||||
Prime();
|
||||
SyncIfNeeded();
|
||||
if (Current.MainPage is NavigationPage navPage && navPage.CurrentPage is LockPage lockPage)
|
||||
@ -390,20 +388,6 @@ namespace Bit.App
|
||||
});
|
||||
}
|
||||
|
||||
private async Task TryClearCiphersCacheAsync()
|
||||
{
|
||||
if (Device.RuntimePlatform != Device.iOS)
|
||||
{
|
||||
return;
|
||||
}
|
||||
var clearCache = await _storageService.GetAsync<bool?>(Constants.ClearCiphersCacheKey);
|
||||
if (clearCache.GetValueOrDefault())
|
||||
{
|
||||
_cipherService.ClearCache();
|
||||
await _storageService.RemoveAsync(Constants.ClearCiphersCacheKey);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task LockedAsync(bool autoPromptBiometric)
|
||||
{
|
||||
await _stateService.PurgeAsync();
|
||||
|
@ -32,6 +32,8 @@ namespace Bit.App.Services
|
||||
Constants.MigratedFromV1AutofillPromptShown,
|
||||
Constants.TriedV1Resync,
|
||||
Constants.ClearCiphersCacheKey,
|
||||
Constants.iOSAutoFillClearCiphersCacheKey,
|
||||
Constants.iOSExtensionClearCiphersCacheKey,
|
||||
Constants.EnvironmentUrlsKey,
|
||||
};
|
||||
|
||||
|
@ -11,7 +11,7 @@ namespace Bit.Core.Abstractions
|
||||
public interface ICipherService
|
||||
{
|
||||
Task ClearAsync(string userId);
|
||||
void ClearCache();
|
||||
Task ClearCacheAsync();
|
||||
Task DeleteAsync(List<string> ids);
|
||||
Task DeleteAsync(string id);
|
||||
Task DeleteAttachmentAsync(string id, string attachmentId);
|
||||
|
@ -29,6 +29,8 @@
|
||||
public static string OldUserIdKey = "userId";
|
||||
public static string AddSitePromptShownKey = "addSitePromptShown";
|
||||
public static string ClearCiphersCacheKey = "clearCiphersCache";
|
||||
public static string iOSAutoFillClearCiphersCacheKey = "iOSAutoFillClearCiphersCache";
|
||||
public static string iOSExtensionClearCiphersCacheKey = "iOSExtensionClearCiphersCache";
|
||||
public static string MigratedFromV1 = "migratedFromV1";
|
||||
public static string MigratedFromV1AutofillPromptShown = "migratedV1AutofillPromptShown";
|
||||
public static string TriedV1Resync = "triedV1Resync";
|
||||
@ -37,5 +39,17 @@
|
||||
public const int SelectFileRequestCode = 42;
|
||||
public const int SelectFilePermissionRequestCode = 43;
|
||||
public const int SaveFileRequestCode = 44;
|
||||
|
||||
public static readonly string[] AndroidAllClearCipherCacheKeys =
|
||||
{
|
||||
ClearCiphersCacheKey
|
||||
};
|
||||
|
||||
public static readonly string[] iOSAllClearCipherCacheKeys =
|
||||
{
|
||||
ClearCiphersCacheKey,
|
||||
iOSAutoFillClearCiphersCacheKey,
|
||||
iOSExtensionClearCiphersCacheKey
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -33,6 +33,8 @@ namespace Bit.Core.Services
|
||||
private readonly IStorageService _storageService;
|
||||
private readonly II18nService _i18nService;
|
||||
private readonly Func<ISearchService> _searchService;
|
||||
private readonly string _clearCipherCacheKey;
|
||||
private readonly string[] _allClearCipherCacheKeys;
|
||||
private Dictionary<string, HashSet<string>> _domainMatchBlacklist = new Dictionary<string, HashSet<string>>
|
||||
{
|
||||
["google.com"] = new HashSet<string> { "script.google.com" }
|
||||
@ -47,7 +49,9 @@ namespace Bit.Core.Services
|
||||
IApiService apiService,
|
||||
IStorageService storageService,
|
||||
II18nService i18nService,
|
||||
Func<ISearchService> searchService)
|
||||
Func<ISearchService> searchService,
|
||||
string clearCipherCacheKey,
|
||||
string[] allClearCipherCacheKeys)
|
||||
{
|
||||
_cryptoService = cryptoService;
|
||||
_userService = userService;
|
||||
@ -56,6 +60,8 @@ namespace Bit.Core.Services
|
||||
_storageService = storageService;
|
||||
_i18nService = i18nService;
|
||||
_searchService = searchService;
|
||||
_clearCipherCacheKey = clearCipherCacheKey;
|
||||
_allClearCipherCacheKeys = allClearCipherCacheKeys;
|
||||
}
|
||||
|
||||
private List<CipherView> DecryptedCipherCache
|
||||
@ -82,9 +88,16 @@ namespace Bit.Core.Services
|
||||
}
|
||||
}
|
||||
|
||||
public void ClearCache()
|
||||
public async Task ClearCacheAsync()
|
||||
{
|
||||
DecryptedCipherCache = null;
|
||||
if (_allClearCipherCacheKeys != null && _allClearCipherCacheKeys.Length > 0)
|
||||
{
|
||||
foreach (var key in _allClearCipherCacheKeys)
|
||||
{
|
||||
await _storageService.SaveAsync(key, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<Cipher> EncryptAsync(CipherView model, SymmetricCryptoKey key = null,
|
||||
@ -218,15 +231,24 @@ namespace Bit.Core.Services
|
||||
return response?.ToList() ?? new List<Cipher>();
|
||||
}
|
||||
|
||||
public Task<List<CipherView>> GetAllDecryptedAsync()
|
||||
public async Task<List<CipherView>> GetAllDecryptedAsync()
|
||||
{
|
||||
if (_clearCipherCacheKey != null)
|
||||
{
|
||||
var clearCache = await _storageService.GetAsync<bool?>(_clearCipherCacheKey);
|
||||
if (clearCache.GetValueOrDefault())
|
||||
{
|
||||
DecryptedCipherCache = null;
|
||||
await _storageService.RemoveAsync(_clearCipherCacheKey);
|
||||
}
|
||||
}
|
||||
if (DecryptedCipherCache != null)
|
||||
{
|
||||
return Task.FromResult(DecryptedCipherCache);
|
||||
return DecryptedCipherCache;
|
||||
}
|
||||
if (_getAllDecryptedTask != null && !_getAllDecryptedTask.IsCompleted && !_getAllDecryptedTask.IsFaulted)
|
||||
{
|
||||
return _getAllDecryptedTask;
|
||||
return await _getAllDecryptedTask;
|
||||
}
|
||||
async Task<List<CipherView>> doTask()
|
||||
{
|
||||
@ -257,7 +279,7 @@ namespace Bit.Core.Services
|
||||
finally { }
|
||||
}
|
||||
_getAllDecryptedTask = doTask();
|
||||
return _getAllDecryptedTask;
|
||||
return await _getAllDecryptedTask;
|
||||
}
|
||||
|
||||
public async Task<List<CipherView>> GetAllDecryptedForGroupingAsync(string groupingId, bool folder = true)
|
||||
@ -569,7 +591,7 @@ namespace Bit.Core.Services
|
||||
}
|
||||
ciphers[cipher.Id] = cipher;
|
||||
await _storageService.SaveAsync(storageKey, ciphers);
|
||||
DecryptedCipherCache = null;
|
||||
await ClearCacheAsync();
|
||||
}
|
||||
|
||||
public async Task UpsertAsync(List<CipherData> cipher)
|
||||
@ -590,20 +612,20 @@ namespace Bit.Core.Services
|
||||
ciphers[c.Id] = c;
|
||||
}
|
||||
await _storageService.SaveAsync(storageKey, ciphers);
|
||||
DecryptedCipherCache = null;
|
||||
await ClearCacheAsync();
|
||||
}
|
||||
|
||||
public async Task ReplaceAsync(Dictionary<string, CipherData> ciphers)
|
||||
{
|
||||
var userId = await _userService.GetUserIdAsync();
|
||||
await _storageService.SaveAsync(string.Format(Keys_CiphersFormat, userId), ciphers);
|
||||
DecryptedCipherCache = null;
|
||||
await ClearCacheAsync();
|
||||
}
|
||||
|
||||
public async Task ClearAsync(string userId)
|
||||
{
|
||||
await _storageService.RemoveAsync(string.Format(Keys_CiphersFormat, userId));
|
||||
ClearCache();
|
||||
await ClearCacheAsync();
|
||||
}
|
||||
|
||||
public async Task DeleteAsync(string id)
|
||||
@ -621,7 +643,7 @@ namespace Bit.Core.Services
|
||||
}
|
||||
ciphers.Remove(id);
|
||||
await _storageService.SaveAsync(cipherKey, ciphers);
|
||||
DecryptedCipherCache = null;
|
||||
await ClearCacheAsync();
|
||||
}
|
||||
|
||||
public async Task DeleteAsync(List<string> ids)
|
||||
@ -642,7 +664,7 @@ namespace Bit.Core.Services
|
||||
ciphers.Remove(id);
|
||||
}
|
||||
await _storageService.SaveAsync(cipherKey, ciphers);
|
||||
DecryptedCipherCache = null;
|
||||
await ClearCacheAsync();
|
||||
}
|
||||
|
||||
public async Task DeleteWithServerAsync(string id)
|
||||
@ -666,7 +688,7 @@ namespace Bit.Core.Services
|
||||
ciphers[id].Attachments.Remove(attachment);
|
||||
}
|
||||
await _storageService.SaveAsync(cipherKey, ciphers);
|
||||
DecryptedCipherCache = null;
|
||||
await ClearCacheAsync();
|
||||
}
|
||||
|
||||
public async Task DeleteAttachmentWithServerAsync(string id, string attachmentId)
|
||||
@ -721,7 +743,7 @@ namespace Bit.Core.Services
|
||||
await _apiService.PutDeleteCipherAsync(id);
|
||||
ciphers[id].DeletedDate = DateTime.UtcNow;
|
||||
await _storageService.SaveAsync(cipherKey, ciphers);
|
||||
DecryptedCipherCache = null;
|
||||
await ClearCacheAsync();
|
||||
}
|
||||
|
||||
public async Task RestoreWithServerAsync(string id)
|
||||
@ -740,7 +762,7 @@ namespace Bit.Core.Services
|
||||
await _apiService.PutRestoreCipherAsync(id);
|
||||
ciphers[id].DeletedDate = null;
|
||||
await _storageService.SaveAsync(cipherKey, ciphers);
|
||||
DecryptedCipherCache = null;
|
||||
await ClearCacheAsync();
|
||||
}
|
||||
|
||||
// Helpers
|
||||
|
@ -135,7 +135,7 @@ namespace Bit.Core.Services
|
||||
_cryptoService.ClearEncKeyAsync(true));
|
||||
|
||||
_folderService.ClearCache();
|
||||
_cipherService.ClearCache();
|
||||
await _cipherService.ClearCacheAsync();
|
||||
_collectionService.ClearCache();
|
||||
_searchService.ClearIndex();
|
||||
_messagingService.Send("locked", userInitiated);
|
||||
|
@ -11,7 +11,8 @@ namespace Bit.Core.Utilities
|
||||
public static Dictionary<string, object> RegisteredServices { get; set; } = new Dictionary<string, object>();
|
||||
public static bool Inited { get; set; }
|
||||
|
||||
public static void Init(string customUserAgent = null)
|
||||
public static void Init(string customUserAgent = null, string clearCipherCacheKey = null,
|
||||
string[] allClearCipherCacheKeys = null)
|
||||
{
|
||||
if (Inited)
|
||||
{
|
||||
@ -40,7 +41,7 @@ namespace Bit.Core.Utilities
|
||||
var userService = new UserService(storageService, tokenService);
|
||||
var settingsService = new SettingsService(userService, storageService);
|
||||
var cipherService = new CipherService(cryptoService, userService, settingsService, apiService,
|
||||
storageService, i18nService, () => searchService);
|
||||
storageService, i18nService, () => searchService, clearCipherCacheKey, allClearCipherCacheKeys);
|
||||
var folderService = new FolderService(cryptoService, userService, apiService, storageService,
|
||||
i18nService, cipherService);
|
||||
var collectionService = new CollectionService(cryptoService, userService, storageService, i18nService);
|
||||
|
@ -273,7 +273,8 @@ namespace Bit.iOS.Autofill
|
||||
iOSCoreHelpers.RegisterLocalServices();
|
||||
var deviceActionService = ServiceContainer.Resolve<IDeviceActionService>("deviceActionService");
|
||||
var messagingService = ServiceContainer.Resolve<IMessagingService>("messagingService");
|
||||
ServiceContainer.Init(deviceActionService.DeviceUserAgent);
|
||||
ServiceContainer.Init(deviceActionService.DeviceUserAgent,
|
||||
Bit.Core.Constants.iOSAutoFillClearCiphersCacheKey, Bit.Core.Constants.iOSAllClearCipherCacheKeys);
|
||||
if (!_initedAppCenter)
|
||||
{
|
||||
iOSCoreHelpers.RegisterAppCenter();
|
||||
|
@ -395,7 +395,8 @@ namespace Bit.iOS.Extension
|
||||
iOSCoreHelpers.RegisterLocalServices();
|
||||
var deviceActionService = ServiceContainer.Resolve<IDeviceActionService>("deviceActionService");
|
||||
var messagingService = ServiceContainer.Resolve<IMessagingService>("messagingService");
|
||||
ServiceContainer.Init(deviceActionService.DeviceUserAgent);
|
||||
ServiceContainer.Init(deviceActionService.DeviceUserAgent,
|
||||
Bit.Core.Constants.iOSExtensionClearCiphersCacheKey, Bit.Core.Constants.iOSAllClearCipherCacheKeys);
|
||||
if (!_initedAppCenter)
|
||||
{
|
||||
iOSCoreHelpers.RegisterAppCenter();
|
||||
|
@ -301,7 +301,8 @@ namespace Bit.iOS
|
||||
iOSCoreHelpers.RegisterLocalServices();
|
||||
RegisterPush();
|
||||
var deviceActionService = ServiceContainer.Resolve<IDeviceActionService>("deviceActionService");
|
||||
ServiceContainer.Init(deviceActionService.DeviceUserAgent);
|
||||
ServiceContainer.Init(deviceActionService.DeviceUserAgent, Constants.ClearCiphersCacheKey,
|
||||
Constants.iOSAllClearCipherCacheKeys);
|
||||
iOSCoreHelpers.RegisterAppCenter();
|
||||
_pushHandler = new iOSPushNotificationHandler(
|
||||
ServiceContainer.Resolve<IPushNotificationListenerService>("pushNotificationListenerService"));
|
||||
|
Loading…
Reference in New Issue
Block a user