Allow user with untrusted device to unlock vault if they have a means to do so (#1321)

This commit is contained in:
David Perez 2024-04-30 13:17:01 -05:00 committed by Álison Fernandes
parent 3a25747518
commit 13d31c6ce8
3 changed files with 45 additions and 1 deletions

View file

@ -70,6 +70,14 @@ data class UserState(
* Indicates that the user does or does not have a master password. * Indicates that the user does or does not have a master password.
*/ */
val hasMasterPassword: Boolean get() = trustedDevice?.hasMasterPassword != false val hasMasterPassword: Boolean get() = trustedDevice?.hasMasterPassword != false
/**
* Indicates that the user does or does not have a means to unlock the vault.
*/
val hasUnlockMechanism: Boolean
get() = hasMasterPassword ||
isBiometricsEnabled ||
vaultUnlockType == VaultUnlockType.PIN
} }
/** /**

View file

@ -61,7 +61,8 @@ class RootNavViewModel @Inject constructor(
val userState = action.userState val userState = action.userState
val updatedRootNavState = when { val updatedRootNavState = when {
userState?.activeAccount?.trustedDevice?.isDeviceTrusted == false && userState?.activeAccount?.trustedDevice?.isDeviceTrusted == false &&
!userState.activeAccount.isVaultUnlocked -> RootNavState.TrustedDevice !userState.activeAccount.isVaultUnlocked &&
!userState.activeAccount.hasUnlockMechanism -> RootNavState.TrustedDevice
userState?.activeAccount?.needsMasterPassword == true -> RootNavState.SetPassword userState?.activeAccount?.needsMasterPassword == true -> RootNavState.SetPassword

View file

@ -153,6 +153,41 @@ class RootNavViewModelTest : BaseViewModelTest() {
assertEquals(RootNavState.TrustedDevice, viewModel.stateFlow.value) assertEquals(RootNavState.TrustedDevice, viewModel.stateFlow.value)
} }
@Suppress("MaxLineLength")
@Test
fun `when the active user has an untrusted device with password the nav state should be VaultLocked`() {
mutableUserStateFlow.tryEmit(
UserState(
activeUserId = "activeUserId",
accounts = listOf(
UserState.Account(
userId = "activeUserId",
name = "name",
email = "email",
avatarColorHex = "avatarColorHex",
environment = Environment.Us,
isPremium = true,
isLoggedIn = true,
isVaultUnlocked = false,
needsPasswordReset = false,
isBiometricsEnabled = false,
organizations = emptyList(),
needsMasterPassword = false,
trustedDevice = UserState.TrustedDevice(
isDeviceTrusted = false,
hasMasterPassword = true,
hasAdminApproval = true,
hasLoginApprovingDevice = true,
hasResetPasswordPermission = false,
),
),
),
),
)
val viewModel = createViewModel()
assertEquals(RootNavState.VaultLocked, viewModel.stateFlow.value)
}
@Suppress("MaxLineLength") @Suppress("MaxLineLength")
@Test @Test
fun `when the active user has an untrusted device but an unlocked vault the nav state should be Auth`() { fun `when the active user has an untrusted device but an unlocked vault the nav state should be Auth`() {