mirror of
https://github.com/bitwarden/mobile
synced 2025-12-16 08:13:20 +00:00
PM-3349 PM-3350 MAUI Migration Initial
This commit is contained in:
551
src/Core/Pages/Settings/SecuritySettingsPageViewModel.cs
Normal file
551
src/Core/Pages/Settings/SecuritySettingsPageViewModel.cs
Normal file
@@ -0,0 +1,551 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Input;
|
||||
using Bit.App.Abstractions;
|
||||
using Bit.App.Pages.Accounts;
|
||||
using Bit.Core.Resources.Localization;
|
||||
using Bit.App.Utilities;
|
||||
using Bit.Core;
|
||||
using Bit.Core.Abstractions;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Models.Domain;
|
||||
using Bit.Core.Utilities;
|
||||
|
||||
using Microsoft.Maui.ApplicationModel;
|
||||
using Microsoft.Maui.Controls;
|
||||
using Microsoft.Maui;
|
||||
|
||||
namespace Bit.App.Pages
|
||||
{
|
||||
public class SecuritySettingsPageViewModel : BaseViewModel
|
||||
{
|
||||
private const int NEVER_SESSION_TIMEOUT_VALUE = -2;
|
||||
private const int CUSTOM_VAULT_TIMEOUT_VALUE = -100;
|
||||
|
||||
private readonly IStateService _stateService;
|
||||
private readonly IPushNotificationService _pushNotificationService;
|
||||
private readonly IPlatformUtilsService _platformUtilsService;
|
||||
private readonly IDeviceActionService _deviceActionService;
|
||||
private readonly IVaultTimeoutService _vaultTimeoutService;
|
||||
private readonly IBiometricService _biometricsService;
|
||||
private readonly IUserPinService _userPinService;
|
||||
private readonly ICryptoService _cryptoService;
|
||||
private readonly IUserVerificationService _userVerificationService;
|
||||
private readonly IPolicyService _policyService;
|
||||
private readonly IMessagingService _messagingService;
|
||||
private readonly IEnvironmentService _environmentService;
|
||||
private readonly ILogger _logger;
|
||||
|
||||
private bool _inited;
|
||||
private bool _useThisDeviceToApproveLoginRequests;
|
||||
private bool _supportsBiometric, _canUnlockWithBiometrics;
|
||||
private bool _canUnlockWithPin;
|
||||
private bool _hasMasterPassword;
|
||||
private int? _maximumVaultTimeoutPolicy;
|
||||
private string _vaultTimeoutActionPolicy;
|
||||
private TimeSpan? _customVaultTimeoutTime;
|
||||
|
||||
public SecuritySettingsPageViewModel()
|
||||
{
|
||||
_stateService = ServiceContainer.Resolve<IStateService>();
|
||||
_pushNotificationService = ServiceContainer.Resolve<IPushNotificationService>();
|
||||
_platformUtilsService = ServiceContainer.Resolve<IPlatformUtilsService>();
|
||||
_deviceActionService = ServiceContainer.Resolve<IDeviceActionService>();
|
||||
_vaultTimeoutService = ServiceContainer.Resolve<IVaultTimeoutService>();
|
||||
_biometricsService = ServiceContainer.Resolve<IBiometricService>();
|
||||
_userPinService = ServiceContainer.Resolve<IUserPinService>();
|
||||
_cryptoService = ServiceContainer.Resolve<ICryptoService>();
|
||||
_userVerificationService = ServiceContainer.Resolve<IUserVerificationService>();
|
||||
_policyService = ServiceContainer.Resolve<IPolicyService>();
|
||||
_messagingService = ServiceContainer.Resolve<IMessagingService>();
|
||||
_environmentService = ServiceContainer.Resolve<IEnvironmentService>();
|
||||
_logger = ServiceContainer.Resolve<ILogger>();
|
||||
|
||||
VaultTimeoutPickerViewModel = new PickerViewModel<int>(
|
||||
_deviceActionService,
|
||||
_logger,
|
||||
OnVaultTimeoutChangingAsync,
|
||||
AppResources.SessionTimeout,
|
||||
() => _inited,
|
||||
ex => HandleException(ex));
|
||||
VaultTimeoutPickerViewModel.SetAfterSelectionChanged(_ => MainThread.InvokeOnMainThreadAsync(TriggerUpdateCustomVaultTimeoutPicker));
|
||||
|
||||
VaultTimeoutActionPickerViewModel = new PickerViewModel<VaultTimeoutAction>(
|
||||
_deviceActionService,
|
||||
_logger,
|
||||
OnVaultTimeoutActionChangingAsync,
|
||||
AppResources.SessionTimeoutAction,
|
||||
() => _inited && !HasVaultTimeoutActionPolicy,
|
||||
ex => HandleException(ex));
|
||||
|
||||
ToggleUseThisDeviceToApproveLoginRequestsCommand = CreateDefaultAsyncCommnad(ToggleUseThisDeviceToApproveLoginRequestsAsync, () => _inited);
|
||||
GoToPendingLogInRequestsCommand = CreateDefaultAsyncCommnad(() => Page.Navigation.PushModalAsync(new NavigationPage(new LoginPasswordlessRequestsListPage())));
|
||||
ToggleCanUnlockWithBiometricsCommand = CreateDefaultAsyncCommnad(ToggleCanUnlockWithBiometricsAsync, () => _inited);
|
||||
ToggleCanUnlockWithPinCommand = CreateDefaultAsyncCommnad(ToggleCanUnlockWithPinAsync, () => _inited);
|
||||
ShowAccountFingerprintPhraseCommand = CreateDefaultAsyncCommnad(ShowAccountFingerprintPhraseAsync);
|
||||
GoToTwoStepLoginCommand = CreateDefaultAsyncCommnad(() => GoToWebVaultSettingsAsync(AppResources.TwoStepLoginDescriptionLong, AppResources.ContinueToWebApp));
|
||||
GoToChangeMasterPasswordCommand = CreateDefaultAsyncCommnad(() => GoToWebVaultSettingsAsync(AppResources.ChangeMasterPasswordDescriptionLong, AppResources.ContinueToWebApp));
|
||||
LockCommand = CreateDefaultAsyncCommnad(() => _vaultTimeoutService.LockAsync(true, true));
|
||||
LogOutCommand = CreateDefaultAsyncCommnad(LogOutAsync);
|
||||
DeleteAccountCommand = CreateDefaultAsyncCommnad(() => Page.Navigation.PushModalAsync(new NavigationPage(new DeleteAccountPage())));
|
||||
}
|
||||
|
||||
public bool UseThisDeviceToApproveLoginRequests
|
||||
{
|
||||
get => _useThisDeviceToApproveLoginRequests;
|
||||
set
|
||||
{
|
||||
if (SetProperty(ref _useThisDeviceToApproveLoginRequests, value))
|
||||
{
|
||||
((ICommand)ToggleUseThisDeviceToApproveLoginRequestsCommand).Execute(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public string UnlockWithBiometricsTitle
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!_supportsBiometric)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var biometricName = AppResources.Biometrics;
|
||||
// TODO Xamarin.Forms.Device.RuntimePlatform is no longer supported. Use Microsoft.Maui.Devices.DeviceInfo.Platform instead. For more details see https://learn.microsoft.com/en-us/dotnet/maui/migration/forms-projects#device-changes
|
||||
if (Device.RuntimePlatform == Device.iOS)
|
||||
{
|
||||
biometricName = _deviceActionService.SupportsFaceBiometric()
|
||||
? AppResources.FaceID
|
||||
: AppResources.TouchID;
|
||||
}
|
||||
|
||||
return string.Format(AppResources.UnlockWith, biometricName);
|
||||
}
|
||||
}
|
||||
|
||||
public bool CanUnlockWithBiometrics
|
||||
{
|
||||
get => _canUnlockWithBiometrics;
|
||||
set
|
||||
{
|
||||
if (SetProperty(ref _canUnlockWithBiometrics, value))
|
||||
{
|
||||
((ICommand)ToggleCanUnlockWithBiometricsCommand).Execute(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool CanUnlockWithPin
|
||||
{
|
||||
get => _canUnlockWithPin;
|
||||
set
|
||||
{
|
||||
if (SetProperty(ref _canUnlockWithPin, value))
|
||||
{
|
||||
((ICommand)ToggleCanUnlockWithPinCommand).Execute(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public TimeSpan? CustomVaultTimeoutTime
|
||||
{
|
||||
get => _customVaultTimeoutTime;
|
||||
set
|
||||
{
|
||||
var oldValue = _customVaultTimeoutTime;
|
||||
|
||||
if (SetProperty(ref _customVaultTimeoutTime, value, additionalPropertyNames: new string[] { nameof(CustomVaultTimeoutTimeVerbalized) }) && value.HasValue)
|
||||
{
|
||||
UpdateVaultTimeoutAsync((int)value.Value.TotalMinutes)
|
||||
.FireAndForget(ex =>
|
||||
{
|
||||
HandleException(ex);
|
||||
MainThread.BeginInvokeOnMainThread(() => SetProperty(ref _customVaultTimeoutTime, oldValue));
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public string CustomVaultTimeoutTimeVerbalized => CustomVaultTimeoutTime?.Verbalize(A11yExtensions.TimeSpanVerbalizationMode.HoursAndMinutes);
|
||||
|
||||
public bool ShowCustomVaultTimeoutPicker => VaultTimeoutPickerViewModel.SelectedKey == CUSTOM_VAULT_TIMEOUT_VALUE;
|
||||
|
||||
public bool ShowVaultTimeoutPolicyInfo => _maximumVaultTimeoutPolicy.HasValue || HasVaultTimeoutActionPolicy;
|
||||
|
||||
public string VaultTimeoutPolicyDescription
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!ShowVaultTimeoutPolicyInfo)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
static string LocalizeTimeoutAction(string actionPolicy)
|
||||
{
|
||||
return actionPolicy == Policy.ACTION_LOCK ? AppResources.Lock : AppResources.LogOut;
|
||||
};
|
||||
|
||||
if (!_maximumVaultTimeoutPolicy.HasValue)
|
||||
{
|
||||
return string.Format(AppResources.VaultTimeoutActionPolicyInEffect, LocalizeTimeoutAction(_vaultTimeoutActionPolicy));
|
||||
}
|
||||
|
||||
var hours = Math.Floor((float)_maximumVaultTimeoutPolicy / 60);
|
||||
var minutes = _maximumVaultTimeoutPolicy % 60;
|
||||
|
||||
return string.IsNullOrWhiteSpace(_vaultTimeoutActionPolicy)
|
||||
? string.Format(AppResources.VaultTimeoutPolicyInEffect, hours, minutes)
|
||||
: string.Format(AppResources.VaultTimeoutPolicyWithActionInEffect, hours, minutes, LocalizeTimeoutAction(_vaultTimeoutActionPolicy));
|
||||
}
|
||||
}
|
||||
|
||||
public bool ShowChangeMasterPassword { get; private set; }
|
||||
|
||||
private bool IsVaultTimeoutActionLockAllowed => _hasMasterPassword || _canUnlockWithBiometrics || _canUnlockWithPin;
|
||||
|
||||
private int? CurrentVaultTimeout => GetRawVaultTimeoutFrom(VaultTimeoutPickerViewModel.SelectedKey);
|
||||
|
||||
private bool IncludeLinksWithSubscriptionInfo => // TODO Xamarin.Forms.Device.RuntimePlatform is no longer supported. Use Microsoft.Maui.Devices.DeviceInfo.Platform instead. For more details see https://learn.microsoft.com/en-us/dotnet/maui/migration/forms-projects#device-changes
|
||||
Device.RuntimePlatform != Device.iOS;
|
||||
|
||||
private bool HasVaultTimeoutActionPolicy => !string.IsNullOrEmpty(_vaultTimeoutActionPolicy);
|
||||
|
||||
public PickerViewModel<int> VaultTimeoutPickerViewModel { get; }
|
||||
public PickerViewModel<VaultTimeoutAction> VaultTimeoutActionPickerViewModel { get; }
|
||||
|
||||
public AsyncCommand ToggleUseThisDeviceToApproveLoginRequestsCommand { get; }
|
||||
public ICommand GoToPendingLogInRequestsCommand { get; }
|
||||
public AsyncCommand ToggleCanUnlockWithBiometricsCommand { get; }
|
||||
public AsyncCommand ToggleCanUnlockWithPinCommand { get; }
|
||||
public ICommand ShowAccountFingerprintPhraseCommand { get; }
|
||||
public ICommand GoToTwoStepLoginCommand { get; }
|
||||
public ICommand GoToChangeMasterPasswordCommand { get; }
|
||||
public ICommand LockCommand { get; }
|
||||
public ICommand LogOutCommand { get; }
|
||||
public ICommand DeleteAccountCommand { get; }
|
||||
|
||||
public async Task InitAsync()
|
||||
{
|
||||
var decryptionOptions = await _stateService.GetAccountDecryptionOptions();
|
||||
// set default true for backwards compatibility
|
||||
_hasMasterPassword = decryptionOptions?.HasMasterPassword ?? true;
|
||||
_useThisDeviceToApproveLoginRequests = await _stateService.GetApprovePasswordlessLoginsAsync();
|
||||
_supportsBiometric = await _platformUtilsService.SupportsBiometricAsync();
|
||||
_canUnlockWithBiometrics = await _vaultTimeoutService.IsBiometricLockSetAsync();
|
||||
_canUnlockWithPin = await _vaultTimeoutService.GetPinLockTypeAsync() != Core.Services.PinLockType.Disabled;
|
||||
|
||||
await LoadPoliciesAsync();
|
||||
await InitVaultTimeoutPickerAsync();
|
||||
await InitVaultTimeoutActionPickerAsync();
|
||||
|
||||
ShowChangeMasterPassword = IncludeLinksWithSubscriptionInfo && await _userVerificationService.HasMasterPasswordAsync();
|
||||
|
||||
_inited = true;
|
||||
|
||||
MainThread.BeginInvokeOnMainThread(() =>
|
||||
{
|
||||
TriggerPropertyChanged(nameof(UseThisDeviceToApproveLoginRequests));
|
||||
TriggerPropertyChanged(nameof(UnlockWithBiometricsTitle));
|
||||
TriggerPropertyChanged(nameof(CanUnlockWithBiometrics));
|
||||
TriggerPropertyChanged(nameof(CanUnlockWithPin));
|
||||
TriggerPropertyChanged(nameof(ShowVaultTimeoutPolicyInfo));
|
||||
TriggerPropertyChanged(nameof(VaultTimeoutPolicyDescription));
|
||||
TriggerPropertyChanged(nameof(ShowChangeMasterPassword));
|
||||
TriggerUpdateCustomVaultTimeoutPicker();
|
||||
ToggleUseThisDeviceToApproveLoginRequestsCommand.RaiseCanExecuteChanged();
|
||||
ToggleCanUnlockWithBiometricsCommand.RaiseCanExecuteChanged();
|
||||
ToggleCanUnlockWithPinCommand.RaiseCanExecuteChanged();
|
||||
VaultTimeoutPickerViewModel.SelectOptionCommand.RaiseCanExecuteChanged();
|
||||
VaultTimeoutActionPickerViewModel.SelectOptionCommand.RaiseCanExecuteChanged();
|
||||
});
|
||||
}
|
||||
|
||||
private async Task LoadPoliciesAsync()
|
||||
{
|
||||
if (!await _policyService.PolicyAppliesToUser(PolicyType.MaximumVaultTimeout))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var maximumVaultTimeoutPolicy = await _policyService.FirstOrDefault(PolicyType.MaximumVaultTimeout);
|
||||
_maximumVaultTimeoutPolicy = maximumVaultTimeoutPolicy?.GetInt(Policy.MINUTES_KEY);
|
||||
_vaultTimeoutActionPolicy = maximumVaultTimeoutPolicy?.GetString(Policy.ACTION_KEY);
|
||||
|
||||
MainThread.BeginInvokeOnMainThread(VaultTimeoutActionPickerViewModel.SelectOptionCommand.RaiseCanExecuteChanged);
|
||||
}
|
||||
|
||||
private async Task InitVaultTimeoutPickerAsync()
|
||||
{
|
||||
var options = new Dictionary<int, string>
|
||||
{
|
||||
[0] = AppResources.Immediately,
|
||||
[1] = AppResources.OneMinute,
|
||||
[5] = AppResources.FiveMinutes,
|
||||
[15] = AppResources.FifteenMinutes,
|
||||
[30] = AppResources.ThirtyMinutes,
|
||||
[60] = AppResources.OneHour,
|
||||
[240] = AppResources.FourHours,
|
||||
[-1] = AppResources.OnRestart,
|
||||
[NEVER_SESSION_TIMEOUT_VALUE] = AppResources.Never
|
||||
};
|
||||
|
||||
if (_maximumVaultTimeoutPolicy.HasValue)
|
||||
{
|
||||
options = options.Where(t => t.Key >= 0 && t.Key <= _maximumVaultTimeoutPolicy.Value)
|
||||
.ToDictionary(v => v.Key, v => v.Value);
|
||||
}
|
||||
|
||||
options.Add(CUSTOM_VAULT_TIMEOUT_VALUE, AppResources.Custom);
|
||||
|
||||
var vaultTimeout = await _vaultTimeoutService.GetVaultTimeout() ?? NEVER_SESSION_TIMEOUT_VALUE;
|
||||
VaultTimeoutPickerViewModel.Init(options, vaultTimeout, CUSTOM_VAULT_TIMEOUT_VALUE, false);
|
||||
|
||||
if (VaultTimeoutPickerViewModel.SelectedKey == CUSTOM_VAULT_TIMEOUT_VALUE)
|
||||
{
|
||||
_customVaultTimeoutTime = TimeSpan.FromMinutes(vaultTimeout);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task InitVaultTimeoutActionPickerAsync()
|
||||
{
|
||||
var options = new Dictionary<VaultTimeoutAction, string>();
|
||||
if (IsVaultTimeoutActionLockAllowed)
|
||||
{
|
||||
options.Add(VaultTimeoutAction.Lock, AppResources.Lock);
|
||||
}
|
||||
options.Add(VaultTimeoutAction.Logout, AppResources.LogOut);
|
||||
|
||||
var timeoutAction = await _vaultTimeoutService.GetVaultTimeoutAction() ?? VaultTimeoutAction.Lock;
|
||||
if (!IsVaultTimeoutActionLockAllowed && timeoutAction == VaultTimeoutAction.Lock)
|
||||
{
|
||||
timeoutAction = VaultTimeoutAction.Logout;
|
||||
await _vaultTimeoutService.SetVaultTimeoutOptionsAsync(CurrentVaultTimeout, VaultTimeoutAction.Logout);
|
||||
}
|
||||
|
||||
VaultTimeoutActionPickerViewModel.Init(options, timeoutAction, IsVaultTimeoutActionLockAllowed ? VaultTimeoutAction.Lock : VaultTimeoutAction.Logout);
|
||||
}
|
||||
|
||||
private async Task ToggleUseThisDeviceToApproveLoginRequestsAsync()
|
||||
{
|
||||
if (UseThisDeviceToApproveLoginRequests
|
||||
&&
|
||||
!await Page.DisplayAlert(AppResources.ApproveLoginRequests, AppResources.UseThisDeviceToApproveLoginRequestsMadeFromOtherDevices, AppResources.Yes, AppResources.No))
|
||||
{
|
||||
_useThisDeviceToApproveLoginRequests = !UseThisDeviceToApproveLoginRequests;
|
||||
MainThread.BeginInvokeOnMainThread(() => TriggerPropertyChanged(nameof(UseThisDeviceToApproveLoginRequests)));
|
||||
return;
|
||||
}
|
||||
|
||||
await _stateService.SetApprovePasswordlessLoginsAsync(UseThisDeviceToApproveLoginRequests);
|
||||
|
||||
if (!UseThisDeviceToApproveLoginRequests || await _pushNotificationService.AreNotificationsSettingsEnabledAsync())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var openAppSettingsResult = await _platformUtilsService.ShowDialogAsync(
|
||||
AppResources.ReceivePushNotificationsForNewLoginRequests,
|
||||
string.Empty,
|
||||
AppResources.Settings,
|
||||
AppResources.NoThanks
|
||||
);
|
||||
if (openAppSettingsResult)
|
||||
{
|
||||
_deviceActionService.OpenAppSettings();
|
||||
}
|
||||
}
|
||||
|
||||
private async Task ToggleCanUnlockWithBiometricsAsync()
|
||||
{
|
||||
if (!_canUnlockWithBiometrics)
|
||||
{
|
||||
await UpdateVaultTimeoutActionIfNeededAsync();
|
||||
await _biometricsService.SetCanUnlockWithBiometricsAsync(CanUnlockWithBiometrics);
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO Xamarin.Forms.Device.RuntimePlatform is no longer supported. Use Microsoft.Maui.Devices.DeviceInfo.Platform instead. For more details see https://learn.microsoft.com/en-us/dotnet/maui/migration/forms-projects#device-changes
|
||||
if (!_supportsBiometric
|
||||
||
|
||||
!await _platformUtilsService.AuthenticateBiometricAsync(null, Device.RuntimePlatform == Device.Android ? "." : null))
|
||||
{
|
||||
_canUnlockWithBiometrics = false;
|
||||
MainThread.BeginInvokeOnMainThread(() => TriggerPropertyChanged(nameof(CanUnlockWithBiometrics)));
|
||||
return;
|
||||
}
|
||||
|
||||
await _biometricsService.SetCanUnlockWithBiometricsAsync(CanUnlockWithBiometrics);
|
||||
}
|
||||
|
||||
public async Task ToggleCanUnlockWithPinAsync()
|
||||
{
|
||||
if (!CanUnlockWithPin)
|
||||
{
|
||||
await _vaultTimeoutService.ClearAsync();
|
||||
await UpdateVaultTimeoutActionIfNeededAsync();
|
||||
return;
|
||||
}
|
||||
|
||||
var newPin = await _deviceActionService.DisplayPromptAync(AppResources.EnterPIN,
|
||||
AppResources.SetPINDescription, null, AppResources.Submit, AppResources.Cancel, true);
|
||||
if (string.IsNullOrWhiteSpace(newPin))
|
||||
{
|
||||
_canUnlockWithPin = false;
|
||||
MainThread.BeginInvokeOnMainThread(() => TriggerPropertyChanged(nameof(CanUnlockWithPin)));
|
||||
return;
|
||||
}
|
||||
|
||||
var requireMasterPasswordOnRestart = await _userVerificationService.HasMasterPasswordAsync()
|
||||
&&
|
||||
await _platformUtilsService.ShowDialogAsync(AppResources.PINRequireMasterPasswordRestart,
|
||||
AppResources.UnlockWithPIN,
|
||||
AppResources.Yes,
|
||||
AppResources.No);
|
||||
|
||||
await _userPinService.SetupPinAsync(newPin, requireMasterPasswordOnRestart);
|
||||
}
|
||||
|
||||
private async Task UpdateVaultTimeoutActionIfNeededAsync()
|
||||
{
|
||||
if (IsVaultTimeoutActionLockAllowed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
VaultTimeoutActionPickerViewModel.Select(VaultTimeoutAction.Logout);
|
||||
await _vaultTimeoutService.SetVaultTimeoutOptionsAsync(CurrentVaultTimeout, VaultTimeoutAction.Logout);
|
||||
_deviceActionService.Toast(AppResources.VaultTimeoutActionChangedToLogOut);
|
||||
}
|
||||
|
||||
private async Task<bool> OnVaultTimeoutChangingAsync(int newTimeout)
|
||||
{
|
||||
if (newTimeout == NEVER_SESSION_TIMEOUT_VALUE
|
||||
&&
|
||||
!await _platformUtilsService.ShowDialogAsync(AppResources.NeverLockWarning, AppResources.Warning, AppResources.Yes, AppResources.Cancel))
|
||||
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (newTimeout == CUSTOM_VAULT_TIMEOUT_VALUE)
|
||||
{
|
||||
_customVaultTimeoutTime = TimeSpan.FromMinutes(0);
|
||||
}
|
||||
|
||||
return await UpdateVaultTimeoutAsync(newTimeout);
|
||||
}
|
||||
|
||||
private async Task<bool> UpdateVaultTimeoutAsync(int newTimeout)
|
||||
{
|
||||
var rawTimeout = GetRawVaultTimeoutFrom(newTimeout);
|
||||
|
||||
if (rawTimeout > _maximumVaultTimeoutPolicy)
|
||||
{
|
||||
await _platformUtilsService.ShowDialogAsync(AppResources.VaultTimeoutToLarge, AppResources.Warning);
|
||||
VaultTimeoutPickerViewModel.Select(_maximumVaultTimeoutPolicy.Value, false);
|
||||
|
||||
if (VaultTimeoutPickerViewModel.SelectedKey == CUSTOM_VAULT_TIMEOUT_VALUE)
|
||||
{
|
||||
_customVaultTimeoutTime = TimeSpan.FromMinutes(_maximumVaultTimeoutPolicy.Value);
|
||||
}
|
||||
|
||||
MainThread.BeginInvokeOnMainThread(TriggerUpdateCustomVaultTimeoutPicker);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
await _vaultTimeoutService.SetVaultTimeoutOptionsAsync(rawTimeout, VaultTimeoutActionPickerViewModel.SelectedKey);
|
||||
|
||||
await _cryptoService.RefreshKeysAsync();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void TriggerUpdateCustomVaultTimeoutPicker()
|
||||
{
|
||||
TriggerPropertyChanged(nameof(ShowCustomVaultTimeoutPicker));
|
||||
TriggerPropertyChanged(nameof(CustomVaultTimeoutTime));
|
||||
}
|
||||
|
||||
private int? GetRawVaultTimeoutFrom(int vaultTimeoutPickerKey)
|
||||
{
|
||||
if (vaultTimeoutPickerKey == NEVER_SESSION_TIMEOUT_VALUE)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (vaultTimeoutPickerKey == CUSTOM_VAULT_TIMEOUT_VALUE
|
||||
&&
|
||||
CustomVaultTimeoutTime.HasValue)
|
||||
{
|
||||
return (int)CustomVaultTimeoutTime.Value.TotalMinutes;
|
||||
}
|
||||
|
||||
return vaultTimeoutPickerKey;
|
||||
}
|
||||
|
||||
private async Task<bool> OnVaultTimeoutActionChangingAsync(VaultTimeoutAction timeoutActionKey)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(_vaultTimeoutActionPolicy))
|
||||
{
|
||||
// do nothing if we have a policy set
|
||||
return false;
|
||||
}
|
||||
|
||||
if (timeoutActionKey == VaultTimeoutAction.Logout
|
||||
&&
|
||||
!await _platformUtilsService.ShowDialogAsync(AppResources.VaultTimeoutLogOutConfirmation, AppResources.Warning, AppResources.Yes, AppResources.Cancel))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
await _vaultTimeoutService.SetVaultTimeoutOptionsAsync(CurrentVaultTimeout, timeoutActionKey);
|
||||
_messagingService.Send(AppHelpers.VAULT_TIMEOUT_ACTION_CHANGED_MESSAGE_COMMAND);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private async Task ShowAccountFingerprintPhraseAsync()
|
||||
{
|
||||
List<string> fingerprint;
|
||||
try
|
||||
{
|
||||
fingerprint = await _cryptoService.GetFingerprintAsync(await _stateService.GetActiveUserIdAsync());
|
||||
}
|
||||
catch (Exception e) when (e.Message == "No public key available.")
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var phrase = string.Join("-", fingerprint);
|
||||
var text = $"{AppResources.YourAccountsFingerprint}:\n\n{phrase}";
|
||||
|
||||
var learnMore = await _platformUtilsService.ShowDialogAsync(text, AppResources.FingerprintPhrase,
|
||||
AppResources.LearnMore, AppResources.Close);
|
||||
if (learnMore)
|
||||
{
|
||||
_platformUtilsService.LaunchUri(ExternalLinksConstants.HELP_FINGERPRINT_PHRASE);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task GoToWebVaultSettingsAsync(string dialogText, string dialogTitle)
|
||||
{
|
||||
if (await _platformUtilsService.ShowDialogAsync(dialogText, dialogTitle, AppResources.Continue, AppResources.Cancel))
|
||||
{
|
||||
_platformUtilsService.LaunchUri(string.Format(ExternalLinksConstants.WEB_VAULT_SETTINGS_FORMAT, _environmentService.GetWebVaultUrl()));
|
||||
}
|
||||
}
|
||||
|
||||
public async Task LogOutAsync()
|
||||
{
|
||||
if (await _platformUtilsService.ShowDialogAsync(AppResources.LogoutConfirmation, AppResources.LogOut, AppResources.Yes, AppResources.Cancel))
|
||||
{
|
||||
_messagingService.Send(AccountsManagerMessageCommands.LOGOUT);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user