mirror of
https://github.com/bitwarden/android.git
synced 2024-11-26 19:36:18 +03:00
User settings repo to get biometrics enabled info (#824)
This commit is contained in:
parent
9fcc326df3
commit
aacb955720
5 changed files with 31 additions and 69 deletions
|
@ -66,6 +66,11 @@ interface SettingsRepository {
|
|||
*/
|
||||
var defaultUriMatchType: UriMatchType
|
||||
|
||||
/**
|
||||
* Whether or not biometric unlocking is enabled for the current user.
|
||||
*/
|
||||
val isUnlockWithBiometricsEnabled: Boolean
|
||||
|
||||
/**
|
||||
* Whether or not PIN unlocking is enabled for the current user.
|
||||
*/
|
||||
|
|
|
@ -151,6 +151,11 @@ class SettingsRepositoryImpl(
|
|||
)
|
||||
}
|
||||
|
||||
override val isUnlockWithBiometricsEnabled: Boolean
|
||||
get() = activeUserId
|
||||
?.let { authDiskSource.getUserBiometricUnlockKey(userId = it) != null }
|
||||
?: false
|
||||
|
||||
override val isUnlockWithPinEnabled: Boolean
|
||||
get() = activeUserId
|
||||
?.let { authDiskSource.getEncryptedPin(userId = it) != null }
|
||||
|
|
|
@ -6,7 +6,6 @@ import androidx.lifecycle.viewModelScope
|
|||
import com.x8bit.bitwarden.R
|
||||
import com.x8bit.bitwarden.data.auth.repository.AuthRepository
|
||||
import com.x8bit.bitwarden.data.auth.repository.model.UserFingerprintResult
|
||||
import com.x8bit.bitwarden.data.auth.repository.model.UserState
|
||||
import com.x8bit.bitwarden.data.platform.repository.EnvironmentRepository
|
||||
import com.x8bit.bitwarden.data.platform.repository.SettingsRepository
|
||||
import com.x8bit.bitwarden.data.platform.repository.model.VaultTimeout
|
||||
|
@ -18,7 +17,6 @@ import com.x8bit.bitwarden.ui.platform.base.util.Text
|
|||
import com.x8bit.bitwarden.ui.platform.base.util.asText
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.flow.update
|
||||
import kotlinx.coroutines.launch
|
||||
|
@ -44,11 +42,7 @@ class AccountSecurityViewModel @Inject constructor(
|
|||
dialog = null,
|
||||
fingerprintPhrase = "".asText(), // This will be filled in dynamically
|
||||
isApproveLoginRequestsEnabled = settingsRepository.isApprovePasswordlessLoginsEnabled,
|
||||
isUnlockWithBiometricsEnabled = authRepository
|
||||
.userStateFlow
|
||||
.value
|
||||
?.activeAccount
|
||||
?.isBiometricsEnabled == true,
|
||||
isUnlockWithBiometricsEnabled = settingsRepository.isUnlockWithBiometricsEnabled,
|
||||
isUnlockWithPinEnabled = settingsRepository.isUnlockWithPinEnabled,
|
||||
vaultTimeout = settingsRepository.vaultTimeout,
|
||||
vaultTimeoutAction = settingsRepository.vaultTimeoutAction,
|
||||
|
@ -75,12 +69,6 @@ class AccountSecurityViewModel @Inject constructor(
|
|||
),
|
||||
)
|
||||
}
|
||||
|
||||
authRepository
|
||||
.userStateFlow
|
||||
.map { AccountSecurityAction.Internal.UserStateReceive(it) }
|
||||
.onEach(::sendAction)
|
||||
.launchIn(viewModelScope)
|
||||
}
|
||||
|
||||
override fun handleAction(action: AccountSecurityAction): Unit = when (action) {
|
||||
|
@ -263,8 +251,6 @@ class AccountSecurityViewModel @Inject constructor(
|
|||
is AccountSecurityAction.Internal.FingerprintResultReceive -> {
|
||||
handleFingerprintResultReceived(action)
|
||||
}
|
||||
|
||||
is AccountSecurityAction.Internal.UserStateReceive -> handleUserStateReceive(action)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -281,17 +267,6 @@ class AccountSecurityViewModel @Inject constructor(
|
|||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleUserStateReceive(action: AccountSecurityAction.Internal.UserStateReceive) {
|
||||
mutableStateFlow.update {
|
||||
it.copy(
|
||||
isUnlockWithBiometricsEnabled = action
|
||||
.userState
|
||||
?.activeAccount
|
||||
?.isBiometricsEnabled == true,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -546,12 +521,5 @@ sealed class AccountSecurityAction {
|
|||
data class FingerprintResultReceive(
|
||||
val fingerprintResult: UserFingerprintResult,
|
||||
) : Internal()
|
||||
|
||||
/**
|
||||
* The updated [userState] has been received.
|
||||
*/
|
||||
data class UserStateReceive(
|
||||
val userState: UserState?,
|
||||
) : Internal()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -412,6 +412,24 @@ class SettingsRepositoryTest {
|
|||
}
|
||||
}
|
||||
|
||||
@Suppress("MaxLineLength")
|
||||
@Test
|
||||
fun `isUnlockWithBiometricsEnabled should return a value that tracks the existence of a biometrics key for the current user`() {
|
||||
val userId = "userId"
|
||||
fakeAuthDiskSource.userState = MOCK_USER_STATE
|
||||
fakeAuthDiskSource.storeUserBiometricUnlockKey(
|
||||
userId = userId,
|
||||
biometricsKey = null,
|
||||
)
|
||||
assertFalse(settingsRepository.isUnlockWithBiometricsEnabled)
|
||||
|
||||
fakeAuthDiskSource.storeUserBiometricUnlockKey(
|
||||
userId = userId,
|
||||
biometricsKey = "biometricsKey",
|
||||
)
|
||||
assertTrue(settingsRepository.isUnlockWithBiometricsEnabled)
|
||||
}
|
||||
|
||||
@Suppress("MaxLineLength")
|
||||
@Test
|
||||
fun `isUnlockWithPinEnabled should return a value that tracks the existence of an encrypted PIN for the current user`() {
|
||||
|
|
|
@ -4,7 +4,6 @@ import androidx.lifecycle.SavedStateHandle
|
|||
import app.cash.turbine.test
|
||||
import com.x8bit.bitwarden.data.auth.repository.AuthRepository
|
||||
import com.x8bit.bitwarden.data.auth.repository.model.UserFingerprintResult
|
||||
import com.x8bit.bitwarden.data.auth.repository.model.UserState
|
||||
import com.x8bit.bitwarden.data.platform.repository.EnvironmentRepository
|
||||
import com.x8bit.bitwarden.data.platform.repository.SettingsRepository
|
||||
import com.x8bit.bitwarden.data.platform.repository.model.Environment
|
||||
|
@ -21,7 +20,6 @@ import io.mockk.just
|
|||
import io.mockk.mockk
|
||||
import io.mockk.runs
|
||||
import io.mockk.verify
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.jupiter.api.Assertions.assertEquals
|
||||
import org.junit.jupiter.api.Assertions.assertFalse
|
||||
|
@ -31,12 +29,10 @@ import org.junit.jupiter.api.Test
|
|||
class AccountSecurityViewModelTest : BaseViewModelTest() {
|
||||
|
||||
private val fakeEnvironmentRepository = FakeEnvironmentRepository()
|
||||
private val mutableUserStateFlow = MutableStateFlow<UserState?>(DEFAULT_USER_STATE)
|
||||
private val authRepository: AuthRepository = mockk(relaxed = true) {
|
||||
every { userStateFlow } returns mutableUserStateFlow
|
||||
}
|
||||
private val authRepository: AuthRepository = mockk(relaxed = true)
|
||||
private val vaultRepository: VaultRepository = mockk(relaxed = true)
|
||||
private val settingsRepository: SettingsRepository = mockk {
|
||||
every { isUnlockWithBiometricsEnabled } returns false
|
||||
every { isApprovePasswordlessLoginsEnabled } returns false
|
||||
every { isUnlockWithPinEnabled } returns false
|
||||
every { vaultTimeout } returns VaultTimeout.ThirtyMinutes
|
||||
|
@ -62,18 +58,6 @@ class AccountSecurityViewModelTest : BaseViewModelTest() {
|
|||
coVerify { settingsRepository.getUserFingerprint() }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `userState with biometrics should update state`() {
|
||||
mutableUserStateFlow.value = DEFAULT_USER_STATE.copy(
|
||||
accounts = listOf(DEFAULT_USER_ACCOUNT.copy(isBiometricsEnabled = true)),
|
||||
)
|
||||
val viewModel = createViewModel(initialState = null)
|
||||
assertEquals(
|
||||
DEFAULT_STATE.copy(isUnlockWithBiometricsEnabled = true),
|
||||
viewModel.stateFlow.value,
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `on FingerprintResultReceive should update the fingerprint phrase`() = runTest {
|
||||
val fingerprint = "fingerprint"
|
||||
|
@ -466,21 +450,3 @@ private val DEFAULT_STATE: AccountSecurityState = AccountSecurityState(
|
|||
vaultTimeout = VaultTimeout.ThirtyMinutes,
|
||||
vaultTimeoutAction = VaultTimeoutAction.LOCK,
|
||||
)
|
||||
|
||||
private val DEFAULT_USER_ACCOUNT: UserState.Account = UserState.Account(
|
||||
userId = "activeUserId",
|
||||
name = "Active User",
|
||||
email = "active@bitwarden.com",
|
||||
avatarColorHex = "#aa00aa",
|
||||
environment = Environment.Us,
|
||||
isPremium = true,
|
||||
isLoggedIn = true,
|
||||
isVaultUnlocked = true,
|
||||
isBiometricsEnabled = false,
|
||||
organizations = emptyList(),
|
||||
)
|
||||
|
||||
private val DEFAULT_USER_STATE: UserState = UserState(
|
||||
activeUserId = "activeUserId",
|
||||
accounts = listOf(DEFAULT_USER_ACCOUNT),
|
||||
)
|
||||
|
|
Loading…
Reference in a new issue