2019-05-17 19:03:35 +03:00
|
|
|
|
using Bit.App.Abstractions;
|
|
|
|
|
using Bit.App.Models;
|
2019-04-10 06:24:03 +03:00
|
|
|
|
using Bit.App.Pages;
|
2019-04-11 22:33:10 +03:00
|
|
|
|
using Bit.App.Resources;
|
|
|
|
|
using Bit.App.Services;
|
2019-03-30 04:23:34 +03:00
|
|
|
|
using Bit.App.Utilities;
|
2019-05-16 19:30:20 +03:00
|
|
|
|
using Bit.Core;
|
2019-04-11 22:33:10 +03:00
|
|
|
|
using Bit.Core.Abstractions;
|
|
|
|
|
using Bit.Core.Utilities;
|
2019-03-29 00:10:10 +03:00
|
|
|
|
using System;
|
2019-04-19 23:40:20 +03:00
|
|
|
|
using System.Threading.Tasks;
|
2019-03-28 03:12:44 +03:00
|
|
|
|
using Xamarin.Forms;
|
|
|
|
|
using Xamarin.Forms.Xaml;
|
|
|
|
|
|
|
|
|
|
[assembly: XamlCompilation(XamlCompilationOptions.Compile)]
|
|
|
|
|
namespace Bit.App
|
|
|
|
|
{
|
|
|
|
|
public partial class App : Application
|
|
|
|
|
{
|
2019-04-11 22:33:10 +03:00
|
|
|
|
private readonly MobileI18nService _i18nService;
|
2019-04-19 16:42:55 +03:00
|
|
|
|
private readonly IUserService _userService;
|
2019-04-18 20:15:46 +03:00
|
|
|
|
private readonly IBroadcasterService _broadcasterService;
|
|
|
|
|
private readonly IMessagingService _messagingService;
|
2019-05-15 22:47:50 +03:00
|
|
|
|
private readonly IStateService _stateService;
|
2020-05-29 19:26:36 +03:00
|
|
|
|
private readonly IVaultTimeoutService _vaultTimeoutService;
|
2019-05-16 00:37:59 +03:00
|
|
|
|
private readonly ISyncService _syncService;
|
|
|
|
|
private readonly ITokenService _tokenService;
|
|
|
|
|
private readonly ICryptoService _cryptoService;
|
|
|
|
|
private readonly ICipherService _cipherService;
|
|
|
|
|
private readonly IFolderService _folderService;
|
|
|
|
|
private readonly ICollectionService _collectionService;
|
|
|
|
|
private readonly ISettingsService _settingsService;
|
|
|
|
|
private readonly IPasswordGenerationService _passwordGenerationService;
|
|
|
|
|
private readonly ISearchService _searchService;
|
|
|
|
|
private readonly IPlatformUtilsService _platformUtilsService;
|
|
|
|
|
private readonly IAuthService _authService;
|
2019-05-16 19:30:20 +03:00
|
|
|
|
private readonly IStorageService _storageService;
|
2019-06-01 00:49:51 +03:00
|
|
|
|
private readonly IStorageService _secureStorageService;
|
2019-05-17 19:03:35 +03:00
|
|
|
|
private readonly IDeviceActionService _deviceActionService;
|
2019-04-11 22:33:10 +03:00
|
|
|
|
|
2020-03-06 00:18:04 +03:00
|
|
|
|
private static bool _isResumed;
|
|
|
|
|
|
2019-05-17 19:03:35 +03:00
|
|
|
|
public App(AppOptions appOptions)
|
2019-03-28 03:12:44 +03:00
|
|
|
|
{
|
2020-05-29 19:26:36 +03:00
|
|
|
|
Options = appOptions ?? new AppOptions();
|
2020-05-29 22:25:06 +03:00
|
|
|
|
if (Options.IosExtension)
|
2020-05-29 19:26:36 +03:00
|
|
|
|
{
|
|
|
|
|
Current = this;
|
|
|
|
|
return;
|
|
|
|
|
}
|
2019-04-19 16:42:55 +03:00
|
|
|
|
_userService = ServiceContainer.Resolve<IUserService>("userService");
|
2019-04-18 20:15:46 +03:00
|
|
|
|
_broadcasterService = ServiceContainer.Resolve<IBroadcasterService>("broadcasterService");
|
|
|
|
|
_messagingService = ServiceContainer.Resolve<IMessagingService>("messagingService");
|
2019-05-15 22:47:50 +03:00
|
|
|
|
_stateService = ServiceContainer.Resolve<IStateService>("stateService");
|
2020-05-29 19:26:36 +03:00
|
|
|
|
_vaultTimeoutService = ServiceContainer.Resolve<IVaultTimeoutService>("vaultTimeoutService");
|
2019-05-16 00:37:59 +03:00
|
|
|
|
_syncService = ServiceContainer.Resolve<ISyncService>("syncService");
|
|
|
|
|
_tokenService = ServiceContainer.Resolve<ITokenService>("tokenService");
|
|
|
|
|
_cryptoService = ServiceContainer.Resolve<ICryptoService>("cryptoService");
|
|
|
|
|
_cipherService = ServiceContainer.Resolve<ICipherService>("cipherService");
|
|
|
|
|
_folderService = ServiceContainer.Resolve<IFolderService>("folderService");
|
|
|
|
|
_settingsService = ServiceContainer.Resolve<ISettingsService>("settingsService");
|
|
|
|
|
_collectionService = ServiceContainer.Resolve<ICollectionService>("collectionService");
|
|
|
|
|
_searchService = ServiceContainer.Resolve<ISearchService>("searchService");
|
|
|
|
|
_authService = ServiceContainer.Resolve<IAuthService>("authService");
|
|
|
|
|
_platformUtilsService = ServiceContainer.Resolve<IPlatformUtilsService>("platformUtilsService");
|
2019-05-16 19:30:20 +03:00
|
|
|
|
_storageService = ServiceContainer.Resolve<IStorageService>("storageService");
|
2019-06-01 00:49:51 +03:00
|
|
|
|
_secureStorageService = ServiceContainer.Resolve<IStorageService>("secureStorageService");
|
2019-05-16 00:37:59 +03:00
|
|
|
|
_passwordGenerationService = ServiceContainer.Resolve<IPasswordGenerationService>(
|
|
|
|
|
"passwordGenerationService");
|
2019-04-11 22:33:10 +03:00
|
|
|
|
_i18nService = ServiceContainer.Resolve<II18nService>("i18nService") as MobileI18nService;
|
2019-05-17 19:03:35 +03:00
|
|
|
|
_deviceActionService = ServiceContainer.Resolve<IDeviceActionService>("deviceActionService");
|
2019-03-30 00:54:03 +03:00
|
|
|
|
|
2019-05-29 22:50:20 +03:00
|
|
|
|
Bootstrap();
|
2019-04-19 19:29:37 +03:00
|
|
|
|
_broadcasterService.Subscribe(nameof(App), async (message) =>
|
2019-04-10 06:24:03 +03:00
|
|
|
|
{
|
2020-03-28 16:16:28 +03:00
|
|
|
|
if (message.Command == "showDialog")
|
2019-04-10 06:24:03 +03:00
|
|
|
|
{
|
2019-04-19 19:29:37 +03:00
|
|
|
|
var details = message.Data as DialogDetails;
|
|
|
|
|
var confirmed = true;
|
|
|
|
|
var confirmText = string.IsNullOrWhiteSpace(details.ConfirmText) ?
|
|
|
|
|
AppResources.Ok : details.ConfirmText;
|
2019-05-30 18:40:33 +03:00
|
|
|
|
Device.BeginInvokeOnMainThread(async () =>
|
2019-04-19 19:29:37 +03:00
|
|
|
|
{
|
2020-03-28 16:16:28 +03:00
|
|
|
|
if (!string.IsNullOrWhiteSpace(details.CancelText))
|
2019-05-30 18:40:33 +03:00
|
|
|
|
{
|
2019-05-31 01:27:57 +03:00
|
|
|
|
confirmed = await Current.MainPage.DisplayAlert(details.Title, details.Text, confirmText,
|
2019-05-30 18:40:33 +03:00
|
|
|
|
details.CancelText);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2019-05-31 01:27:57 +03:00
|
|
|
|
await Current.MainPage.DisplayAlert(details.Title, details.Text, confirmText);
|
2019-05-30 18:40:33 +03:00
|
|
|
|
}
|
|
|
|
|
_messagingService.Send("showDialogResolve", new Tuple<int, bool>(details.DialogId, confirmed));
|
|
|
|
|
});
|
2019-04-10 06:24:03 +03:00
|
|
|
|
}
|
2020-03-28 16:16:28 +03:00
|
|
|
|
else if (message.Command == "locked")
|
2019-05-15 22:47:50 +03:00
|
|
|
|
{
|
2019-07-31 23:50:16 +03:00
|
|
|
|
await LockedAsync(!(message.Data as bool?).GetValueOrDefault());
|
2019-05-16 00:37:59 +03:00
|
|
|
|
}
|
2020-03-28 16:16:28 +03:00
|
|
|
|
else if (message.Command == "lockVault")
|
2019-05-16 00:37:59 +03:00
|
|
|
|
{
|
2020-05-29 19:26:36 +03:00
|
|
|
|
await _vaultTimeoutService.LockAsync(true);
|
2019-05-16 00:37:59 +03:00
|
|
|
|
}
|
2020-03-28 16:16:28 +03:00
|
|
|
|
else if (message.Command == "logout")
|
2019-05-16 00:37:59 +03:00
|
|
|
|
{
|
2019-10-22 23:30:28 +03:00
|
|
|
|
Device.BeginInvokeOnMainThread(async () =>
|
|
|
|
|
await LogOutAsync((message.Data as bool?).GetValueOrDefault()));
|
2019-05-16 00:37:59 +03:00
|
|
|
|
}
|
2020-03-28 16:16:28 +03:00
|
|
|
|
else if (message.Command == "loggedOut")
|
2019-05-16 00:37:59 +03:00
|
|
|
|
{
|
2019-06-01 00:49:51 +03:00
|
|
|
|
// Clean up old migrated key if they ever log out.
|
|
|
|
|
await _secureStorageService.RemoveAsync("oldKey");
|
2019-05-16 00:37:59 +03:00
|
|
|
|
}
|
2020-03-28 16:16:28 +03:00
|
|
|
|
else if (message.Command == "resumed")
|
2019-05-30 21:13:02 +03:00
|
|
|
|
{
|
2020-03-28 16:16:28 +03:00
|
|
|
|
if (Device.RuntimePlatform == Device.iOS)
|
2019-05-30 21:13:02 +03:00
|
|
|
|
{
|
2019-06-25 00:02:05 +03:00
|
|
|
|
ResumedAsync();
|
2019-05-30 21:13:02 +03:00
|
|
|
|
}
|
|
|
|
|
}
|
2020-03-28 16:16:28 +03:00
|
|
|
|
else if (message.Command == "slept")
|
2019-07-14 03:25:31 +03:00
|
|
|
|
{
|
2020-03-28 16:16:28 +03:00
|
|
|
|
if (Device.RuntimePlatform == Device.iOS)
|
2019-07-14 03:25:31 +03:00
|
|
|
|
{
|
|
|
|
|
await SleptAsync();
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-03-28 16:16:28 +03:00
|
|
|
|
else if (message.Command == "migrated")
|
2019-06-02 06:33:36 +03:00
|
|
|
|
{
|
|
|
|
|
await Task.Delay(1000);
|
|
|
|
|
await SetMainPageAsync();
|
|
|
|
|
}
|
2020-03-28 16:16:28 +03:00
|
|
|
|
else if (message.Command == "popAllAndGoToTabGenerator" ||
|
2019-06-05 23:37:54 +03:00
|
|
|
|
message.Command == "popAllAndGoToTabMyVault")
|
|
|
|
|
{
|
|
|
|
|
Device.BeginInvokeOnMainThread(async () =>
|
|
|
|
|
{
|
2020-03-28 16:16:28 +03:00
|
|
|
|
if (Current.MainPage is TabsPage tabsPage)
|
2019-06-05 23:37:54 +03:00
|
|
|
|
{
|
2020-03-28 16:16:28 +03:00
|
|
|
|
while (tabsPage.Navigation.ModalStack.Count > 0)
|
2019-06-05 23:37:54 +03:00
|
|
|
|
{
|
|
|
|
|
await tabsPage.Navigation.PopModalAsync(false);
|
|
|
|
|
}
|
2020-03-28 16:16:28 +03:00
|
|
|
|
if (message.Command == "popAllAndGoToTabMyVault")
|
2019-06-05 23:37:54 +03:00
|
|
|
|
{
|
2020-05-29 19:26:36 +03:00
|
|
|
|
Options.MyVaultTile = false;
|
2019-06-05 23:37:54 +03:00
|
|
|
|
tabsPage.ResetToVaultPage();
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2020-05-29 19:26:36 +03:00
|
|
|
|
Options.GeneratorTile = false;
|
2019-06-05 23:37:54 +03:00
|
|
|
|
tabsPage.ResetToGeneratorPage();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
2019-04-10 06:24:03 +03:00
|
|
|
|
});
|
2019-03-28 03:12:44 +03:00
|
|
|
|
}
|
2020-05-29 19:26:36 +03:00
|
|
|
|
|
|
|
|
|
public AppOptions Options { get; private set; }
|
|
|
|
|
|
2019-05-17 19:03:35 +03:00
|
|
|
|
protected async override void OnStart()
|
2019-03-28 03:12:44 +03:00
|
|
|
|
{
|
2019-05-16 19:30:20 +03:00
|
|
|
|
System.Diagnostics.Debug.WriteLine("XF App: OnStart");
|
2019-05-17 19:03:35 +03:00
|
|
|
|
await ClearCacheIfNeededAsync();
|
2019-05-29 00:18:27 +03:00
|
|
|
|
Prime();
|
2020-05-29 19:26:36 +03:00
|
|
|
|
if (string.IsNullOrWhiteSpace(Options.Uri))
|
2019-05-30 21:13:02 +03:00
|
|
|
|
{
|
|
|
|
|
var updated = await AppHelpers.PerformUpdateTasksAsync(_syncService, _deviceActionService,
|
|
|
|
|
_storageService);
|
2020-03-28 16:16:28 +03:00
|
|
|
|
if (!updated)
|
2019-05-30 21:13:02 +03:00
|
|
|
|
{
|
|
|
|
|
SyncIfNeeded();
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-07-13 00:29:40 +03:00
|
|
|
|
_messagingService.Send("startEventTimer");
|
2019-03-28 03:12:44 +03:00
|
|
|
|
}
|
|
|
|
|
|
2019-05-16 19:30:20 +03:00
|
|
|
|
protected async override void OnSleep()
|
2019-03-28 03:12:44 +03:00
|
|
|
|
{
|
2019-05-16 19:30:20 +03:00
|
|
|
|
System.Diagnostics.Debug.WriteLine("XF App: OnSleep");
|
2020-03-06 00:18:04 +03:00
|
|
|
|
_isResumed = false;
|
2020-03-28 16:16:28 +03:00
|
|
|
|
if (Device.RuntimePlatform == Device.Android)
|
2019-05-31 03:24:30 +03:00
|
|
|
|
{
|
2020-05-29 19:26:36 +03:00
|
|
|
|
var isLocked = await _vaultTimeoutService.IsLockedAsync();
|
2020-03-28 16:16:28 +03:00
|
|
|
|
if (!isLocked)
|
2019-07-22 15:37:06 +03:00
|
|
|
|
{
|
2020-12-14 23:29:30 +03:00
|
|
|
|
await _storageService.SaveAsync(Constants.LastActiveKey, _deviceActionService.GetActiveTime());
|
2019-07-22 15:37:06 +03:00
|
|
|
|
}
|
|
|
|
|
SetTabsPageFromAutofill(isLocked);
|
2019-07-14 03:25:31 +03:00
|
|
|
|
await SleptAsync();
|
2019-05-31 03:24:30 +03:00
|
|
|
|
}
|
2019-03-28 03:12:44 +03:00
|
|
|
|
}
|
|
|
|
|
|
2019-07-07 05:49:17 +03:00
|
|
|
|
protected override void OnResume()
|
2019-03-28 03:12:44 +03:00
|
|
|
|
{
|
2019-05-16 19:30:20 +03:00
|
|
|
|
System.Diagnostics.Debug.WriteLine("XF App: OnResume");
|
2020-03-06 00:18:04 +03:00
|
|
|
|
_isResumed = true;
|
2020-03-28 16:16:28 +03:00
|
|
|
|
if (Device.RuntimePlatform == Device.Android)
|
2019-05-30 21:13:02 +03:00
|
|
|
|
{
|
2019-06-25 00:02:05 +03:00
|
|
|
|
ResumedAsync();
|
2019-05-30 21:13:02 +03:00
|
|
|
|
}
|
2019-06-25 00:02:05 +03:00
|
|
|
|
}
|
|
|
|
|
|
2019-07-14 03:25:31 +03:00
|
|
|
|
private async Task SleptAsync()
|
|
|
|
|
{
|
2020-05-29 19:26:36 +03:00
|
|
|
|
await HandleVaultTimeoutAsync();
|
2019-07-14 03:25:31 +03:00
|
|
|
|
_messagingService.Send("stopEventTimer");
|
|
|
|
|
}
|
|
|
|
|
|
2019-06-25 00:02:05 +03:00
|
|
|
|
private async void ResumedAsync()
|
|
|
|
|
{
|
2020-12-14 23:29:30 +03:00
|
|
|
|
await _vaultTimeoutService.CheckVaultTimeoutAsync();
|
2019-07-13 00:29:40 +03:00
|
|
|
|
_messagingService.Send("startEventTimer");
|
2019-06-25 00:02:05 +03:00
|
|
|
|
await ClearCacheIfNeededAsync();
|
|
|
|
|
Prime();
|
|
|
|
|
SyncIfNeeded();
|
2020-03-28 16:16:28 +03:00
|
|
|
|
if (Current.MainPage is NavigationPage navPage && navPage.CurrentPage is LockPage lockPage)
|
2019-06-06 15:04:54 +03:00
|
|
|
|
{
|
2020-06-08 15:25:13 +03:00
|
|
|
|
await lockPage.PromptBiometricAfterResumeAsync();
|
2019-06-06 15:04:54 +03:00
|
|
|
|
}
|
2019-03-28 03:12:44 +03:00
|
|
|
|
}
|
2019-04-11 22:33:10 +03:00
|
|
|
|
|
|
|
|
|
private void SetCulture()
|
|
|
|
|
{
|
|
|
|
|
// Calendars are removed by linker. ref https://bugzilla.xamarin.com/show_bug.cgi?id=59077
|
|
|
|
|
new System.Globalization.ThaiBuddhistCalendar();
|
|
|
|
|
new System.Globalization.HijriCalendar();
|
|
|
|
|
new System.Globalization.UmAlQuraCalendar();
|
|
|
|
|
}
|
2019-04-19 23:40:20 +03:00
|
|
|
|
|
2019-05-16 00:37:59 +03:00
|
|
|
|
private async Task LogOutAsync(bool expired)
|
|
|
|
|
{
|
|
|
|
|
var userId = await _userService.GetUserIdAsync();
|
|
|
|
|
await Task.WhenAll(
|
|
|
|
|
_syncService.SetLastSyncAsync(DateTime.MinValue),
|
|
|
|
|
_tokenService.ClearTokenAsync(),
|
|
|
|
|
_cryptoService.ClearKeysAsync(),
|
|
|
|
|
_userService.ClearAsync(),
|
|
|
|
|
_settingsService.ClearAsync(userId),
|
|
|
|
|
_cipherService.ClearAsync(userId),
|
|
|
|
|
_folderService.ClearAsync(userId),
|
|
|
|
|
_collectionService.ClearAsync(userId),
|
|
|
|
|
_passwordGenerationService.ClearAsync(),
|
2020-05-29 19:26:36 +03:00
|
|
|
|
_vaultTimeoutService.ClearAsync(),
|
2019-07-02 15:05:34 +03:00
|
|
|
|
_stateService.PurgeAsync());
|
2020-06-08 15:25:13 +03:00
|
|
|
|
_vaultTimeoutService.BiometricLocked = true;
|
2019-05-16 00:37:59 +03:00
|
|
|
|
_searchService.ClearIndex();
|
|
|
|
|
_authService.LogOut(() =>
|
|
|
|
|
{
|
2019-05-31 01:27:57 +03:00
|
|
|
|
Current.MainPage = new HomePage();
|
2020-03-28 16:16:28 +03:00
|
|
|
|
if (expired)
|
2019-10-22 23:30:28 +03:00
|
|
|
|
{
|
|
|
|
|
_platformUtilsService.ShowToast("warning", null, AppResources.LoginExpired);
|
|
|
|
|
}
|
2019-05-16 00:37:59 +03:00
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2019-04-19 23:40:20 +03:00
|
|
|
|
private async Task SetMainPageAsync()
|
|
|
|
|
{
|
|
|
|
|
var authed = await _userService.IsAuthenticatedAsync();
|
2020-03-28 16:16:28 +03:00
|
|
|
|
if (authed)
|
2019-04-19 23:40:20 +03:00
|
|
|
|
{
|
2020-05-29 19:26:36 +03:00
|
|
|
|
if (await _vaultTimeoutService.IsLockedAsync())
|
2019-05-16 00:37:59 +03:00
|
|
|
|
{
|
2020-05-29 19:26:36 +03:00
|
|
|
|
Current.MainPage = new NavigationPage(new LockPage(Options));
|
2019-05-16 00:37:59 +03:00
|
|
|
|
}
|
2020-05-29 19:26:36 +03:00
|
|
|
|
else if (Options.FromAutofillFramework && Options.SaveType.HasValue)
|
2019-05-17 19:03:35 +03:00
|
|
|
|
{
|
2020-05-29 19:26:36 +03:00
|
|
|
|
Current.MainPage = new NavigationPage(new AddEditPage(appOptions: Options));
|
2019-05-17 19:03:35 +03:00
|
|
|
|
}
|
2020-05-29 19:26:36 +03:00
|
|
|
|
else if (Options.Uri != null)
|
2019-05-17 20:14:26 +03:00
|
|
|
|
{
|
2020-05-29 19:26:36 +03:00
|
|
|
|
Current.MainPage = new NavigationPage(new AutofillCiphersPage(Options));
|
2019-05-17 20:14:26 +03:00
|
|
|
|
}
|
2019-05-16 00:37:59 +03:00
|
|
|
|
else
|
|
|
|
|
{
|
2020-05-29 19:26:36 +03:00
|
|
|
|
Current.MainPage = new TabsPage(Options);
|
2019-05-16 00:37:59 +03:00
|
|
|
|
}
|
2019-04-19 23:40:20 +03:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2020-05-29 19:26:36 +03:00
|
|
|
|
Current.MainPage = new HomePage(Options);
|
2019-04-19 23:40:20 +03:00
|
|
|
|
}
|
|
|
|
|
}
|
2019-05-16 19:30:20 +03:00
|
|
|
|
|
2020-05-29 19:26:36 +03:00
|
|
|
|
private async Task HandleVaultTimeoutAsync()
|
2019-05-16 19:30:20 +03:00
|
|
|
|
{
|
2020-05-29 19:26:36 +03:00
|
|
|
|
if (await _vaultTimeoutService.IsLockedAsync())
|
2019-05-16 19:33:48 +03:00
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
var authed = await _userService.IsAuthenticatedAsync();
|
2020-03-28 16:16:28 +03:00
|
|
|
|
if (!authed)
|
2019-05-16 19:33:48 +03:00
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
2020-05-29 19:26:36 +03:00
|
|
|
|
// Will only ever be null - look to remove this in the future
|
|
|
|
|
var vaultTimeout = _platformUtilsService.LockTimeout();
|
|
|
|
|
if (vaultTimeout == null)
|
2019-05-16 19:30:20 +03:00
|
|
|
|
{
|
2020-05-29 19:26:36 +03:00
|
|
|
|
vaultTimeout = await _storageService.GetAsync<int?>(Constants.VaultTimeoutKey);
|
2019-05-16 19:30:20 +03:00
|
|
|
|
}
|
2020-05-29 19:26:36 +03:00
|
|
|
|
vaultTimeout = vaultTimeout.GetValueOrDefault(-1);
|
2020-12-14 23:29:30 +03:00
|
|
|
|
if (vaultTimeout == 0)
|
2019-05-16 19:30:20 +03:00
|
|
|
|
{
|
2020-05-29 19:26:36 +03:00
|
|
|
|
var action = await _storageService.GetAsync<string>(Constants.VaultTimeoutActionKey);
|
|
|
|
|
if (action == "logOut")
|
|
|
|
|
{
|
|
|
|
|
await _vaultTimeoutService.LogOutAsync();
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
await _vaultTimeoutService.LockAsync(true);
|
|
|
|
|
}
|
2019-05-16 19:30:20 +03:00
|
|
|
|
}
|
|
|
|
|
}
|
2019-05-17 19:03:35 +03:00
|
|
|
|
|
|
|
|
|
private async Task ClearCacheIfNeededAsync()
|
|
|
|
|
{
|
|
|
|
|
var lastClear = await _storageService.GetAsync<DateTime?>(Constants.LastFileCacheClearKey);
|
2020-03-28 16:16:28 +03:00
|
|
|
|
if ((DateTime.UtcNow - lastClear.GetValueOrDefault(DateTime.MinValue)).TotalDays >= 1)
|
2019-05-17 19:03:35 +03:00
|
|
|
|
{
|
|
|
|
|
var task = Task.Run(() => _deviceActionService.ClearCacheAsync());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-07-22 15:37:06 +03:00
|
|
|
|
private void SetTabsPageFromAutofill(bool isLocked)
|
2019-05-17 19:03:35 +03:00
|
|
|
|
{
|
2020-05-29 19:26:36 +03:00
|
|
|
|
if (Device.RuntimePlatform == Device.Android && !string.IsNullOrWhiteSpace(Options.Uri) &&
|
|
|
|
|
!Options.FromAutofillFramework)
|
2019-05-17 19:03:35 +03:00
|
|
|
|
{
|
|
|
|
|
Task.Run(() =>
|
|
|
|
|
{
|
|
|
|
|
Device.BeginInvokeOnMainThread(() =>
|
|
|
|
|
{
|
2020-05-29 19:26:36 +03:00
|
|
|
|
Options.Uri = null;
|
2020-03-28 16:16:28 +03:00
|
|
|
|
if (isLocked)
|
2019-07-22 15:37:06 +03:00
|
|
|
|
{
|
|
|
|
|
Current.MainPage = new NavigationPage(new LockPage());
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
Current.MainPage = new TabsPage();
|
|
|
|
|
}
|
2019-05-17 19:03:35 +03:00
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-05-29 00:18:27 +03:00
|
|
|
|
|
|
|
|
|
private void Prime()
|
|
|
|
|
{
|
|
|
|
|
Task.Run(() =>
|
|
|
|
|
{
|
|
|
|
|
var word = EEFLongWordList.Instance.List[1];
|
|
|
|
|
var parsedDomain = DomainName.TryParse("https://bitwarden.com", out var domainName);
|
|
|
|
|
});
|
|
|
|
|
}
|
2019-05-29 22:50:20 +03:00
|
|
|
|
|
|
|
|
|
private void Bootstrap()
|
|
|
|
|
{
|
|
|
|
|
InitializeComponent();
|
|
|
|
|
SetCulture();
|
2020-05-29 19:26:36 +03:00
|
|
|
|
ThemeManager.SetTheme(Device.RuntimePlatform == Device.Android, Current.Resources);
|
2019-05-31 01:27:57 +03:00
|
|
|
|
Current.MainPage = new HomePage();
|
2019-05-29 22:50:20 +03:00
|
|
|
|
var mainPageTask = SetMainPageAsync();
|
|
|
|
|
ServiceContainer.Resolve<MobilePlatformUtilsService>("platformUtilsService").Init();
|
|
|
|
|
}
|
2019-05-30 21:13:02 +03:00
|
|
|
|
|
|
|
|
|
private void SyncIfNeeded()
|
|
|
|
|
{
|
2020-03-28 16:16:28 +03:00
|
|
|
|
if (Xamarin.Essentials.Connectivity.NetworkAccess == Xamarin.Essentials.NetworkAccess.None)
|
2019-06-04 06:12:54 +03:00
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
2019-05-30 21:13:02 +03:00
|
|
|
|
Task.Run(async () =>
|
|
|
|
|
{
|
|
|
|
|
var lastSync = await _syncService.GetLastSyncAsync();
|
2020-03-28 16:16:28 +03:00
|
|
|
|
if (lastSync == null || ((DateTime.UtcNow - lastSync) > TimeSpan.FromMinutes(30)))
|
2019-05-30 21:13:02 +03:00
|
|
|
|
{
|
2019-08-12 16:35:18 +03:00
|
|
|
|
await Task.Delay(1000);
|
2019-05-30 21:13:02 +03:00
|
|
|
|
await _syncService.FullSyncAsync(false);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
2019-07-07 05:49:17 +03:00
|
|
|
|
|
2020-06-08 15:25:13 +03:00
|
|
|
|
private async Task LockedAsync(bool autoPromptBiometric)
|
2019-07-31 23:50:16 +03:00
|
|
|
|
{
|
|
|
|
|
await _stateService.PurgeAsync();
|
2020-06-08 15:25:13 +03:00
|
|
|
|
if (autoPromptBiometric && Device.RuntimePlatform == Device.iOS)
|
2019-07-31 23:50:16 +03:00
|
|
|
|
{
|
2020-05-29 19:26:36 +03:00
|
|
|
|
var vaultTimeout = await _storageService.GetAsync<int?>(Constants.VaultTimeoutKey);
|
|
|
|
|
if (vaultTimeout == 0)
|
2019-07-31 23:50:16 +03:00
|
|
|
|
{
|
2020-06-08 15:25:13 +03:00
|
|
|
|
autoPromptBiometric = false;
|
2019-07-31 23:50:16 +03:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
PreviousPageInfo lastPageBeforeLock = null;
|
2020-03-28 16:16:28 +03:00
|
|
|
|
if (Current.MainPage is TabbedPage tabbedPage && tabbedPage.Navigation.ModalStack.Count > 0)
|
2019-07-31 23:50:16 +03:00
|
|
|
|
{
|
|
|
|
|
var topPage = tabbedPage.Navigation.ModalStack[tabbedPage.Navigation.ModalStack.Count - 1];
|
2020-03-28 16:16:28 +03:00
|
|
|
|
if (topPage is NavigationPage navPage)
|
2019-07-31 23:50:16 +03:00
|
|
|
|
{
|
2020-03-28 16:16:28 +03:00
|
|
|
|
if (navPage.CurrentPage is ViewPage viewPage)
|
2019-07-31 23:50:16 +03:00
|
|
|
|
{
|
|
|
|
|
lastPageBeforeLock = new PreviousPageInfo
|
|
|
|
|
{
|
|
|
|
|
Page = "view",
|
|
|
|
|
CipherId = viewPage.ViewModel.CipherId
|
|
|
|
|
};
|
|
|
|
|
}
|
2020-03-28 16:16:28 +03:00
|
|
|
|
else if (navPage.CurrentPage is AddEditPage addEditPage && addEditPage.ViewModel.EditMode)
|
2019-07-31 23:50:16 +03:00
|
|
|
|
{
|
|
|
|
|
lastPageBeforeLock = new PreviousPageInfo
|
|
|
|
|
{
|
|
|
|
|
Page = "edit",
|
|
|
|
|
CipherId = addEditPage.ViewModel.CipherId
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
await _storageService.SaveAsync(Constants.PreviousPageKey, lastPageBeforeLock);
|
2020-06-08 15:25:13 +03:00
|
|
|
|
var lockPage = new LockPage(Options, autoPromptBiometric);
|
2019-07-31 23:50:16 +03:00
|
|
|
|
Device.BeginInvokeOnMainThread(() => Current.MainPage = new NavigationPage(lockPage));
|
|
|
|
|
}
|
2019-03-28 03:12:44 +03:00
|
|
|
|
}
|
|
|
|
|
}
|