2019-05-15 19:09:49 +02:00
|
|
|
|
using Bit.App.Abstractions;
|
|
|
|
|
using Bit.App.Resources;
|
2019-05-16 20:55:18 +02:00
|
|
|
|
using Bit.Core;
|
2019-05-15 15:14:49 +02:00
|
|
|
|
using Bit.Core.Abstractions;
|
|
|
|
|
using Bit.Core.Utilities;
|
2019-05-14 15:09:35 +02:00
|
|
|
|
using System;
|
2019-03-29 04:52:33 +01:00
|
|
|
|
using System.Collections.Generic;
|
2019-05-16 20:55:18 +02:00
|
|
|
|
using System.Linq;
|
2019-05-15 15:14:49 +02:00
|
|
|
|
using System.Threading.Tasks;
|
2019-04-05 22:13:17 +02:00
|
|
|
|
using Xamarin.Forms;
|
2019-03-29 04:52:33 +01:00
|
|
|
|
|
|
|
|
|
namespace Bit.App.Pages
|
|
|
|
|
{
|
|
|
|
|
public class SettingsPageViewModel : BaseViewModel
|
|
|
|
|
{
|
2019-05-15 15:14:49 +02:00
|
|
|
|
private readonly IPlatformUtilsService _platformUtilsService;
|
2019-05-15 18:54:48 +02:00
|
|
|
|
private readonly ICryptoService _cryptoService;
|
|
|
|
|
private readonly IUserService _userService;
|
2019-05-15 19:09:49 +02:00
|
|
|
|
private readonly IDeviceActionService _deviceActionService;
|
2019-05-15 19:26:55 +02:00
|
|
|
|
private readonly IEnvironmentService _environmentService;
|
|
|
|
|
private readonly IMessagingService _messagingService;
|
2020-05-29 18:26:36 +02:00
|
|
|
|
private readonly IVaultTimeoutService _vaultTimeoutService;
|
2019-05-16 20:55:18 +02:00
|
|
|
|
private readonly IStorageService _storageService;
|
|
|
|
|
private readonly ISyncService _syncService;
|
|
|
|
|
|
2019-05-16 22:31:58 +02:00
|
|
|
|
private bool _supportsFingerprint;
|
2019-05-16 20:55:18 +02:00
|
|
|
|
private bool _pin;
|
|
|
|
|
private bool _fingerprint;
|
|
|
|
|
private string _lastSyncDate;
|
2020-05-29 18:26:36 +02:00
|
|
|
|
private string _vaultTimeoutDisplayValue;
|
|
|
|
|
private string _vaultTimeoutActionDisplayValue;
|
|
|
|
|
private List<KeyValuePair<string, int?>> _vaultTimeouts =
|
2019-05-16 20:55:18 +02:00
|
|
|
|
new List<KeyValuePair<string, int?>>
|
|
|
|
|
{
|
2020-05-29 18:26:36 +02:00
|
|
|
|
new KeyValuePair<string, int?>(AppResources.Immediately, 0),
|
|
|
|
|
new KeyValuePair<string, int?>(AppResources.OneMinute, 1),
|
|
|
|
|
new KeyValuePair<string, int?>(AppResources.FiveMinutes, 5),
|
|
|
|
|
new KeyValuePair<string, int?>(AppResources.FifteenMinutes, 15),
|
|
|
|
|
new KeyValuePair<string, int?>(AppResources.ThirtyMinutes, 30),
|
|
|
|
|
new KeyValuePair<string, int?>(AppResources.OneHour, 60),
|
|
|
|
|
new KeyValuePair<string, int?>(AppResources.FourHours, 240),
|
|
|
|
|
new KeyValuePair<string, int?>(AppResources.OnRestart, -1),
|
2019-05-16 20:55:18 +02:00
|
|
|
|
new KeyValuePair<string, int?>(AppResources.Never, null),
|
|
|
|
|
};
|
2020-05-29 18:26:36 +02:00
|
|
|
|
private List<KeyValuePair<string, string>> _vaultTimeoutActions =
|
|
|
|
|
new List<KeyValuePair<string, string>>
|
|
|
|
|
{
|
|
|
|
|
new KeyValuePair<string, string>(AppResources.Lock, "lock"),
|
|
|
|
|
new KeyValuePair<string, string>(AppResources.LogOut, "logOut"),
|
|
|
|
|
};
|
2019-05-15 15:14:49 +02:00
|
|
|
|
|
2019-03-29 04:52:33 +01:00
|
|
|
|
public SettingsPageViewModel()
|
|
|
|
|
{
|
2019-05-15 15:14:49 +02:00
|
|
|
|
_platformUtilsService = ServiceContainer.Resolve<IPlatformUtilsService>("platformUtilsService");
|
2019-05-15 18:54:48 +02:00
|
|
|
|
_cryptoService = ServiceContainer.Resolve<ICryptoService>("cryptoService");
|
|
|
|
|
_userService = ServiceContainer.Resolve<IUserService>("userService");
|
2019-05-15 19:09:49 +02:00
|
|
|
|
_deviceActionService = ServiceContainer.Resolve<IDeviceActionService>("deviceActionService");
|
2019-05-15 19:26:55 +02:00
|
|
|
|
_environmentService = ServiceContainer.Resolve<IEnvironmentService>("environmentService");
|
|
|
|
|
_messagingService = ServiceContainer.Resolve<IMessagingService>("messagingService");
|
2020-05-29 18:26:36 +02:00
|
|
|
|
_vaultTimeoutService = ServiceContainer.Resolve<IVaultTimeoutService>("vaultTimeoutService");
|
2019-05-16 20:55:18 +02:00
|
|
|
|
_storageService = ServiceContainer.Resolve<IStorageService>("storageService");
|
|
|
|
|
_syncService = ServiceContainer.Resolve<ISyncService>("syncService");
|
2019-04-05 22:13:17 +02:00
|
|
|
|
|
2019-05-16 20:55:18 +02:00
|
|
|
|
GroupedItems = new ExtendedObservableCollection<SettingsPageListGroup>();
|
2019-05-15 15:14:49 +02:00
|
|
|
|
PageTitle = AppResources.Settings;
|
2019-03-29 04:52:33 +01:00
|
|
|
|
}
|
2019-04-05 22:13:17 +02:00
|
|
|
|
|
2019-05-16 20:55:18 +02:00
|
|
|
|
public ExtendedObservableCollection<SettingsPageListGroup> GroupedItems { get; set; }
|
|
|
|
|
|
|
|
|
|
public async Task InitAsync()
|
|
|
|
|
{
|
2019-10-23 15:11:48 +02:00
|
|
|
|
_supportsFingerprint = await _platformUtilsService.SupportsBiometricAsync();
|
2019-05-16 20:55:18 +02:00
|
|
|
|
var lastSync = await _syncService.GetLastSyncAsync();
|
2020-03-28 14:16:28 +01:00
|
|
|
|
if (lastSync != null)
|
2019-05-16 20:55:18 +02:00
|
|
|
|
{
|
2019-06-04 22:36:34 +02:00
|
|
|
|
lastSync = lastSync.Value.ToLocalTime();
|
2019-05-16 20:55:18 +02:00
|
|
|
|
_lastSyncDate = string.Format("{0} {1}", lastSync.Value.ToShortDateString(),
|
|
|
|
|
lastSync.Value.ToShortTimeString());
|
|
|
|
|
}
|
2020-05-29 18:26:36 +02:00
|
|
|
|
var timeout = await _storageService.GetAsync<int?>(Constants.VaultTimeoutKey);
|
|
|
|
|
_vaultTimeoutDisplayValue = _vaultTimeouts.FirstOrDefault(o => o.Value == timeout).Key;
|
|
|
|
|
var action = await _storageService.GetAsync<string>(Constants.VaultTimeoutActionKey) ?? "lock";
|
|
|
|
|
_vaultTimeoutActionDisplayValue = _vaultTimeoutActions.FirstOrDefault(o => o.Value == action).Key;
|
|
|
|
|
var pinSet = await _vaultTimeoutService.IsPinLockSetAsync();
|
2019-05-16 20:55:18 +02:00
|
|
|
|
_pin = pinSet.Item1 || pinSet.Item2;
|
2020-05-29 18:26:36 +02:00
|
|
|
|
_fingerprint = await _vaultTimeoutService.IsFingerprintLockSetAsync();
|
2019-05-16 20:55:18 +02:00
|
|
|
|
BuildList();
|
|
|
|
|
}
|
2019-05-14 17:53:41 +02:00
|
|
|
|
|
2019-05-15 15:14:49 +02:00
|
|
|
|
public async Task AboutAsync()
|
|
|
|
|
{
|
2019-05-31 03:25:54 +02:00
|
|
|
|
var debugText = string.Format("{0}: {1} ({2})", AppResources.Version,
|
|
|
|
|
_platformUtilsService.GetApplicationVersion(), _deviceActionService.GetBuildNumber());
|
2020-02-19 04:39:35 +01:00
|
|
|
|
var text = string.Format("© Bitwarden Inc. 2015-{0}\n\n{1}", DateTime.Now.Year, debugText);
|
2019-05-15 15:14:49 +02:00
|
|
|
|
var copy = await _platformUtilsService.ShowDialogAsync(text, AppResources.Bitwarden, AppResources.Copy,
|
|
|
|
|
AppResources.Close);
|
2020-03-28 14:16:28 +01:00
|
|
|
|
if (copy)
|
2019-05-15 15:14:49 +02:00
|
|
|
|
{
|
|
|
|
|
await _platformUtilsService.CopyToClipboardAsync(debugText);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-05-15 18:54:48 +02:00
|
|
|
|
public void Help()
|
|
|
|
|
{
|
|
|
|
|
_platformUtilsService.LaunchUri("https://help.bitwarden.com/");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public async Task FingerprintAsync()
|
|
|
|
|
{
|
2019-06-05 14:37:07 +02:00
|
|
|
|
List<string> fingerprint;
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
fingerprint = await _cryptoService.GetFingerprintAsync(await _userService.GetUserIdAsync());
|
|
|
|
|
}
|
2020-06-01 20:46:53 +02:00
|
|
|
|
catch (Exception e) when (e.Message == "No public key available.")
|
2019-06-05 14:37:07 +02:00
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
2019-05-15 18:54:48 +02:00
|
|
|
|
var phrase = string.Join("-", fingerprint);
|
2019-05-15 18:55:52 +02:00
|
|
|
|
var text = string.Format("{0}:\n\n{1}", AppResources.YourAccountsFingerprint, phrase);
|
2019-05-15 18:54:48 +02:00
|
|
|
|
var learnMore = await _platformUtilsService.ShowDialogAsync(text, AppResources.FingerprintPhrase,
|
|
|
|
|
AppResources.LearnMore, AppResources.Close);
|
2020-03-28 14:16:28 +01:00
|
|
|
|
if (learnMore)
|
2019-05-15 18:54:48 +02:00
|
|
|
|
{
|
|
|
|
|
_platformUtilsService.LaunchUri("https://help.bitwarden.com/article/fingerprint-phrase/");
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-05-15 19:09:49 +02:00
|
|
|
|
|
|
|
|
|
public void Rate()
|
|
|
|
|
{
|
|
|
|
|
_deviceActionService.RateApp();
|
|
|
|
|
}
|
2019-05-15 18:54:48 +02:00
|
|
|
|
|
2019-05-15 19:26:55 +02:00
|
|
|
|
public void Import()
|
|
|
|
|
{
|
|
|
|
|
_platformUtilsService.LaunchUri("https://help.bitwarden.com/article/import-data/");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void WebVault()
|
|
|
|
|
{
|
|
|
|
|
var url = _environmentService.GetWebVaultUrl();
|
2020-03-28 14:16:28 +01:00
|
|
|
|
if (url == null)
|
2019-05-15 19:26:55 +02:00
|
|
|
|
{
|
|
|
|
|
url = "https://vault.bitwarden.com";
|
|
|
|
|
}
|
|
|
|
|
_platformUtilsService.LaunchUri(url);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public async Task ShareAsync()
|
|
|
|
|
{
|
|
|
|
|
var confirmed = await _platformUtilsService.ShowDialogAsync(AppResources.ShareVaultConfirmation,
|
|
|
|
|
AppResources.ShareVault, AppResources.Yes, AppResources.Cancel);
|
2020-03-28 14:16:28 +01:00
|
|
|
|
if (confirmed)
|
2019-05-15 19:26:55 +02:00
|
|
|
|
{
|
|
|
|
|
_platformUtilsService.LaunchUri("https://help.bitwarden.com/article/what-is-an-organization/");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public async Task TwoStepAsync()
|
|
|
|
|
{
|
|
|
|
|
var confirmed = await _platformUtilsService.ShowDialogAsync(AppResources.TwoStepLoginConfirmation,
|
|
|
|
|
AppResources.TwoStepLogin, AppResources.Yes, AppResources.Cancel);
|
2020-03-28 14:16:28 +01:00
|
|
|
|
if (confirmed)
|
2019-05-15 19:26:55 +02:00
|
|
|
|
{
|
|
|
|
|
_platformUtilsService.LaunchUri("https://help.bitwarden.com/article/setup-two-step-login/");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public async Task ChangePasswordAsync()
|
|
|
|
|
{
|
|
|
|
|
var confirmed = await _platformUtilsService.ShowDialogAsync(AppResources.ChangePasswordConfirmation,
|
|
|
|
|
AppResources.ChangeMasterPassword, AppResources.Yes, AppResources.Cancel);
|
2020-03-28 14:16:28 +01:00
|
|
|
|
if (confirmed)
|
2019-05-15 19:26:55 +02:00
|
|
|
|
{
|
|
|
|
|
_platformUtilsService.LaunchUri("https://help.bitwarden.com/article/change-your-master-password/");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public async Task LogOutAsync()
|
|
|
|
|
{
|
|
|
|
|
var confirmed = await _platformUtilsService.ShowDialogAsync(AppResources.LogoutConfirmation,
|
|
|
|
|
AppResources.LogOut, AppResources.Yes, AppResources.Cancel);
|
2020-03-28 14:16:28 +01:00
|
|
|
|
if (confirmed)
|
2019-05-15 19:26:55 +02:00
|
|
|
|
{
|
|
|
|
|
_messagingService.Send("logout");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-05-15 21:47:50 +02:00
|
|
|
|
public async Task LockAsync()
|
|
|
|
|
{
|
2020-05-29 18:26:36 +02:00
|
|
|
|
await _vaultTimeoutService.LockAsync(true, true);
|
2019-05-15 21:47:50 +02:00
|
|
|
|
}
|
|
|
|
|
|
2020-05-29 18:26:36 +02:00
|
|
|
|
public async Task VaultTimeoutAsync()
|
|
|
|
|
{
|
2020-06-01 20:46:53 +02:00
|
|
|
|
var options = _vaultTimeouts.Select(
|
|
|
|
|
o => o.Key == _vaultTimeoutDisplayValue ? $"✓ {o.Key}" : o.Key).ToArray();
|
|
|
|
|
var selection = await Page.DisplayActionSheet(AppResources.VaultTimeout,
|
|
|
|
|
AppResources.Cancel, null, options);
|
2020-05-29 18:26:36 +02:00
|
|
|
|
if (selection == null || selection == AppResources.Cancel)
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
var cleanSelection = selection.Replace("✓ ", string.Empty);
|
|
|
|
|
var selectionOption = _vaultTimeouts.FirstOrDefault(o => o.Key == cleanSelection);
|
|
|
|
|
_vaultTimeoutDisplayValue = selectionOption.Key;
|
|
|
|
|
await _vaultTimeoutService.SetVaultTimeoutOptionsAsync(selectionOption.Value,
|
|
|
|
|
GetVaultTimeoutActionFromKey(_vaultTimeoutActionDisplayValue));
|
|
|
|
|
BuildList();
|
|
|
|
|
}
|
2020-06-01 20:46:53 +02:00
|
|
|
|
|
2020-05-29 18:26:36 +02:00
|
|
|
|
public async Task VaultTimeoutActionAsync()
|
2019-05-16 20:55:18 +02:00
|
|
|
|
{
|
2020-06-01 20:46:53 +02:00
|
|
|
|
var options = _vaultTimeoutActions.Select(o =>
|
|
|
|
|
o.Key == _vaultTimeoutActionDisplayValue ? $"✓ {o.Key}" : o.Key).ToArray();
|
|
|
|
|
var selection = await Page.DisplayActionSheet(AppResources.VaultTimeoutAction,
|
|
|
|
|
AppResources.Cancel, null, options);
|
2020-03-28 14:16:28 +01:00
|
|
|
|
if (selection == null || selection == AppResources.Cancel)
|
2019-05-16 20:55:18 +02:00
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
var cleanSelection = selection.Replace("✓ ", string.Empty);
|
2020-05-29 18:26:36 +02:00
|
|
|
|
if (cleanSelection == AppResources.LogOut)
|
|
|
|
|
{
|
|
|
|
|
var confirmed = await _platformUtilsService.ShowDialogAsync(AppResources.VaultTimeoutLogOutConfirmation,
|
|
|
|
|
AppResources.Warning, AppResources.Yes, AppResources.Cancel);
|
|
|
|
|
if (!confirmed)
|
|
|
|
|
{
|
|
|
|
|
// Reset to lock and continue process as if lock were selected
|
|
|
|
|
cleanSelection = AppResources.Lock;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
var selectionOption = _vaultTimeoutActions.FirstOrDefault(o => o.Key == cleanSelection);
|
2020-06-01 20:46:53 +02:00
|
|
|
|
if(_vaultTimeoutActionDisplayValue != selectionOption.Key)
|
|
|
|
|
{
|
|
|
|
|
_messagingService.Send("vaultTimeoutActionChanged");
|
|
|
|
|
}
|
2020-05-29 18:26:36 +02:00
|
|
|
|
_vaultTimeoutActionDisplayValue = selectionOption.Key;
|
|
|
|
|
await _vaultTimeoutService.SetVaultTimeoutOptionsAsync(GetVaultTimeoutFromKey(_vaultTimeoutDisplayValue),
|
|
|
|
|
selectionOption.Value);
|
2019-05-16 20:55:18 +02:00
|
|
|
|
BuildList();
|
|
|
|
|
}
|
|
|
|
|
|
2019-05-16 21:54:21 +02:00
|
|
|
|
public async Task UpdatePinAsync()
|
|
|
|
|
{
|
|
|
|
|
_pin = !_pin;
|
2020-03-28 14:16:28 +01:00
|
|
|
|
if (_pin)
|
2019-05-16 21:54:21 +02:00
|
|
|
|
{
|
|
|
|
|
var pin = await _deviceActionService.DisplayPromptAync(AppResources.EnterPIN,
|
|
|
|
|
AppResources.SetPINDescription, null, AppResources.Submit, AppResources.Cancel, true);
|
2020-03-28 14:16:28 +01:00
|
|
|
|
if (!string.IsNullOrWhiteSpace(pin))
|
2019-05-16 21:54:21 +02:00
|
|
|
|
{
|
2019-05-31 21:30:22 +02:00
|
|
|
|
var masterPassOnRestart = await _platformUtilsService.ShowDialogAsync(
|
|
|
|
|
AppResources.PINRequireMasterPasswordRestart, AppResources.UnlockWithPIN,
|
|
|
|
|
AppResources.Yes, AppResources.No);
|
2019-09-20 22:43:03 +02:00
|
|
|
|
|
|
|
|
|
var kdf = await _userService.GetKdfAsync();
|
|
|
|
|
var kdfIterations = await _userService.GetKdfIterationsAsync();
|
|
|
|
|
var email = await _userService.GetEmailAsync();
|
|
|
|
|
var pinKey = await _cryptoService.MakePinKeyAysnc(pin, email,
|
|
|
|
|
kdf.GetValueOrDefault(Core.Enums.KdfType.PBKDF2_SHA256),
|
|
|
|
|
kdfIterations.GetValueOrDefault(5000));
|
|
|
|
|
var key = await _cryptoService.GetKeyAsync();
|
|
|
|
|
var pinProtectedKey = await _cryptoService.EncryptAsync(key.Key, pinKey);
|
|
|
|
|
|
2020-03-28 14:16:28 +01:00
|
|
|
|
if (masterPassOnRestart)
|
2019-05-16 21:54:21 +02:00
|
|
|
|
{
|
|
|
|
|
var encPin = await _cryptoService.EncryptAsync(pin);
|
|
|
|
|
await _storageService.SaveAsync(Constants.ProtectedPin, encPin.EncryptedString);
|
2020-05-29 18:26:36 +02:00
|
|
|
|
_vaultTimeoutService.PinProtectedKey = pinProtectedKey;
|
2019-05-16 21:54:21 +02:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
await _storageService.SaveAsync(Constants.PinProtectedKey, pinProtectedKey.EncryptedString);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
_pin = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-03-28 14:16:28 +01:00
|
|
|
|
if (!_pin)
|
2019-05-16 21:54:21 +02:00
|
|
|
|
{
|
2019-09-20 22:43:03 +02:00
|
|
|
|
await _cryptoService.ClearPinProtectedKeyAsync();
|
2020-05-29 18:26:36 +02:00
|
|
|
|
await _vaultTimeoutService.ClearAsync();
|
2019-05-16 21:54:21 +02:00
|
|
|
|
}
|
2019-05-16 23:30:07 +02:00
|
|
|
|
BuildList();
|
|
|
|
|
}
|
2019-05-16 22:31:58 +02:00
|
|
|
|
|
2019-05-16 23:30:07 +02:00
|
|
|
|
public async Task UpdateFingerprintAsync()
|
|
|
|
|
{
|
2019-05-31 04:50:58 +02:00
|
|
|
|
var current = _fingerprint;
|
2020-03-28 14:16:28 +01:00
|
|
|
|
if (_fingerprint)
|
2019-05-31 04:50:58 +02:00
|
|
|
|
{
|
|
|
|
|
_fingerprint = false;
|
|
|
|
|
}
|
2020-03-28 14:16:28 +01:00
|
|
|
|
else if (await _platformUtilsService.SupportsBiometricAsync())
|
2019-05-31 04:50:58 +02:00
|
|
|
|
{
|
2019-10-23 15:11:48 +02:00
|
|
|
|
_fingerprint = await _platformUtilsService.AuthenticateBiometricAsync(null,
|
2019-06-13 04:21:47 +02:00
|
|
|
|
_deviceActionService.DeviceType == Core.Enums.DeviceType.Android ? "." : null);
|
2019-05-31 04:50:58 +02:00
|
|
|
|
}
|
2020-03-28 14:16:28 +01:00
|
|
|
|
if (_fingerprint == current)
|
2019-05-31 04:50:58 +02:00
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
2020-03-28 14:16:28 +01:00
|
|
|
|
if (_fingerprint)
|
2019-05-16 23:30:07 +02:00
|
|
|
|
{
|
|
|
|
|
await _storageService.SaveAsync(Constants.FingerprintUnlockKey, true);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
await _storageService.RemoveAsync(Constants.FingerprintUnlockKey);
|
|
|
|
|
}
|
2020-05-29 18:26:36 +02:00
|
|
|
|
_vaultTimeoutService.FingerprintLocked = false;
|
2019-05-16 23:30:07 +02:00
|
|
|
|
await _cryptoService.ToggleKeyAsync();
|
2019-05-16 21:54:21 +02:00
|
|
|
|
BuildList();
|
|
|
|
|
}
|
|
|
|
|
|
2019-06-03 18:05:18 +02:00
|
|
|
|
public void BuildList()
|
2019-05-14 17:53:41 +02:00
|
|
|
|
{
|
|
|
|
|
var doUpper = Device.RuntimePlatform != Device.Android;
|
2019-05-31 04:45:48 +02:00
|
|
|
|
var autofillItems = new List<SettingsPageListItem>();
|
2020-03-28 14:16:28 +01:00
|
|
|
|
if (Device.RuntimePlatform == Device.Android)
|
2019-05-31 04:45:48 +02:00
|
|
|
|
{
|
2020-03-28 14:16:28 +01:00
|
|
|
|
if (_deviceActionService.SupportsAutofillService())
|
2019-05-31 04:45:48 +02:00
|
|
|
|
{
|
|
|
|
|
autofillItems.Add(new SettingsPageListItem
|
|
|
|
|
{
|
|
|
|
|
Name = AppResources.AutofillService,
|
2019-06-03 17:26:16 +02:00
|
|
|
|
SubLabel = _deviceActionService.AutofillServiceEnabled() ?
|
|
|
|
|
AppResources.Enabled : AppResources.Disabled
|
2019-05-31 04:45:48 +02:00
|
|
|
|
});
|
|
|
|
|
}
|
2020-01-10 16:20:19 +01:00
|
|
|
|
|
|
|
|
|
var accessibilityEnabled = _deviceActionService.AutofillAccessibilityServiceRunning() &&
|
|
|
|
|
_deviceActionService.AutofillAccessibilityOverlayPermitted();
|
2019-05-31 04:45:48 +02:00
|
|
|
|
autofillItems.Add(new SettingsPageListItem
|
|
|
|
|
{
|
|
|
|
|
Name = AppResources.AutofillAccessibilityService,
|
2020-01-10 16:20:19 +01:00
|
|
|
|
SubLabel = accessibilityEnabled ?
|
2019-06-03 17:26:16 +02:00
|
|
|
|
AppResources.Enabled : AppResources.Disabled
|
2019-05-31 04:45:48 +02:00
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2020-03-28 14:16:28 +01:00
|
|
|
|
if (_deviceActionService.SystemMajorVersion() >= 12)
|
2019-05-31 04:45:48 +02:00
|
|
|
|
{
|
|
|
|
|
autofillItems.Add(new SettingsPageListItem { Name = AppResources.PasswordAutofill });
|
|
|
|
|
}
|
|
|
|
|
autofillItems.Add(new SettingsPageListItem { Name = AppResources.AppExtension });
|
|
|
|
|
}
|
2019-05-14 17:53:41 +02:00
|
|
|
|
var manageItems = new List<SettingsPageListItem>
|
|
|
|
|
{
|
|
|
|
|
new SettingsPageListItem { Name = AppResources.Folders },
|
2019-05-16 20:55:18 +02:00
|
|
|
|
new SettingsPageListItem { Name = AppResources.Sync, SubLabel = _lastSyncDate }
|
2019-05-14 17:53:41 +02:00
|
|
|
|
};
|
|
|
|
|
var securityItems = new List<SettingsPageListItem>
|
|
|
|
|
{
|
2020-05-29 18:26:36 +02:00
|
|
|
|
new SettingsPageListItem { Name = AppResources.VaultTimeout, SubLabel = _vaultTimeoutDisplayValue },
|
2020-06-01 20:46:53 +02:00
|
|
|
|
new SettingsPageListItem
|
|
|
|
|
{
|
|
|
|
|
Name = AppResources.VaultTimeoutAction,
|
|
|
|
|
SubLabel = _vaultTimeoutActionDisplayValue
|
|
|
|
|
},
|
2019-06-03 17:26:16 +02:00
|
|
|
|
new SettingsPageListItem
|
|
|
|
|
{
|
|
|
|
|
Name = AppResources.UnlockWithPIN,
|
|
|
|
|
SubLabel = _pin ? AppResources.Enabled : AppResources.Disabled
|
|
|
|
|
},
|
2019-05-15 19:35:17 +02:00
|
|
|
|
new SettingsPageListItem { Name = AppResources.LockNow },
|
2019-05-14 17:53:41 +02:00
|
|
|
|
new SettingsPageListItem { Name = AppResources.TwoStepLogin }
|
|
|
|
|
};
|
2020-03-28 14:16:28 +01:00
|
|
|
|
if (_supportsFingerprint || _fingerprint)
|
2019-05-16 22:31:58 +02:00
|
|
|
|
{
|
2019-07-08 19:37:45 +02:00
|
|
|
|
var fingerprintName = AppResources.Fingerprint;
|
2020-03-28 14:16:28 +01:00
|
|
|
|
if (Device.RuntimePlatform == Device.iOS)
|
2019-07-08 19:37:45 +02:00
|
|
|
|
{
|
2019-10-23 15:11:48 +02:00
|
|
|
|
fingerprintName = _deviceActionService.SupportsFaceBiometric() ? AppResources.FaceID :
|
|
|
|
|
AppResources.TouchID;
|
2019-07-08 19:37:45 +02:00
|
|
|
|
}
|
2020-03-28 14:16:28 +01:00
|
|
|
|
else if (Device.RuntimePlatform == Device.Android && _deviceActionService.UseNativeBiometric())
|
2019-10-23 15:24:34 +02:00
|
|
|
|
{
|
|
|
|
|
fingerprintName = AppResources.Biometrics;
|
|
|
|
|
}
|
2019-05-16 22:31:58 +02:00
|
|
|
|
var item = new SettingsPageListItem
|
|
|
|
|
{
|
2019-07-08 19:37:45 +02:00
|
|
|
|
Name = string.Format(AppResources.UnlockWith, fingerprintName),
|
2019-06-03 17:26:16 +02:00
|
|
|
|
SubLabel = _fingerprint ? AppResources.Enabled : AppResources.Disabled
|
2019-05-16 22:31:58 +02:00
|
|
|
|
};
|
2020-05-29 18:26:36 +02:00
|
|
|
|
securityItems.Insert(2, item);
|
2019-05-16 22:31:58 +02:00
|
|
|
|
}
|
2019-05-14 17:53:41 +02:00
|
|
|
|
var accountItems = new List<SettingsPageListItem>
|
|
|
|
|
{
|
|
|
|
|
new SettingsPageListItem { Name = AppResources.ChangeMasterPassword },
|
2019-05-15 18:54:48 +02:00
|
|
|
|
new SettingsPageListItem { Name = AppResources.FingerprintPhrase },
|
2019-05-14 17:53:41 +02:00
|
|
|
|
new SettingsPageListItem { Name = AppResources.LogOut }
|
|
|
|
|
};
|
2019-05-15 19:26:55 +02:00
|
|
|
|
var toolsItems = new List<SettingsPageListItem>
|
|
|
|
|
{
|
|
|
|
|
new SettingsPageListItem { Name = AppResources.ImportItems },
|
|
|
|
|
new SettingsPageListItem { Name = AppResources.ExportVault },
|
|
|
|
|
new SettingsPageListItem { Name = AppResources.ShareVault },
|
|
|
|
|
new SettingsPageListItem { Name = AppResources.WebVault }
|
|
|
|
|
};
|
2019-05-14 17:53:41 +02:00
|
|
|
|
var otherItems = new List<SettingsPageListItem>
|
|
|
|
|
{
|
|
|
|
|
new SettingsPageListItem { Name = AppResources.Options },
|
|
|
|
|
new SettingsPageListItem { Name = AppResources.About },
|
|
|
|
|
new SettingsPageListItem { Name = AppResources.HelpAndFeedback },
|
|
|
|
|
new SettingsPageListItem { Name = AppResources.RateTheApp }
|
|
|
|
|
};
|
2019-05-16 20:55:18 +02:00
|
|
|
|
GroupedItems.ResetWithRange(new List<SettingsPageListGroup>
|
2019-05-14 17:53:41 +02:00
|
|
|
|
{
|
2019-05-31 17:52:56 +02:00
|
|
|
|
new SettingsPageListGroup(autofillItems, AppResources.Autofill, doUpper, true),
|
2019-05-14 17:53:41 +02:00
|
|
|
|
new SettingsPageListGroup(manageItems, AppResources.Manage, doUpper),
|
|
|
|
|
new SettingsPageListGroup(securityItems, AppResources.Security, doUpper),
|
|
|
|
|
new SettingsPageListGroup(accountItems, AppResources.Account, doUpper),
|
2019-05-15 19:26:55 +02:00
|
|
|
|
new SettingsPageListGroup(toolsItems, AppResources.Tools, doUpper),
|
2019-05-14 17:53:41 +02:00
|
|
|
|
new SettingsPageListGroup(otherItems, AppResources.Other, doUpper)
|
2019-05-16 20:55:18 +02:00
|
|
|
|
});
|
2019-05-14 17:53:41 +02:00
|
|
|
|
}
|
2020-05-29 18:26:36 +02:00
|
|
|
|
|
|
|
|
|
private string GetVaultTimeoutActionFromKey(string key)
|
|
|
|
|
{
|
|
|
|
|
return _vaultTimeoutActions.FirstOrDefault(o => o.Key == key).Value;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private int? GetVaultTimeoutFromKey(string key)
|
|
|
|
|
{
|
|
|
|
|
return _vaultTimeouts.FirstOrDefault(o => o.Key == key).Value;
|
|
|
|
|
}
|
2019-03-29 04:52:33 +01:00
|
|
|
|
}
|
|
|
|
|
}
|