1
0
mirror of https://github.com/bitwarden/mobile synced 2025-12-05 23:53:33 +00:00

[PM-3102] Update Master password reprompt to be based on MP instead of Key Connector (#2653)

* PM-3102 Added check to see if a user has master password set replacing previous usage of key connector.

* PM-3102 Fix formatting
This commit is contained in:
Federico Maccaroni
2023-08-10 13:23:04 -03:00
committed by GitHub
parent af016cd13c
commit 9001fa1ccf
18 changed files with 83 additions and 91 deletions

View File

@@ -70,7 +70,8 @@ namespace Bit.Droid
var verificationActionsFlowHelper = new VerificationActionsFlowHelper(
ServiceContainer.Resolve<IKeyConnectorService>("keyConnectorService"),
ServiceContainer.Resolve<IPasswordRepromptService>("passwordRepromptService"),
ServiceContainer.Resolve<ICryptoService>("cryptoService"));
ServiceContainer.Resolve<ICryptoService>("cryptoService"),
ServiceContainer.Resolve<IUserVerificationService>());
ServiceContainer.Register<IVerificationActionsFlowHelper>("verificationActionsFlowHelper", verificationActionsFlowHelper);
var accountsManager = new AccountsManager(

View File

@@ -9,7 +9,5 @@ namespace Bit.App.Abstractions
Task<bool> ShowPasswordPromptAsync();
Task<(string password, bool valid)> ShowPasswordPromptAndGetItAsync();
Task<bool> Enabled();
}
}

View File

@@ -98,7 +98,7 @@ namespace Bit.App.Pages
}
else
{
if (_vm.UsingKeyConnector && !_vm.PinEnabled)
if (!_vm.HasMasterPassword && !_vm.PinEnabled)
{
_passwordGrid.IsVisible = false;
_unlockButton.IsVisible = false;

View File

@@ -27,7 +27,7 @@ namespace Bit.App.Pages
private readonly IEnvironmentService _environmentService;
private readonly IStateService _stateService;
private readonly IBiometricService _biometricService;
private readonly IKeyConnectorService _keyConnectorService;
private readonly IUserVerificationService _userVerificationService;
private readonly ILogger _logger;
private readonly IWatchDeviceService _watchDeviceService;
private readonly WeakEventManager<int?> _secretEntryFocusWeakEventManager = new WeakEventManager<int?>();
@@ -44,7 +44,7 @@ namespace Bit.App.Pages
private bool _biometricEnabled;
private bool _biometricIntegrityValid = true;
private bool _biometricButtonVisible;
private bool _usingKeyConnector;
private bool _hasMasterPassword;
private string _biometricButtonText;
private string _loggedInAsText;
private string _lockedVerifyText;
@@ -60,7 +60,7 @@ namespace Bit.App.Pages
_environmentService = ServiceContainer.Resolve<IEnvironmentService>("environmentService");
_stateService = ServiceContainer.Resolve<IStateService>("stateService");
_biometricService = ServiceContainer.Resolve<IBiometricService>("biometricService");
_keyConnectorService = ServiceContainer.Resolve<IKeyConnectorService>("keyConnectorService");
_userVerificationService = ServiceContainer.Resolve<IUserVerificationService>();
_logger = ServiceContainer.Resolve<ILogger>("logger");
_watchDeviceService = ServiceContainer.Resolve<IWatchDeviceService>();
_policyService = ServiceContainer.Resolve<IPolicyService>();
@@ -108,9 +108,9 @@ namespace Bit.App.Pages
set => SetProperty(ref _pinEnabled, value);
}
public bool UsingKeyConnector
public bool HasMasterPassword
{
get => _usingKeyConnector;
get => _hasMasterPassword;
}
public bool BiometricEnabled
@@ -182,10 +182,10 @@ namespace Bit.App.Pages
BiometricEnabled = await _vaultTimeoutService.IsBiometricLockSetAsync() && await _cryptoService.HasEncryptedUserKeyAsync();
var decryptOptions = await _stateService.GetAccountDecryptionOptions();
// Users without MP and without biometric or pin has no MP to unlock with
_hasMasterPassword = await _userVerificationService.HasMasterPasswordAsync();
if (await _stateService.IsAuthenticatedAsync()
&& decryptOptions?.TrustedDeviceOption != null
&& !decryptOptions.HasMasterPassword
&& !_hasMasterPassword
&& !BiometricEnabled
&& !PinEnabled)
{
@@ -193,13 +193,6 @@ namespace Bit.App.Pages
return;
}
// Users with key connector and without biometric or pin has no MP to unlock with
_usingKeyConnector = await _keyConnectorService.GetUsesKeyConnector();
if (_usingKeyConnector && !(BiometricEnabled || PinEnabled))
{
await _vaultTimeoutService.LogOutAsync();
return;
}
_email = await _stateService.GetEmailAsync();
if (string.IsNullOrWhiteSpace(_email))
{
@@ -221,16 +214,8 @@ namespace Bit.App.Pages
}
else
{
if (_usingKeyConnector)
{
PageTitle = AppResources.UnlockVault;
LockedVerifyText = AppResources.VaultLockedIdentity;
}
else
{
PageTitle = AppResources.VerifyMasterPassword;
LockedVerifyText = AppResources.VaultLockedMasterPassword;
}
PageTitle = _hasMasterPassword ? AppResources.VerifyMasterPassword : AppResources.UnlockVault;
LockedVerifyText = _hasMasterPassword ? AppResources.VaultLockedMasterPassword : AppResources.VaultLockedIdentity;
}
if (BiometricEnabled)

View File

@@ -21,7 +21,6 @@ namespace Bit.App.Pages
private readonly II18nService _i18nService;
private readonly IExportService _exportService;
private readonly IPolicyService _policyService;
private readonly IKeyConnectorService _keyConnectorService;
private readonly IUserVerificationService _userVerificationService;
private readonly IApiService _apiService;
private readonly ILogger _logger;
@@ -45,8 +44,7 @@ namespace Bit.App.Pages
_i18nService = ServiceContainer.Resolve<II18nService>("i18nService");
_exportService = ServiceContainer.Resolve<IExportService>("exportService");
_policyService = ServiceContainer.Resolve<IPolicyService>("policyService");
_keyConnectorService = ServiceContainer.Resolve<IKeyConnectorService>("keyConnectorService");
_userVerificationService = ServiceContainer.Resolve<IUserVerificationService>("userVerificationService");
_userVerificationService = ServiceContainer.Resolve<IUserVerificationService>();
_apiService = ServiceContainer.Resolve<IApiService>("apiService");
_logger = ServiceContainer.Resolve<ILogger>("logger");
@@ -67,7 +65,7 @@ namespace Bit.App.Pages
_initialized = true;
FileFormatSelectedIndex = FileFormatOptions.FindIndex(k => k.Key == "json");
DisablePrivateVaultPolicyEnabled = await _policyService.PolicyAppliesToUser(PolicyType.DisablePersonalVaultExport);
UseOTPVerification = await _keyConnectorService.GetUsesKeyConnector();
UseOTPVerification = !await _userVerificationService.HasMasterPasswordAsync();
if (UseOTPVerification)
{
@@ -165,9 +163,9 @@ namespace Bit.App.Pages
return;
}
var verificationType = await _keyConnectorService.GetUsesKeyConnector()
? VerificationType.OTP
: VerificationType.MasterPassword;
var verificationType = await _userVerificationService.HasMasterPasswordAsync()
? VerificationType.MasterPassword
: VerificationType.OTP;
if (!await _userVerificationService.VerifyUser(Secret, verificationType))
{
return;

View File

@@ -29,7 +29,7 @@ namespace Bit.App.Pages
private readonly IBiometricService _biometricService;
private readonly IPolicyService _policyService;
private readonly ILocalizeService _localizeService;
private readonly IKeyConnectorService _keyConnectorService;
private readonly IUserVerificationService _userVerificationService;
private readonly IClipboardService _clipboardService;
private readonly ILogger _loggerService;
private readonly IPushNotificationService _pushNotificationService;
@@ -89,7 +89,7 @@ namespace Bit.App.Pages
_biometricService = ServiceContainer.Resolve<IBiometricService>("biometricService");
_policyService = ServiceContainer.Resolve<IPolicyService>("policyService");
_localizeService = ServiceContainer.Resolve<ILocalizeService>("localizeService");
_keyConnectorService = ServiceContainer.Resolve<IKeyConnectorService>("keyConnectorService");
_userVerificationService = ServiceContainer.Resolve<IUserVerificationService>();
_clipboardService = ServiceContainer.Resolve<IClipboardService>("clipboardService");
_loggerService = ServiceContainer.Resolve<ILogger>("logger");
_pushNotificationService = ServiceContainer.Resolve<IPushNotificationService>();
@@ -159,8 +159,7 @@ namespace Bit.App.Pages
_vaultTimeoutDisplayValue = AppResources.Custom;
}
_showChangeMasterPassword = IncludeLinksWithSubscriptionInfo() &&
!await _keyConnectorService.GetUsesKeyConnector();
_showChangeMasterPassword = IncludeLinksWithSubscriptionInfo() && await _userVerificationService.HasMasterPasswordAsync();
_reportLoggingEnabled = await _loggerService.IsEnabled();
_approvePasswordlessLoginRequests = await _stateService.GetApprovePasswordlessLoginsAsync();
_shouldConnectToWatch = await _stateService.GetShouldConnectToWatchAsync();
@@ -443,7 +442,7 @@ namespace Bit.App.Pages
if (!string.IsNullOrWhiteSpace(pin))
{
var masterPassOnRestart = false;
if (!await _keyConnectorService.GetUsesKeyConnector())
if (await _userVerificationService.HasMasterPasswordAsync())
{
masterPassOnRestart = await _platformUtilsService.ShowDialogAsync(
AppResources.PINRequireMasterPasswordRestart, AppResources.UnlockWithPIN,

View File

@@ -21,7 +21,7 @@ namespace Bit.App.Pages
private readonly IDeviceActionService _deviceActionService;
private readonly IAutofillHandler _autofillHandler;
private readonly IVaultTimeoutService _vaultTimeoutService;
private readonly IKeyConnectorService _keyConnectorService;
private readonly IUserVerificationService _userVerificationService;
private CipherAddEditPageViewModel _vm;
private bool _fromAutofill;
@@ -43,7 +43,7 @@ namespace Bit.App.Pages
_deviceActionService = ServiceContainer.Resolve<IDeviceActionService>("deviceActionService");
_autofillHandler = ServiceContainer.Resolve<IAutofillHandler>();
_vaultTimeoutService = ServiceContainer.Resolve<IVaultTimeoutService>("vaultTimeoutService");
_keyConnectorService = ServiceContainer.Resolve<IKeyConnectorService>("keyConnectorService");
_userVerificationService = ServiceContainer.Resolve<IUserVerificationService>();
_appOptions = appOptions;
_fromAutofill = fromAutofill;
@@ -175,8 +175,8 @@ namespace Bit.App.Pages
RequestFocus(_nameEntry);
}
});
// Hide password reprompt option if using key connector
_passwordPrompt.IsVisible = !await _keyConnectorService.GetUsesKeyConnector();
_passwordPrompt.IsVisible = await _userVerificationService.HasMasterPasswordAsync();
}
protected override void OnDisappearing()

View File

@@ -1,9 +1,7 @@
using System;
using System.Threading.Tasks;
using System.Threading.Tasks;
using Bit.App.Abstractions;
using Bit.App.Resources;
using Bit.Core.Abstractions;
using Bit.Core.Utilities;
namespace Bit.App.Services
{
@@ -40,11 +38,5 @@ namespace Bit.App.Services
return await _cryptoService.CompareAndUpdateKeyHashAsync(password, null);
}
public async Task<bool> Enabled()
{
var keyConnectorService = ServiceContainer.Resolve<IKeyConnectorService>("keyConnectorService");
return !await keyConnectorService.GetUsesKeyConnector();
}
}
}

View File

@@ -63,6 +63,7 @@ namespace Bit.App.Utilities
private readonly IKeyConnectorService _keyConnectorService;
private readonly IPasswordRepromptService _passwordRepromptService;
private readonly ICryptoService _cryptoService;
private readonly IUserVerificationService _userVerificationService;
private VerificationFlowAction? _action;
private IActionFlowParmeters _parameters;
@@ -73,11 +74,13 @@ namespace Bit.App.Utilities
public VerificationActionsFlowHelper(IKeyConnectorService keyConnectorService,
IPasswordRepromptService passwordRepromptService,
ICryptoService cryptoService)
ICryptoService cryptoService,
IUserVerificationService userVerificationService)
{
_keyConnectorService = keyConnectorService;
_passwordRepromptService = passwordRepromptService;
_cryptoService = cryptoService;
_userVerificationService = userVerificationService;
_actionExecutionerDictionary.Add(VerificationFlowAction.DeleteAccount, ServiceContainer.Resolve<IDeleteAccountActionFlowExecutioner>("deleteAccountActionFlowExecutioner"));
}
@@ -107,9 +110,9 @@ namespace Bit.App.Utilities
public async Task ValidateAndExecuteAsync()
{
var verificationType = await _keyConnectorService.GetUsesKeyConnector()
? VerificationType.OTP
: VerificationType.MasterPassword;
var verificationType = await _userVerificationService.HasMasterPasswordAsync()
? VerificationType.MasterPassword
: VerificationType.OTP;
switch (verificationType)
{

View File

@@ -1,5 +1,4 @@
using System;
using System.Threading.Tasks;
using System.Threading.Tasks;
using Bit.Core.Models.Domain;
using Bit.Core.Models.Response;
@@ -8,7 +7,7 @@ namespace Bit.Core.Abstractions
public interface IKeyConnectorService
{
Task SetUsesKeyConnector(bool usesKeyConnector);
Task<bool> GetUsesKeyConnector();
Task<bool> GetUsesKeyConnectorAsync();
Task<bool> UserNeedsMigration();
Task MigrateUser();
Task GetAndSetKeyAsync(string url);

View File

@@ -6,5 +6,6 @@ namespace Bit.Core.Abstractions
public interface IUserVerificationService
{
Task<bool> VerifyUser(string secret, VerificationType verificationType);
Task<bool> HasMasterPasswordAsync();
}
}

View File

@@ -47,7 +47,7 @@ namespace Bit.Core.Services
await _stateService.SetUsesKeyConnectorAsync(usesKeyConnector);
}
public async Task<bool> GetUsesKeyConnector()
public async Task<bool> GetUsesKeyConnectorAsync()
{
return await _stateService.GetUsesKeyConnectorAsync();
}
@@ -82,7 +82,7 @@ namespace Bit.Core.Services
{
var loggedInUsingSso = await _tokenService.GetIsExternal();
var requiredByOrganization = await GetManagingOrganization() != null;
var userIsNotUsingKeyConnector = !await GetUsesKeyConnector();
var userIsNotUsingKeyConnector = !await GetUsesKeyConnectorAsync();
return loggedInUsingSso && requiredByOrganization && userIsNotUsingKeyConnector;
}

View File

@@ -11,14 +11,18 @@ namespace Bit.Core.Services
private readonly IPlatformUtilsService _platformUtilsService;
private readonly II18nService _i18nService;
private readonly ICryptoService _cryptoService;
private readonly IStateService _stateService;
private readonly IKeyConnectorService _keyConnectorService;
public UserVerificationService(IApiService apiService, IPlatformUtilsService platformUtilsService,
II18nService i18nService, ICryptoService cryptoService)
II18nService i18nService, ICryptoService cryptoService, IStateService stateService, IKeyConnectorService keyConnectorService)
{
_apiService = apiService;
_platformUtilsService = platformUtilsService;
_i18nService = i18nService;
_cryptoService = cryptoService;
_stateService = stateService;
_keyConnectorService = keyConnectorService;
}
async public Task<bool> VerifyUser(string secret, VerificationType verificationType)
@@ -63,5 +67,16 @@ namespace Bit.Core.Services
await _platformUtilsService.ShowDialogAsync(errorMessage);
}
public async Task<bool> HasMasterPasswordAsync()
{
var decryptOptions = await _stateService.GetAccountDecryptionOptions();
if (decryptOptions != null)
{
return decryptOptions.HasMasterPassword;
}
return !await _keyConnectorService.GetUsesKeyConnectorAsync();
}
}
}

View File

@@ -23,7 +23,7 @@ namespace Bit.Core.Services
private readonly ISearchService _searchService;
private readonly IMessagingService _messagingService;
private readonly ITokenService _tokenService;
private readonly IKeyConnectorService _keyConnectorService;
private readonly IUserVerificationService _userVerificationService;
private readonly Func<Tuple<string, bool>, Task> _lockedCallback;
private readonly Func<Tuple<string, bool, bool>, Task> _loggedOutCallback;
@@ -37,7 +37,7 @@ namespace Bit.Core.Services
ISearchService searchService,
IMessagingService messagingService,
ITokenService tokenService,
IKeyConnectorService keyConnectorService,
IUserVerificationService userVerificationService,
Func<Tuple<string, bool>, Task> lockedCallback,
Func<Tuple<string, bool, bool>, Task> loggedOutCallback)
{
@@ -50,7 +50,7 @@ namespace Bit.Core.Services
_searchService = searchService;
_messagingService = messagingService;
_tokenService = tokenService;
_keyConnectorService = keyConnectorService;
_userVerificationService = userVerificationService;
_lockedCallback = lockedCallback;
_loggedOutCallback = loggedOutCallback;
}
@@ -179,7 +179,7 @@ namespace Bit.Core.Services
userId = await _stateService.GetActiveUserIdAsync();
}
if (await _keyConnectorService.GetUsesKeyConnector())
if (!await _userVerificationService.HasMasterPasswordAsync())
{
var pinStatus = await GetPinLockTypeAsync(userId);
var ephemeralPinSet = await _stateService.GetPinKeyEncryptedUserKeyEphemeralAsync()

View File

@@ -55,9 +55,11 @@ namespace Bit.Core.Utilities
var policyService = new PolicyService(stateService, organizationService);
var keyConnectorService = new KeyConnectorService(stateService, cryptoService, tokenService, apiService, cryptoFunctionService,
organizationService);
var userVerificationService = new UserVerificationService(apiService, platformUtilsService, i18nService,
cryptoService, stateService, keyConnectorService);
var vaultTimeoutService = new VaultTimeoutService(cryptoService, stateService, platformUtilsService,
folderService, cipherService, collectionService, searchService, messagingService, tokenService,
keyConnectorService,
userVerificationService,
(extras) =>
{
messagingService.Send("locked", extras);
@@ -86,8 +88,6 @@ namespace Bit.Core.Utilities
var auditService = new AuditService(cryptoFunctionService, apiService);
var environmentService = new EnvironmentService(apiService, stateService, conditionedRunner);
var eventService = new EventService(apiService, stateService, organizationService, cipherService);
var userVerificationService = new UserVerificationService(apiService, platformUtilsService, i18nService,
cryptoService);
var usernameGenerationService = new UsernameGenerationService(cryptoService, apiService, stateService);
var configService = new ConfigService(apiService, stateService, logger);
@@ -104,6 +104,8 @@ namespace Bit.Core.Utilities
Register<ISearchService>("searchService", searchService);
Register<IPolicyService>("policyService", policyService);
Register<ISyncService>("syncService", syncService);
Register<IKeyConnectorService>("keyConnectorService", keyConnectorService);
Register<IUserVerificationService>(userVerificationService);
Register<IVaultTimeoutService>("vaultTimeoutService", vaultTimeoutService);
Register<IPasswordGenerationService>("passwordGenerationService", passwordGenerationService);
Register<ITotpService>("totpService", totpService);
@@ -112,8 +114,6 @@ namespace Bit.Core.Utilities
Register<IAuditService>("auditService", auditService);
Register<IEnvironmentService>("environmentService", environmentService);
Register<IEventService>("eventService", eventService);
Register<IKeyConnectorService>("keyConnectorService", keyConnectorService);
Register<IUserVerificationService>("userVerificationService", userVerificationService);
Register<IUsernameGenerationService>(usernameGenerationService);
Register<IConfigService>(configService);
Register<IDeviceTrustCryptoService>(deviceTrustCryptoService);

View File

@@ -28,14 +28,14 @@ namespace Bit.iOS.Core.Controllers
private IStorageService _secureStorageService;
private IPlatformUtilsService _platformUtilsService;
private IBiometricService _biometricService;
private IKeyConnectorService _keyConnectorService;
private IUserVerificationService _userVerificationService;
private IAccountsManager _accountManager;
private PinLockType _pinStatus;
private bool _pinEnabled;
private bool _biometricEnabled;
private bool _biometricIntegrityValid = true;
private bool _passwordReprompt = false;
private bool _usesKeyConnector;
private bool _hasMasterPassword;
private bool _biometricUnlockOnly = false;
private bool _checkingPassword;
@@ -96,7 +96,7 @@ namespace Bit.iOS.Core.Controllers
_secureStorageService = ServiceContainer.Resolve<IStorageService>("secureStorageService");
_platformUtilsService = ServiceContainer.Resolve<IPlatformUtilsService>("platformUtilsService");
_biometricService = ServiceContainer.Resolve<IBiometricService>("biometricService");
_keyConnectorService = ServiceContainer.Resolve<IKeyConnectorService>("keyConnectorService");
_userVerificationService = ServiceContainer.Resolve<IUserVerificationService>();
_accountManager = ServiceContainer.Resolve<IAccountsManager>("accountsManager");
// We re-use the lock screen for autofill extension to verify master password
@@ -121,15 +121,15 @@ namespace Bit.iOS.Core.Controllers
&& await _cryptoService.HasEncryptedUserKeyAsync();
_biometricIntegrityValid =
await _platformUtilsService.IsBiometricIntegrityValidAsync(BiometricIntegritySourceKey);
_usesKeyConnector = await _keyConnectorService.GetUsesKeyConnector();
_biometricUnlockOnly = _usesKeyConnector && _biometricEnabled && !_pinEnabled;
_hasMasterPassword = await _userVerificationService.HasMasterPasswordAsync();
_biometricUnlockOnly = !_hasMasterPassword && _biometricEnabled && !_pinEnabled;
}
if (_pinEnabled)
{
BaseNavItem.Title = AppResources.VerifyPIN;
}
else if (_usesKeyConnector)
else if (!_hasMasterPassword)
{
BaseNavItem.Title = AppResources.UnlockVault;
}
@@ -200,7 +200,7 @@ namespace Bit.iOS.Core.Controllers
base.ViewDidAppear(animated);
// Users with key connector and without biometric or pin has no MP to unlock with
if (_usesKeyConnector)
if (!_hasMasterPassword)
{
if (!(_pinEnabled || _biometricEnabled) ||
(_biometricEnabled && !_biometricIntegrityValid))

View File

@@ -29,13 +29,13 @@ namespace Bit.iOS.Core.Controllers
private IStorageService _secureStorageService;
private IPlatformUtilsService _platformUtilsService;
private IBiometricService _biometricService;
private IKeyConnectorService _keyConnectorService;
private IUserVerificationService _userVerificationService;
private PinLockType _pinStatus;
private bool _pinEnabled;
private bool _biometricEnabled;
private bool _biometricIntegrityValid = true;
private bool _passwordReprompt = false;
private bool _usesKeyConnector;
private bool _hasMasterPassword;
private bool _biometricUnlockOnly = false;
protected bool autofillExtension = false;
@@ -89,7 +89,7 @@ namespace Bit.iOS.Core.Controllers
_secureStorageService = ServiceContainer.Resolve<IStorageService>("secureStorageService");
_platformUtilsService = ServiceContainer.Resolve<IPlatformUtilsService>("platformUtilsService");
_biometricService = ServiceContainer.Resolve<IBiometricService>("biometricService");
_keyConnectorService = ServiceContainer.Resolve<IKeyConnectorService>("keyConnectorService");
_userVerificationService = ServiceContainer.Resolve<IUserVerificationService>();
// We re-use the lock screen for autofill extension to verify master password
// when trying to access protected items.
@@ -113,21 +113,21 @@ namespace Bit.iOS.Core.Controllers
&& await _cryptoService.HasEncryptedUserKeyAsync();
_biometricIntegrityValid =
await _platformUtilsService.IsBiometricIntegrityValidAsync(BiometricIntegritySourceKey);
_usesKeyConnector = await _keyConnectorService.GetUsesKeyConnector();
_biometricUnlockOnly = _usesKeyConnector && _biometricEnabled && !_pinEnabled;
_hasMasterPassword = await _userVerificationService.HasMasterPasswordAsync();
_biometricUnlockOnly = !_hasMasterPassword && _biometricEnabled && !_pinEnabled;
}
if (_pinEnabled)
{
BaseNavItem.Title = AppResources.VerifyPIN;
}
else if (_usesKeyConnector)
else if (_hasMasterPassword)
{
BaseNavItem.Title = AppResources.UnlockVault;
BaseNavItem.Title = AppResources.VerifyMasterPassword;
}
else
{
BaseNavItem.Title = AppResources.VerifyMasterPassword;
BaseNavItem.Title = AppResources.UnlockVault;
}
BaseCancelButton.Title = AppResources.Cancel;
@@ -186,8 +186,8 @@ namespace Bit.iOS.Core.Controllers
{
base.ViewDidAppear(animated);
// Users with key connector and without biometric or pin has no MP to unlock with
if (_usesKeyConnector)
// Users without MP and without biometric or pin need SSO
if (!_hasMasterPassword)
{
if (!(_pinEnabled || _biometricEnabled) ||
(_biometricEnabled && !_biometricIntegrityValid))

View File

@@ -247,7 +247,8 @@ namespace Bit.iOS.Core.Utilities
var verificationActionsFlowHelper = new VerificationActionsFlowHelper(
ServiceContainer.Resolve<IKeyConnectorService>("keyConnectorService"),
ServiceContainer.Resolve<IPasswordRepromptService>("passwordRepromptService"),
ServiceContainer.Resolve<ICryptoService>("cryptoService"));
ServiceContainer.Resolve<ICryptoService>("cryptoService"),
ServiceContainer.Resolve<IUserVerificationService>());
ServiceContainer.Register<IVerificationActionsFlowHelper>("verificationActionsFlowHelper", verificationActionsFlowHelper);
if (postBootstrapFunc != null)