diff --git a/app/src/main/java/com/x8bit/bitwarden/data/auth/repository/AuthRepositoryImpl.kt b/app/src/main/java/com/x8bit/bitwarden/data/auth/repository/AuthRepositoryImpl.kt index 4203ce92e..149dcc535 100644 --- a/app/src/main/java/com/x8bit/bitwarden/data/auth/repository/AuthRepositoryImpl.kt +++ b/app/src/main/java/com/x8bit/bitwarden/data/auth/repository/AuthRepositoryImpl.kt @@ -439,7 +439,6 @@ class AuthRepositoryImpl( ) authDiskSource.storeUserKey(userId = userId, userKey = asymmetricalKey) - trustedDeviceManager.trustThisDeviceIfNecessary(userId = userId) vaultRepository.syncIfNecessary() return LoginResult.Success } @@ -1385,7 +1384,6 @@ class AuthRepositoryImpl( organizationKeys = null, ) authDiskSource.storeUserKey(userId = userId, userKey = userKey) - trustedDeviceManager.trustThisDeviceIfNecessary(userId = userId) } authDiskSource.storePendingAuthRequest( userId = userId, diff --git a/app/src/main/java/com/x8bit/bitwarden/data/vault/manager/VaultLockManagerImpl.kt b/app/src/main/java/com/x8bit/bitwarden/data/vault/manager/VaultLockManagerImpl.kt index 973bb0acb..309000e89 100644 --- a/app/src/main/java/com/x8bit/bitwarden/data/vault/manager/VaultLockManagerImpl.kt +++ b/app/src/main/java/com/x8bit/bitwarden/data/vault/manager/VaultLockManagerImpl.kt @@ -8,6 +8,7 @@ import com.bitwarden.crypto.HashPurpose import com.bitwarden.crypto.Kdf import com.x8bit.bitwarden.data.auth.datasource.disk.AuthDiskSource import com.x8bit.bitwarden.data.auth.datasource.sdk.AuthSdkSource +import com.x8bit.bitwarden.data.auth.manager.TrustedDeviceManager import com.x8bit.bitwarden.data.auth.manager.UserLogoutManager import com.x8bit.bitwarden.data.auth.repository.util.toSdkParams import com.x8bit.bitwarden.data.auth.repository.util.userSwitchingChangesFlow @@ -62,7 +63,8 @@ class VaultLockManagerImpl( private val settingsRepository: SettingsRepository, private val appForegroundManager: AppForegroundManager, private val userLogoutManager: UserLogoutManager, - private val dispatcherManager: DispatcherManager, + private val trustedDeviceManager: TrustedDeviceManager, + dispatcherManager: DispatcherManager, private val elapsedRealtimeMillisProvider: () -> Long = { SystemClock.elapsedRealtime() }, ) : VaultLockManager { private val unconfinedScope = CoroutineScope(dispatcherManager.unconfined) @@ -165,6 +167,9 @@ class VaultLockManagerImpl( if (it is VaultUnlockResult.Success) { clearInvalidUnlockCount(userId = userId) setVaultToUnlocked(userId = userId) + trustedDeviceManager.trustThisDeviceIfNecessary( + userId = userId, + ) } else { incrementInvalidUnlockCount(userId = userId) } diff --git a/app/src/main/java/com/x8bit/bitwarden/data/vault/manager/di/VaultManagerModule.kt b/app/src/main/java/com/x8bit/bitwarden/data/vault/manager/di/VaultManagerModule.kt index 6ad86a8a2..e17a6fd07 100644 --- a/app/src/main/java/com/x8bit/bitwarden/data/vault/manager/di/VaultManagerModule.kt +++ b/app/src/main/java/com/x8bit/bitwarden/data/vault/manager/di/VaultManagerModule.kt @@ -3,6 +3,7 @@ package com.x8bit.bitwarden.data.vault.manager.di import android.content.Context import com.x8bit.bitwarden.data.auth.datasource.disk.AuthDiskSource import com.x8bit.bitwarden.data.auth.datasource.sdk.AuthSdkSource +import com.x8bit.bitwarden.data.auth.manager.TrustedDeviceManager import com.x8bit.bitwarden.data.auth.manager.UserLogoutManager import com.x8bit.bitwarden.data.platform.manager.AppForegroundManager import com.x8bit.bitwarden.data.platform.manager.dispatcher.DispatcherManager @@ -52,6 +53,7 @@ object VaultManagerModule { appForegroundManager: AppForegroundManager, userLogoutManager: UserLogoutManager, dispatcherManager: DispatcherManager, + trustedDeviceManager: TrustedDeviceManager, ): VaultLockManager = VaultLockManagerImpl( authDiskSource = authDiskSource, @@ -61,6 +63,7 @@ object VaultManagerModule { appForegroundManager = appForegroundManager, userLogoutManager = userLogoutManager, dispatcherManager = dispatcherManager, + trustedDeviceManager = trustedDeviceManager, ) @Provides diff --git a/app/src/test/java/com/x8bit/bitwarden/data/auth/repository/AuthRepositoryTest.kt b/app/src/test/java/com/x8bit/bitwarden/data/auth/repository/AuthRepositoryTest.kt index c98f1e9b4..8b52d0887 100644 --- a/app/src/test/java/com/x8bit/bitwarden/data/auth/repository/AuthRepositoryTest.kt +++ b/app/src/test/java/com/x8bit/bitwarden/data/auth/repository/AuthRepositoryTest.kt @@ -1215,9 +1215,6 @@ class AuthRepositoryTest { organizationKeys = null, ) } returns VaultUnlockResult.Success - coEvery { - trustedDeviceManager.trustThisDeviceIfNecessary(userId = USER_ID_1) - } returns true.asSuccess() coEvery { vaultRepository.syncIfNecessary() } just runs val result = repository.completeTdeLogin( @@ -1237,7 +1234,6 @@ class AuthRepositoryTest { ), organizationKeys = null, ) - trustedDeviceManager.trustThisDeviceIfNecessary(userId = USER_ID_1) vaultRepository.syncIfNecessary() } fakeAuthDiskSource.assertUserKey(userId = USER_ID_1, userKey = asymmetricalKey) @@ -2531,9 +2527,6 @@ class AuthRepositoryTest { ) } returns successResponse.asSuccess() coEvery { vaultRepository.syncIfNecessary() } just runs - coEvery { - trustedDeviceManager.trustThisDeviceIfNecessary(userId = USER_ID_1) - } returns true.asSuccess() every { successResponse.toUserState( previousUserState = null, @@ -2577,7 +2570,6 @@ class AuthRepositoryTest { ), organizationKeys = null, ) - trustedDeviceManager.trustThisDeviceIfNecessary(userId = USER_ID_1) vaultRepository.syncIfNecessary() } verify(exactly = 1) { diff --git a/app/src/test/java/com/x8bit/bitwarden/data/vault/manager/VaultLockManagerTest.kt b/app/src/test/java/com/x8bit/bitwarden/data/vault/manager/VaultLockManagerTest.kt index cf3425858..f3b9de45e 100644 --- a/app/src/test/java/com/x8bit/bitwarden/data/vault/manager/VaultLockManagerTest.kt +++ b/app/src/test/java/com/x8bit/bitwarden/data/vault/manager/VaultLockManagerTest.kt @@ -9,6 +9,7 @@ import com.x8bit.bitwarden.data.auth.datasource.disk.model.AccountTokensJson import com.x8bit.bitwarden.data.auth.datasource.disk.model.UserStateJson import com.x8bit.bitwarden.data.auth.datasource.disk.util.FakeAuthDiskSource import com.x8bit.bitwarden.data.auth.datasource.sdk.AuthSdkSource +import com.x8bit.bitwarden.data.auth.manager.TrustedDeviceManager import com.x8bit.bitwarden.data.auth.manager.UserLogoutManager import com.x8bit.bitwarden.data.auth.repository.util.toSdkParams import com.x8bit.bitwarden.data.platform.base.FakeDispatcherManager @@ -62,6 +63,7 @@ class VaultLockManagerTest { every { logout(any()) } just runs every { softLogout(any()) } just runs } + private val trustedDeviceManager: TrustedDeviceManager = mockk() private val mutableVaultTimeoutStateFlow = MutableStateFlow<VaultTimeout>(VaultTimeout.ThirtyMinutes) private val mutableVaultTimeoutActionStateFlow = MutableStateFlow(VaultTimeoutAction.LOCK) @@ -79,6 +81,7 @@ class VaultLockManagerTest { settingsRepository = settingsRepository, appForegroundManager = fakeAppForegroundManager, userLogoutManager = userLogoutManager, + trustedDeviceManager = trustedDeviceManager, dispatcherManager = FakeDispatcherManager(), elapsedRealtimeMillisProvider = { elapsedRealtimeMillis }, ) @@ -545,6 +548,9 @@ class VaultLockManagerTest { ), ) } returns InitializeCryptoResult.Success.asSuccess() + coEvery { + trustedDeviceManager.trustThisDeviceIfNecessary(userId = USER_ID) + } returns true.asSuccess() assertFalse(vaultLockManager.isVaultUnlocked(userId = USER_ID)) @@ -564,6 +570,7 @@ class VaultLockManagerTest { ), ), ) + trustedDeviceManager.trustThisDeviceIfNecessary(userId = USER_ID) } } @@ -702,6 +709,9 @@ class VaultLockManagerTest { request = InitOrgCryptoRequest(organizationKeys = organizationKeys), ) } returns InitializeCryptoResult.Success.asSuccess() + coEvery { + trustedDeviceManager.trustThisDeviceIfNecessary(userId = USER_ID) + } returns false.asSuccess() assertEquals( emptyList<VaultUnlockData>(), vaultLockManager.vaultUnlockDataStateFlow.value, @@ -756,12 +766,11 @@ class VaultLockManagerTest { ), ), ) - } - coVerify(exactly = 1) { vaultSdkSource.initializeOrganizationCrypto( userId = USER_ID, request = InitOrgCryptoRequest(organizationKeys = organizationKeys), ) + trustedDeviceManager.trustThisDeviceIfNecessary(userId = USER_ID) } } @@ -799,6 +808,9 @@ class VaultLockManagerTest { coEvery { vaultSdkSource.getUserEncryptionKey(userId = USER_ID) } returns userAutoUnlockKey.asSuccess() + coEvery { + trustedDeviceManager.trustThisDeviceIfNecessary(userId = USER_ID) + } returns true.asSuccess() assertEquals( emptyList<VaultUnlockData>(), vaultLockManager.vaultUnlockDataStateFlow.value, @@ -861,15 +873,12 @@ class VaultLockManagerTest { ), ), ) - } - coVerify(exactly = 1) { vaultSdkSource.initializeOrganizationCrypto( userId = USER_ID, request = InitOrgCryptoRequest(organizationKeys = organizationKeys), ) - } - coVerify { vaultSdkSource.getUserEncryptionKey(userId = USER_ID) + trustedDeviceManager.trustThisDeviceIfNecessary(userId = USER_ID) } } @@ -1410,6 +1419,9 @@ class VaultLockManagerTest { coEvery { vaultSdkSource.getUserEncryptionKey(userId = userId) } returns userAutoUnlockKey.asSuccess() + coEvery { + trustedDeviceManager.trustThisDeviceIfNecessary(userId = userId) + } returns true.asSuccess() val result = vaultLockManager.unlockVault( userId = userId,