mirror of
https://github.com/bitwarden/android.git
synced 2026-08-29 10:17:56 -05:00
PM-33160: Instantiate SDK client with Repositories class (#6681)
This commit is contained in:
@@ -124,6 +124,16 @@ interface AuthDiskSource : AppIdProvider {
|
||||
*/
|
||||
fun storeUserKey(userId: String, userKey: String?)
|
||||
|
||||
/**
|
||||
* Retrieves the local user data key for the given [userId].
|
||||
*/
|
||||
fun getLocalUserDataKey(userId: String): String?
|
||||
|
||||
/**
|
||||
* Stores the local user data key for a given [userId].
|
||||
*/
|
||||
fun storeLocalUserDataKey(userId: String, wrappedKey: String?)
|
||||
|
||||
/**
|
||||
* Retrieves a private key using a [userId].
|
||||
*/
|
||||
|
||||
+9
@@ -35,6 +35,7 @@ private const val REMEMBERED_ORG_IDENTIFIER_KEY = "rememberedOrgIdentifier"
|
||||
private const val STATE_KEY = "state"
|
||||
private const val INVALID_UNLOCK_ATTEMPTS_KEY = "invalidUnlockAttempts"
|
||||
private const val MASTER_KEY_ENCRYPTION_USER_KEY = "masterKeyEncryptedUserKey"
|
||||
private const val LOCAL_USER_DATA_KEY = "localUserDataKey"
|
||||
private const val MASTER_KEY_ENCRYPTION_PRIVATE_KEY = "encPrivateKey"
|
||||
private const val PIN_PROTECTED_USER_KEY_KEY = "pinKeyEncryptedUserKey"
|
||||
private const val PIN_PROTECTED_USER_KEY_KEY_ENVELOPE = "pinKeyEncryptedUserKeyEnvelope"
|
||||
@@ -144,6 +145,7 @@ class AuthDiskSourceImpl(
|
||||
override fun clearData(userId: String) {
|
||||
storeInvalidUnlockAttempts(userId = userId, invalidUnlockAttempts = null)
|
||||
storeUserKey(userId = userId, userKey = null)
|
||||
storeLocalUserDataKey(userId = userId, wrappedKey = null)
|
||||
storeUserAutoUnlockKey(userId = userId, userAutoUnlockKey = null)
|
||||
storePrivateKey(userId = userId, privateKey = null)
|
||||
storeAccountKeys(userId = userId, accountKeys = null)
|
||||
@@ -237,6 +239,13 @@ class AuthDiskSourceImpl(
|
||||
)
|
||||
}
|
||||
|
||||
override fun getLocalUserDataKey(userId: String): String? =
|
||||
getString(key = LOCAL_USER_DATA_KEY.appendIdentifier(userId))
|
||||
|
||||
override fun storeLocalUserDataKey(userId: String, wrappedKey: String?) {
|
||||
putString(key = LOCAL_USER_DATA_KEY.appendIdentifier(userId), value = wrappedKey)
|
||||
}
|
||||
|
||||
@Deprecated("Use getAccountKeys instead.", replaceWith = ReplaceWith("getAccountKeys"))
|
||||
override fun getPrivateKey(userId: String): String? =
|
||||
getString(key = MASTER_KEY_ENCRYPTION_PRIVATE_KEY.appendIdentifier(userId))
|
||||
|
||||
+3
-5
@@ -26,11 +26,9 @@ class SdkClientManagerImpl(
|
||||
repository = sdkRepoFactory.getServerCommunicationConfigRepository(),
|
||||
platformApi = sdkPlatformApiFactory.getServerCommunicationConfigPlatformApi(),
|
||||
)
|
||||
userId?.let {
|
||||
platform().state().apply {
|
||||
registerCipherRepository(sdkRepoFactory.getCipherRepository(userId = it))
|
||||
}
|
||||
}
|
||||
platform().state().registerClientManagedRepositories(
|
||||
repositories = sdkRepoFactory.getRepositories(userId = userId),
|
||||
)
|
||||
}
|
||||
},
|
||||
) : SdkClientManager {
|
||||
|
||||
+3
-3
@@ -1,7 +1,7 @@
|
||||
package com.x8bit.bitwarden.data.platform.manager.sdk
|
||||
|
||||
import com.bitwarden.core.ClientManagedTokens
|
||||
import com.bitwarden.sdk.CipherRepository
|
||||
import com.bitwarden.sdk.Repositories
|
||||
import com.bitwarden.sdk.ServerCommunicationConfigRepository
|
||||
|
||||
/**
|
||||
@@ -9,9 +9,9 @@ import com.bitwarden.sdk.ServerCommunicationConfigRepository
|
||||
*/
|
||||
interface SdkRepositoryFactory {
|
||||
/**
|
||||
* Retrieves or creates a [CipherRepository] for use with the Bitwarden SDK.
|
||||
* Retrieves or creates a [Repositories] for use with the Bitwarden SDK.
|
||||
*/
|
||||
fun getCipherRepository(userId: String): CipherRepository
|
||||
fun getRepositories(userId: String?): Repositories
|
||||
|
||||
/**
|
||||
* Retrieves or creates a [ClientManagedTokens] for use with the Bitwarden SDK.
|
||||
|
||||
+17
-7
@@ -2,11 +2,12 @@ package com.x8bit.bitwarden.data.platform.manager.sdk
|
||||
|
||||
import com.bitwarden.core.ClientManagedTokens
|
||||
import com.bitwarden.data.datasource.disk.ConfigDiskSource
|
||||
import com.bitwarden.sdk.CipherRepository
|
||||
import com.bitwarden.sdk.Repositories
|
||||
import com.bitwarden.sdk.ServerCommunicationConfigRepository
|
||||
import com.x8bit.bitwarden.data.auth.datasource.disk.AuthDiskSource
|
||||
import com.x8bit.bitwarden.data.platform.datasource.disk.CookieDiskSource
|
||||
import com.x8bit.bitwarden.data.platform.manager.sdk.repository.SdkCipherRepository
|
||||
import com.x8bit.bitwarden.data.platform.manager.sdk.repository.SdkLocalUserDataKeyStateRepository
|
||||
import com.x8bit.bitwarden.data.platform.manager.sdk.repository.SdkTokenRepository
|
||||
import com.x8bit.bitwarden.data.platform.manager.sdk.repository.ServerCommunicationConfigRepositoryImpl
|
||||
import com.x8bit.bitwarden.data.vault.datasource.disk.VaultDiskSource
|
||||
@@ -20,12 +21,15 @@ class SdkRepositoryFactoryImpl(
|
||||
private val configDiskSource: ConfigDiskSource,
|
||||
private val authDiskSource: AuthDiskSource,
|
||||
) : SdkRepositoryFactory {
|
||||
override fun getCipherRepository(
|
||||
userId: String,
|
||||
): CipherRepository =
|
||||
SdkCipherRepository(
|
||||
userId = userId,
|
||||
vaultDiskSource = vaultDiskSource,
|
||||
override fun getRepositories(userId: String?): Repositories =
|
||||
Repositories(
|
||||
cipher = getSdkRepository(userId = userId),
|
||||
folder = null,
|
||||
userKeyState = null,
|
||||
localUserDataKeyState = SdkLocalUserDataKeyStateRepository(
|
||||
authDiskSource = authDiskSource,
|
||||
),
|
||||
ephemeralPinEnvelopeState = null,
|
||||
)
|
||||
|
||||
override fun getClientManagedTokens(
|
||||
@@ -41,4 +45,10 @@ class SdkRepositoryFactoryImpl(
|
||||
cookieDiskSource = cookieDiskSource,
|
||||
configDiskSource = configDiskSource,
|
||||
)
|
||||
|
||||
private fun getSdkRepository(
|
||||
userId: String?,
|
||||
): SdkCipherRepository? = userId?.let {
|
||||
SdkCipherRepository(userId = it, vaultDiskSource = vaultDiskSource)
|
||||
}
|
||||
}
|
||||
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
package com.x8bit.bitwarden.data.platform.manager.sdk.repository
|
||||
|
||||
import com.bitwarden.core.LocalUserDataKeyState
|
||||
import com.bitwarden.sdk.LocalUserDataKeyStateRepository
|
||||
import com.x8bit.bitwarden.data.auth.datasource.disk.AuthDiskSource
|
||||
|
||||
/**
|
||||
* An implementation of a Bitwarden SDK [LocalUserDataKeyStateRepository].
|
||||
*/
|
||||
class SdkLocalUserDataKeyStateRepository(
|
||||
private val authDiskSource: AuthDiskSource,
|
||||
) : LocalUserDataKeyStateRepository {
|
||||
override suspend fun get(id: String): LocalUserDataKeyState? {
|
||||
return authDiskSource
|
||||
.getLocalUserDataKey(userId = id)
|
||||
?.let { LocalUserDataKeyState(wrappedKey = it) }
|
||||
}
|
||||
|
||||
override suspend fun has(
|
||||
id: String,
|
||||
): Boolean = authDiskSource.getLocalUserDataKey(userId = id) != null
|
||||
|
||||
override suspend fun list(): List<LocalUserDataKeyState> =
|
||||
authDiskSource
|
||||
.userState
|
||||
?.accounts
|
||||
?.mapNotNull { get(id = it.key) }
|
||||
.orEmpty()
|
||||
|
||||
override suspend fun remove(id: String) {
|
||||
authDiskSource.storeLocalUserDataKey(userId = id, wrappedKey = null)
|
||||
}
|
||||
|
||||
override suspend fun removeAll() {
|
||||
removeBulk(keys = authDiskSource.userState?.accounts.orEmpty().keys.toList())
|
||||
}
|
||||
|
||||
override suspend fun removeBulk(keys: List<String>) {
|
||||
keys.forEach { remove(id = it) }
|
||||
}
|
||||
|
||||
override suspend fun set(id: String, value: LocalUserDataKeyState) {
|
||||
authDiskSource.storeLocalUserDataKey(userId = id, value.wrappedKey)
|
||||
}
|
||||
|
||||
override suspend fun setBulk(values: Map<String, LocalUserDataKeyState>) {
|
||||
values.forEach { (id, value) -> set(id = id, value = value) }
|
||||
}
|
||||
}
|
||||
@@ -711,6 +711,7 @@ class VaultLockManagerImpl(
|
||||
is InitUserCryptoMethod.DecryptedKey,
|
||||
is InitUserCryptoMethod.DeviceKey,
|
||||
is InitUserCryptoMethod.KeyConnector,
|
||||
is InitUserCryptoMethod.KeyConnectorUrl,
|
||||
is InitUserCryptoMethod.Pin,
|
||||
is InitUserCryptoMethod.PinEnvelope,
|
||||
-> return
|
||||
|
||||
+1
@@ -14,5 +14,6 @@ val InitUserCryptoMethod.logTag: String
|
||||
is InitUserCryptoMethod.KeyConnector -> "Key Connector"
|
||||
is InitUserCryptoMethod.Pin -> "Pin"
|
||||
is InitUserCryptoMethod.PinEnvelope -> "Pin Envelope"
|
||||
is InitUserCryptoMethod.KeyConnectorUrl -> "Key Connector Url"
|
||||
is InitUserCryptoMethod.MasterPasswordUnlock -> "Master Password Unlock"
|
||||
}
|
||||
|
||||
+22
@@ -448,6 +448,28 @@ class AuthDiskSourceTest {
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `getLocalUserDataKey should pull from SharedPreferences`() {
|
||||
val userKeyBaseKey = "bwPreferencesStorage:localUserDataKey"
|
||||
val mockUserId = "mockUserId"
|
||||
val mockLocalUserKey = "mockLocalUserDataKey"
|
||||
fakeSharedPreferences.edit {
|
||||
putString("${userKeyBaseKey}_$mockUserId", mockLocalUserKey)
|
||||
}
|
||||
val actual = authDiskSource.getLocalUserDataKey(userId = mockUserId)
|
||||
assertEquals(mockLocalUserKey, actual)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `storeLocalUserDataKey should update SharedPreferences`() {
|
||||
val userKeyBaseKey = "bwPreferencesStorage:localUserDataKey"
|
||||
val mockUserId = "mockUserId"
|
||||
val mockLocalUserKey = "mockLocalUserDataKey"
|
||||
authDiskSource.storeLocalUserDataKey(userId = mockUserId, wrappedKey = mockLocalUserKey)
|
||||
val actual = fakeSharedPreferences.getString("${userKeyBaseKey}_$mockUserId", null)
|
||||
assertEquals(mockLocalUserKey, actual)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `getPrivateKey should pull from SharedPreferences`() {
|
||||
val privateKeyBaseKey = "bwPreferencesStorage:encPrivateKey"
|
||||
|
||||
+8
@@ -45,6 +45,7 @@ class FakeAuthDiskSource : AuthDiskSource {
|
||||
private val storedShouldTrustDevice = mutableMapOf<String, Boolean?>()
|
||||
private val storedInvalidUnlockAttempts = mutableMapOf<String, Int?>()
|
||||
private val storedUserKeys = mutableMapOf<String, String?>()
|
||||
private val storedLocalUserDataKeys = mutableMapOf<String, String?>()
|
||||
private val storedPrivateKeys = mutableMapOf<String, String?>()
|
||||
private val storedTwoFactorTokens = mutableMapOf<String, String?>()
|
||||
private val storedUserAutoUnlockKeys = mutableMapOf<String, String?>()
|
||||
@@ -81,6 +82,7 @@ class FakeAuthDiskSource : AuthDiskSource {
|
||||
override fun clearData(userId: String) {
|
||||
storedInvalidUnlockAttempts.remove(userId)
|
||||
storedUserKeys.remove(userId)
|
||||
storedLocalUserDataKeys.remove(userId)
|
||||
storedPrivateKeys.remove(userId)
|
||||
storedTwoFactorTokens.clear()
|
||||
storedUserAutoUnlockKeys.remove(userId)
|
||||
@@ -150,6 +152,12 @@ class FakeAuthDiskSource : AuthDiskSource {
|
||||
storedUserKeys[userId] = userKey
|
||||
}
|
||||
|
||||
override fun getLocalUserDataKey(userId: String): String? = storedLocalUserDataKeys[userId]
|
||||
|
||||
override fun storeLocalUserDataKey(userId: String, wrappedKey: String?) {
|
||||
storedLocalUserDataKeys[userId] = wrappedKey
|
||||
}
|
||||
|
||||
@Deprecated("Use getAccountKeys instead.", replaceWith = ReplaceWith("getAccountKeys"))
|
||||
override fun getPrivateKey(userId: String): String? = storedPrivateKeys[userId]
|
||||
|
||||
|
||||
+1
-1
@@ -22,7 +22,7 @@ class SdkClientManagerTest {
|
||||
every { loadLibrary(any()) } returns Result.success(Unit)
|
||||
}
|
||||
private val sdkRepoFactory: SdkRepositoryFactory = mockk {
|
||||
every { getCipherRepository(userId = any()) } returns mockk()
|
||||
every { getRepositories(userId = any()) } returns mockk()
|
||||
}
|
||||
private val sdkPlatformApiFactory: SdkPlatformApiFactory = mockk {
|
||||
every { getServerCommunicationConfigPlatformApi() } returns mockk()
|
||||
|
||||
+9
-4
@@ -23,18 +23,23 @@ class SdkRepositoryFactoryTests {
|
||||
)
|
||||
|
||||
@Test
|
||||
fun `getCipherRepository should create a new client`() {
|
||||
fun `getRepositories should create a new client`() {
|
||||
val userId = "userId"
|
||||
val firstClient = sdkRepoFactory.getCipherRepository(userId = userId)
|
||||
val firstClient = sdkRepoFactory.getRepositories(userId = userId)
|
||||
|
||||
// Additional calls for the same userId should create a repo
|
||||
val secondClient = sdkRepoFactory.getCipherRepository(userId = userId)
|
||||
val secondClient = sdkRepoFactory.getRepositories(userId = userId)
|
||||
assertNotEquals(firstClient, secondClient)
|
||||
|
||||
// Additional calls for different userIds should return a different repo
|
||||
val otherUserId = "otherUserId"
|
||||
val thirdClient = sdkRepoFactory.getCipherRepository(userId = otherUserId)
|
||||
val thirdClient = sdkRepoFactory.getRepositories(userId = otherUserId)
|
||||
assertNotEquals(firstClient, thirdClient)
|
||||
|
||||
// Null should get its own client too
|
||||
val fourthClient = sdkRepoFactory.getRepositories(userId = null)
|
||||
assertNotEquals(firstClient, fourthClient)
|
||||
assertNotEquals(thirdClient, fourthClient)
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
+171
@@ -0,0 +1,171 @@
|
||||
package com.x8bit.bitwarden.data.platform.manager.sdk.repository
|
||||
|
||||
import com.bitwarden.core.LocalUserDataKeyState
|
||||
import com.x8bit.bitwarden.data.auth.datasource.disk.model.UserStateJson
|
||||
import com.x8bit.bitwarden.data.auth.datasource.disk.util.FakeAuthDiskSource
|
||||
import io.mockk.mockk
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.jupiter.api.Assertions.assertEquals
|
||||
import org.junit.jupiter.api.Assertions.assertFalse
|
||||
import org.junit.jupiter.api.Assertions.assertNull
|
||||
import org.junit.jupiter.api.Assertions.assertTrue
|
||||
import org.junit.jupiter.api.Test
|
||||
|
||||
class SdkLocalUserDataKeyStateRepositoryTest {
|
||||
|
||||
private val fakeAuthDiskSource = FakeAuthDiskSource()
|
||||
|
||||
private val repository = SdkLocalUserDataKeyStateRepository(
|
||||
authDiskSource = fakeAuthDiskSource,
|
||||
)
|
||||
|
||||
@Test
|
||||
fun `get should return null when no key is stored for the given id`() = runTest {
|
||||
assertNull(repository.get(id = USER_ID))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `get should return LocalUserDataKeyState when key is stored for the given id`() = runTest {
|
||||
fakeAuthDiskSource.storeLocalUserDataKey(userId = USER_ID, wrappedKey = WRAPPED_KEY)
|
||||
|
||||
assertEquals(
|
||||
LocalUserDataKeyState(wrappedKey = WRAPPED_KEY),
|
||||
repository.get(id = USER_ID),
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `has should return false when no key is stored for the given id`() = runTest {
|
||||
assertFalse(repository.has(id = USER_ID))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `has should return true when a key is stored for the given id`() = runTest {
|
||||
fakeAuthDiskSource.storeLocalUserDataKey(userId = USER_ID, wrappedKey = WRAPPED_KEY)
|
||||
|
||||
assertTrue(repository.has(id = USER_ID))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `list should return empty list when userState is null`() = runTest {
|
||||
fakeAuthDiskSource.userState = null
|
||||
|
||||
assertEquals(emptyList<LocalUserDataKeyState>(), repository.list())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `list should return empty list when no keys are stored for any account`() = runTest {
|
||||
fakeAuthDiskSource.userState = UserStateJson(
|
||||
activeUserId = USER_ID,
|
||||
accounts = mapOf(USER_ID to mockk()),
|
||||
)
|
||||
|
||||
assertEquals(emptyList<LocalUserDataKeyState>(), repository.list())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `list should return LocalUserDataKeyState for each account that has a stored key`() =
|
||||
runTest {
|
||||
fakeAuthDiskSource.userState = UserStateJson(
|
||||
activeUserId = USER_ID,
|
||||
accounts = mapOf(
|
||||
USER_ID to mockk(),
|
||||
USER_ID_2 to mockk(),
|
||||
),
|
||||
)
|
||||
fakeAuthDiskSource.storeLocalUserDataKey(userId = USER_ID, wrappedKey = WRAPPED_KEY)
|
||||
fakeAuthDiskSource.storeLocalUserDataKey(userId = USER_ID_2, wrappedKey = WRAPPED_KEY_2)
|
||||
|
||||
assertEquals(
|
||||
listOf(
|
||||
LocalUserDataKeyState(wrappedKey = WRAPPED_KEY),
|
||||
LocalUserDataKeyState(wrappedKey = WRAPPED_KEY_2),
|
||||
),
|
||||
repository.list(),
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `list should omit accounts that have no stored key`() = runTest {
|
||||
fakeAuthDiskSource.userState = UserStateJson(
|
||||
activeUserId = USER_ID,
|
||||
accounts = mapOf(USER_ID to mockk(), USER_ID_2 to mockk()),
|
||||
)
|
||||
fakeAuthDiskSource.storeLocalUserDataKey(userId = USER_ID, wrappedKey = WRAPPED_KEY)
|
||||
|
||||
assertEquals(
|
||||
listOf(LocalUserDataKeyState(wrappedKey = WRAPPED_KEY)),
|
||||
repository.list(),
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `remove should clear the stored key for the given id`() = runTest {
|
||||
fakeAuthDiskSource.storeLocalUserDataKey(userId = USER_ID, wrappedKey = WRAPPED_KEY)
|
||||
|
||||
repository.remove(id = USER_ID)
|
||||
|
||||
assertNull(fakeAuthDiskSource.getLocalUserDataKey(userId = USER_ID))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `removeAll should clear the stored key for all accounts`() = runTest {
|
||||
fakeAuthDiskSource.userState = UserStateJson(
|
||||
activeUserId = USER_ID,
|
||||
accounts = mapOf(
|
||||
USER_ID to mockk(),
|
||||
USER_ID_2 to mockk(),
|
||||
),
|
||||
)
|
||||
fakeAuthDiskSource.storeLocalUserDataKey(userId = USER_ID, wrappedKey = WRAPPED_KEY)
|
||||
fakeAuthDiskSource.storeLocalUserDataKey(userId = USER_ID_2, wrappedKey = WRAPPED_KEY_2)
|
||||
|
||||
repository.removeAll()
|
||||
|
||||
assertNull(fakeAuthDiskSource.getLocalUserDataKey(userId = USER_ID))
|
||||
assertNull(fakeAuthDiskSource.getLocalUserDataKey(userId = USER_ID_2))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `removeAll should do nothing when userState is null`() = runTest {
|
||||
fakeAuthDiskSource.userState = null
|
||||
|
||||
repository.removeAll()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `removeBulk should clear the stored key for each given id`() = runTest {
|
||||
fakeAuthDiskSource.storeLocalUserDataKey(userId = USER_ID, wrappedKey = WRAPPED_KEY)
|
||||
fakeAuthDiskSource.storeLocalUserDataKey(userId = USER_ID_2, wrappedKey = WRAPPED_KEY_2)
|
||||
|
||||
repository.removeBulk(keys = listOf(USER_ID, USER_ID_2))
|
||||
|
||||
assertNull(fakeAuthDiskSource.getLocalUserDataKey(userId = USER_ID))
|
||||
assertNull(fakeAuthDiskSource.getLocalUserDataKey(userId = USER_ID_2))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `set should store the wrapped key for the given id`() = runTest {
|
||||
repository.set(id = USER_ID, value = LocalUserDataKeyState(wrappedKey = WRAPPED_KEY))
|
||||
|
||||
assertEquals(WRAPPED_KEY, fakeAuthDiskSource.getLocalUserDataKey(userId = USER_ID))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `setBulk should store the wrapped key for each given id`() = runTest {
|
||||
repository.setBulk(
|
||||
values = mapOf(
|
||||
USER_ID to LocalUserDataKeyState(wrappedKey = WRAPPED_KEY),
|
||||
USER_ID_2 to LocalUserDataKeyState(wrappedKey = WRAPPED_KEY_2),
|
||||
),
|
||||
)
|
||||
|
||||
assertEquals(WRAPPED_KEY, fakeAuthDiskSource.getLocalUserDataKey(userId = USER_ID))
|
||||
assertEquals(WRAPPED_KEY_2, fakeAuthDiskSource.getLocalUserDataKey(userId = USER_ID_2))
|
||||
}
|
||||
}
|
||||
|
||||
private const val USER_ID: String = "userId"
|
||||
private const val USER_ID_2: String = "userId2"
|
||||
private const val WRAPPED_KEY: String = "wrappedKey"
|
||||
private const val WRAPPED_KEY_2: String = "wrappedKey2"
|
||||
@@ -30,7 +30,7 @@ androidxRoom = "2.8.4"
|
||||
androidxSecurityCrypto = "1.1.0"
|
||||
androidxSplash = "1.2.0"
|
||||
androidxWork = "2.11.1"
|
||||
bitwardenSdk = "2.0.0-5451-c73f9161"
|
||||
bitwardenSdk = "2.0.0-5676-14521973"
|
||||
crashlytics = "3.0.6"
|
||||
detekt = "1.23.8"
|
||||
firebaseBom = "34.10.0"
|
||||
|
||||
Reference in New Issue
Block a user