1
0
mirror of https://github.com/bitwarden/mobile synced 2025-12-10 21:33:36 +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( var verificationActionsFlowHelper = new VerificationActionsFlowHelper(
ServiceContainer.Resolve<IKeyConnectorService>("keyConnectorService"), ServiceContainer.Resolve<IKeyConnectorService>("keyConnectorService"),
ServiceContainer.Resolve<IPasswordRepromptService>("passwordRepromptService"), ServiceContainer.Resolve<IPasswordRepromptService>("passwordRepromptService"),
ServiceContainer.Resolve<ICryptoService>("cryptoService")); ServiceContainer.Resolve<ICryptoService>("cryptoService"),
ServiceContainer.Resolve<IUserVerificationService>());
ServiceContainer.Register<IVerificationActionsFlowHelper>("verificationActionsFlowHelper", verificationActionsFlowHelper); ServiceContainer.Register<IVerificationActionsFlowHelper>("verificationActionsFlowHelper", verificationActionsFlowHelper);
var accountsManager = new AccountsManager( var accountsManager = new AccountsManager(

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -21,7 +21,7 @@ namespace Bit.App.Pages
private readonly IDeviceActionService _deviceActionService; private readonly IDeviceActionService _deviceActionService;
private readonly IAutofillHandler _autofillHandler; private readonly IAutofillHandler _autofillHandler;
private readonly IVaultTimeoutService _vaultTimeoutService; private readonly IVaultTimeoutService _vaultTimeoutService;
private readonly IKeyConnectorService _keyConnectorService; private readonly IUserVerificationService _userVerificationService;
private CipherAddEditPageViewModel _vm; private CipherAddEditPageViewModel _vm;
private bool _fromAutofill; private bool _fromAutofill;
@@ -43,7 +43,7 @@ namespace Bit.App.Pages
_deviceActionService = ServiceContainer.Resolve<IDeviceActionService>("deviceActionService"); _deviceActionService = ServiceContainer.Resolve<IDeviceActionService>("deviceActionService");
_autofillHandler = ServiceContainer.Resolve<IAutofillHandler>(); _autofillHandler = ServiceContainer.Resolve<IAutofillHandler>();
_vaultTimeoutService = ServiceContainer.Resolve<IVaultTimeoutService>("vaultTimeoutService"); _vaultTimeoutService = ServiceContainer.Resolve<IVaultTimeoutService>("vaultTimeoutService");
_keyConnectorService = ServiceContainer.Resolve<IKeyConnectorService>("keyConnectorService"); _userVerificationService = ServiceContainer.Resolve<IUserVerificationService>();
_appOptions = appOptions; _appOptions = appOptions;
_fromAutofill = fromAutofill; _fromAutofill = fromAutofill;
@@ -175,8 +175,8 @@ namespace Bit.App.Pages
RequestFocus(_nameEntry); RequestFocus(_nameEntry);
} }
}); });
// Hide password reprompt option if using key connector
_passwordPrompt.IsVisible = !await _keyConnectorService.GetUsesKeyConnector(); _passwordPrompt.IsVisible = await _userVerificationService.HasMasterPasswordAsync();
} }
protected override void OnDisappearing() 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.Abstractions;
using Bit.App.Resources; using Bit.App.Resources;
using Bit.Core.Abstractions; using Bit.Core.Abstractions;
using Bit.Core.Utilities;
namespace Bit.App.Services namespace Bit.App.Services
{ {
@@ -40,11 +38,5 @@ namespace Bit.App.Services
return await _cryptoService.CompareAndUpdateKeyHashAsync(password, null); 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 IKeyConnectorService _keyConnectorService;
private readonly IPasswordRepromptService _passwordRepromptService; private readonly IPasswordRepromptService _passwordRepromptService;
private readonly ICryptoService _cryptoService; private readonly ICryptoService _cryptoService;
private readonly IUserVerificationService _userVerificationService;
private VerificationFlowAction? _action; private VerificationFlowAction? _action;
private IActionFlowParmeters _parameters; private IActionFlowParmeters _parameters;
@@ -73,11 +74,13 @@ namespace Bit.App.Utilities
public VerificationActionsFlowHelper(IKeyConnectorService keyConnectorService, public VerificationActionsFlowHelper(IKeyConnectorService keyConnectorService,
IPasswordRepromptService passwordRepromptService, IPasswordRepromptService passwordRepromptService,
ICryptoService cryptoService) ICryptoService cryptoService,
IUserVerificationService userVerificationService)
{ {
_keyConnectorService = keyConnectorService; _keyConnectorService = keyConnectorService;
_passwordRepromptService = passwordRepromptService; _passwordRepromptService = passwordRepromptService;
_cryptoService = cryptoService; _cryptoService = cryptoService;
_userVerificationService = userVerificationService;
_actionExecutionerDictionary.Add(VerificationFlowAction.DeleteAccount, ServiceContainer.Resolve<IDeleteAccountActionFlowExecutioner>("deleteAccountActionFlowExecutioner")); _actionExecutionerDictionary.Add(VerificationFlowAction.DeleteAccount, ServiceContainer.Resolve<IDeleteAccountActionFlowExecutioner>("deleteAccountActionFlowExecutioner"));
} }
@@ -107,9 +110,9 @@ namespace Bit.App.Utilities
public async Task ValidateAndExecuteAsync() public async Task ValidateAndExecuteAsync()
{ {
var verificationType = await _keyConnectorService.GetUsesKeyConnector() var verificationType = await _userVerificationService.HasMasterPasswordAsync()
? VerificationType.OTP ? VerificationType.MasterPassword
: VerificationType.MasterPassword; : VerificationType.OTP;
switch (verificationType) 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.Domain;
using Bit.Core.Models.Response; using Bit.Core.Models.Response;
@@ -8,7 +7,7 @@ namespace Bit.Core.Abstractions
public interface IKeyConnectorService public interface IKeyConnectorService
{ {
Task SetUsesKeyConnector(bool usesKeyConnector); Task SetUsesKeyConnector(bool usesKeyConnector);
Task<bool> GetUsesKeyConnector(); Task<bool> GetUsesKeyConnectorAsync();
Task<bool> UserNeedsMigration(); Task<bool> UserNeedsMigration();
Task MigrateUser(); Task MigrateUser();
Task GetAndSetKeyAsync(string url); Task GetAndSetKeyAsync(string url);

View File

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

View File

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

View File

@@ -11,14 +11,18 @@ namespace Bit.Core.Services
private readonly IPlatformUtilsService _platformUtilsService; private readonly IPlatformUtilsService _platformUtilsService;
private readonly II18nService _i18nService; private readonly II18nService _i18nService;
private readonly ICryptoService _cryptoService; private readonly ICryptoService _cryptoService;
private readonly IStateService _stateService;
private readonly IKeyConnectorService _keyConnectorService;
public UserVerificationService(IApiService apiService, IPlatformUtilsService platformUtilsService, public UserVerificationService(IApiService apiService, IPlatformUtilsService platformUtilsService,
II18nService i18nService, ICryptoService cryptoService) II18nService i18nService, ICryptoService cryptoService, IStateService stateService, IKeyConnectorService keyConnectorService)
{ {
_apiService = apiService; _apiService = apiService;
_platformUtilsService = platformUtilsService; _platformUtilsService = platformUtilsService;
_i18nService = i18nService; _i18nService = i18nService;
_cryptoService = cryptoService; _cryptoService = cryptoService;
_stateService = stateService;
_keyConnectorService = keyConnectorService;
} }
async public Task<bool> VerifyUser(string secret, VerificationType verificationType) async public Task<bool> VerifyUser(string secret, VerificationType verificationType)
@@ -63,5 +67,16 @@ namespace Bit.Core.Services
await _platformUtilsService.ShowDialogAsync(errorMessage); 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 ISearchService _searchService;
private readonly IMessagingService _messagingService; private readonly IMessagingService _messagingService;
private readonly ITokenService _tokenService; 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>, Task> _lockedCallback;
private readonly Func<Tuple<string, bool, bool>, Task> _loggedOutCallback; private readonly Func<Tuple<string, bool, bool>, Task> _loggedOutCallback;
@@ -37,7 +37,7 @@ namespace Bit.Core.Services
ISearchService searchService, ISearchService searchService,
IMessagingService messagingService, IMessagingService messagingService,
ITokenService tokenService, ITokenService tokenService,
IKeyConnectorService keyConnectorService, IUserVerificationService userVerificationService,
Func<Tuple<string, bool>, Task> lockedCallback, Func<Tuple<string, bool>, Task> lockedCallback,
Func<Tuple<string, bool, bool>, Task> loggedOutCallback) Func<Tuple<string, bool, bool>, Task> loggedOutCallback)
{ {
@@ -50,7 +50,7 @@ namespace Bit.Core.Services
_searchService = searchService; _searchService = searchService;
_messagingService = messagingService; _messagingService = messagingService;
_tokenService = tokenService; _tokenService = tokenService;
_keyConnectorService = keyConnectorService; _userVerificationService = userVerificationService;
_lockedCallback = lockedCallback; _lockedCallback = lockedCallback;
_loggedOutCallback = loggedOutCallback; _loggedOutCallback = loggedOutCallback;
} }
@@ -179,7 +179,7 @@ namespace Bit.Core.Services
userId = await _stateService.GetActiveUserIdAsync(); userId = await _stateService.GetActiveUserIdAsync();
} }
if (await _keyConnectorService.GetUsesKeyConnector()) if (!await _userVerificationService.HasMasterPasswordAsync())
{ {
var pinStatus = await GetPinLockTypeAsync(userId); var pinStatus = await GetPinLockTypeAsync(userId);
var ephemeralPinSet = await _stateService.GetPinKeyEncryptedUserKeyEphemeralAsync() var ephemeralPinSet = await _stateService.GetPinKeyEncryptedUserKeyEphemeralAsync()

View File

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

View File

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

View File

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

View File

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