mirror of
https://github.com/bitwarden/android.git
synced 2026-10-22 02:53:19 -05:00
Update SDK to 3.0.0-8671-5d8ae614 (#7320)
Co-authored-by: bw-ghapp[bot] <178206702+bw-ghapp[bot]@users.noreply.github.com>
This commit is contained in:
1 parent
b1d6d6b513
commit
6f325dd192
7 files changed
+187
-1
No files matched your search
@@ -431,4 +431,23 @@ interface AuthDiskSource : AppIdProvider {
|
||||
* Stores the v2 upgrade token for the given [userId].
|
||||
*/
|
||||
fun storeV2UpgradeToken(userId: String, v2UpgradeToken: V2UpgradeTokenJson?)
|
||||
|
||||
/**
|
||||
* Gets the start of the v2 encrypted migrations grace period for the given [userId].
|
||||
*
|
||||
* This value is retained across logout and lock and is only removed when explicitly stored as
|
||||
* `null`.
|
||||
*/
|
||||
fun getV2EncryptedMigrationsGracePeriodStart(userId: String): Instant?
|
||||
|
||||
/**
|
||||
* Stores the start of the v2 encrypted migrations grace period for the given [userId].
|
||||
*
|
||||
* This value is retained across logout and lock and is only removed when explicitly stored as
|
||||
* `null`.
|
||||
*/
|
||||
fun storeV2EncryptedMigrationsGracePeriodStart(
|
||||
userId: String,
|
||||
gracePeriodStart: Instant?,
|
||||
)
|
||||
}
|
||||
+17
@@ -62,6 +62,8 @@ private const val LAST_LOCK_TIMESTAMP = "lastLockTimestamp"
|
||||
private const val PROFILE_ACCOUNT_KEYS_KEY = "profileAccountKeys"
|
||||
private const val V2_UPGRADE_TOKEN = "v2UpgradeToken"
|
||||
private const val USER_KEY_ID_KEY = "userKeyId"
|
||||
private const val V2_ENCRYPTED_MIGRATIONS_GRACE_PERIOD_START =
|
||||
"v2EncryptedMigrationsGracePeriodStart"
|
||||
|
||||
/**
|
||||
* Primary implementation of [AuthDiskSource].
|
||||
@@ -208,6 +210,7 @@ class AuthDiskSourceImpl(
|
||||
// * DeviceKey
|
||||
// * PendingAuthRequest
|
||||
// * OnboardingStatus
|
||||
// * V2EncryptedMigrationsGracePeriodStart
|
||||
}
|
||||
|
||||
override fun getAuthenticatorSyncUnlockKey(userId: String): String? =
|
||||
@@ -632,6 +635,20 @@ class AuthDiskSourceImpl(
|
||||
)
|
||||
}
|
||||
|
||||
override fun getV2EncryptedMigrationsGracePeriodStart(userId: String): Instant? =
|
||||
getLong(key = V2_ENCRYPTED_MIGRATIONS_GRACE_PERIOD_START.appendIdentifier(userId))
|
||||
?.let { Instant.ofEpochMilli(it) }
|
||||
|
||||
override fun storeV2EncryptedMigrationsGracePeriodStart(
|
||||
userId: String,
|
||||
gracePeriodStart: Instant?,
|
||||
) {
|
||||
putLong(
|
||||
key = V2_ENCRYPTED_MIGRATIONS_GRACE_PERIOD_START.appendIdentifier(userId),
|
||||
value = gracePeriodStart?.toEpochMilli(),
|
||||
)
|
||||
}
|
||||
|
||||
private fun generateAndStoreUniqueAppId(): String =
|
||||
UUID
|
||||
.randomUUID()
|
||||
|
||||
+18
@@ -17,6 +17,7 @@ import com.x8bit.bitwarden.data.auth.repository.util.updateMasterPasswordUnlock
|
||||
import com.x8bit.bitwarden.data.vault.repository.util.toSdkMasterPasswordUnlock
|
||||
import com.x8bit.bitwarden.data.vault.repository.util.toV2UpgradeToken
|
||||
import com.x8bit.bitwarden.data.vault.repository.util.toV2UpgradeTokenJson
|
||||
import java.time.Instant
|
||||
|
||||
/**
|
||||
* A user-scoped implementation of a Bitwarden SDK [StateBridgeForeignImpl].
|
||||
@@ -167,6 +168,23 @@ internal class SdkStateBridge(
|
||||
)
|
||||
}
|
||||
|
||||
override suspend fun setV2EncryptedMigrationsGracePeriodStart(value: Instant) {
|
||||
authDiskSource.storeV2EncryptedMigrationsGracePeriodStart(
|
||||
userId = userId,
|
||||
gracePeriodStart = value,
|
||||
)
|
||||
}
|
||||
|
||||
override suspend fun getV2EncryptedMigrationsGracePeriodStart(): Instant? =
|
||||
authDiskSource.getV2EncryptedMigrationsGracePeriodStart(userId = userId)
|
||||
|
||||
override suspend fun clearV2EncryptedMigrationsGracePeriodStart() {
|
||||
authDiskSource.storeV2EncryptedMigrationsGracePeriodStart(
|
||||
userId = userId,
|
||||
gracePeriodStart = null,
|
||||
)
|
||||
}
|
||||
|
||||
override suspend fun getWebauthnPrfUnlockData(): WebAuthnPrfUnlockData? {
|
||||
// We do not support unlock with WebAuthn, so we can just return null
|
||||
return null
|
||||
|
||||
+64
@@ -378,6 +378,11 @@ class AuthDiskSourceTest {
|
||||
),
|
||||
)
|
||||
authDiskSource.storeUserKeyId(userId = userId, userKeyId = "userKeyId")
|
||||
val gracePeriodStart = Instant.parse("2025-01-13T12:00:00Z")
|
||||
authDiskSource.storeV2EncryptedMigrationsGracePeriodStart(
|
||||
userId = userId,
|
||||
gracePeriodStart = gracePeriodStart,
|
||||
)
|
||||
|
||||
authDiskSource.clearData(userId = userId)
|
||||
|
||||
@@ -389,6 +394,10 @@ class AuthDiskSourceTest {
|
||||
OnboardingStatus.AUTOFILL_SETUP,
|
||||
authDiskSource.getOnboardingStatus(userId = userId),
|
||||
)
|
||||
assertEquals(
|
||||
gracePeriodStart,
|
||||
authDiskSource.getV2EncryptedMigrationsGracePeriodStart(userId = userId),
|
||||
)
|
||||
|
||||
// These should be cleared
|
||||
assertNull(authDiskSource.getUserBiometricInitVector(userId = userId))
|
||||
@@ -1557,6 +1566,61 @@ class AuthDiskSourceTest {
|
||||
val actual = authDiskSource.getLastLockTimestamp(userId = mockUserId)
|
||||
assertNull(actual)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `getV2EncryptedMigrationsGracePeriodStart should pull from SharedPreferences`() {
|
||||
val storeKey = "bwPreferencesStorage:v2EncryptedMigrationsGracePeriodStart"
|
||||
val mockUserId = "mockUserId"
|
||||
val expectedState = Instant.parse("2025-01-13T12:00:00Z")
|
||||
fakeSharedPreferences.edit {
|
||||
putLong("${storeKey}_$mockUserId", expectedState.toEpochMilli())
|
||||
}
|
||||
|
||||
val actual = authDiskSource.getV2EncryptedMigrationsGracePeriodStart(userId = mockUserId)
|
||||
|
||||
assertEquals(expectedState, actual)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `getV2EncryptedMigrationsGracePeriodStart should pull null when there is no data`() {
|
||||
val mockUserId = "mockUserId"
|
||||
|
||||
val actual = authDiskSource.getV2EncryptedMigrationsGracePeriodStart(userId = mockUserId)
|
||||
|
||||
assertNull(actual)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `storeV2EncryptedMigrationsGracePeriodStart should update SharedPreferences`() {
|
||||
val mockUserId = "mockUserId"
|
||||
val expectedState = Instant.parse("2025-01-13T12:00:00Z")
|
||||
|
||||
authDiskSource.storeV2EncryptedMigrationsGracePeriodStart(
|
||||
userId = mockUserId,
|
||||
gracePeriodStart = expectedState,
|
||||
)
|
||||
|
||||
assertEquals(
|
||||
expectedState,
|
||||
authDiskSource.getV2EncryptedMigrationsGracePeriodStart(userId = mockUserId),
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `storeV2EncryptedMigrationsGracePeriodStart should clear the value when null is passed`() {
|
||||
val mockUserId = "mockUserId"
|
||||
authDiskSource.storeV2EncryptedMigrationsGracePeriodStart(
|
||||
userId = mockUserId,
|
||||
gracePeriodStart = Instant.parse("2025-01-13T12:00:00Z"),
|
||||
)
|
||||
|
||||
authDiskSource.storeV2EncryptedMigrationsGracePeriodStart(
|
||||
userId = mockUserId,
|
||||
gracePeriodStart = null,
|
||||
)
|
||||
|
||||
assertNull(authDiskSource.getV2EncryptedMigrationsGracePeriodStart(userId = mockUserId))
|
||||
}
|
||||
}
|
||||
|
||||
private const val USER_STATE_JSON = """
|
||||
|
||||
+24
@@ -74,6 +74,7 @@ class FakeAuthDiskSource : AuthDiskSource {
|
||||
mutableMapOf<String, MutableSharedFlow<String?>>()
|
||||
private val storedV2UpgradeTokens = mutableMapOf<String, V2UpgradeTokenJson?>()
|
||||
private val storedUserKeyIds = mutableMapOf<String, String?>()
|
||||
private val storedV2EncryptedMigrationsGracePeriodStarts = mutableMapOf<String, Instant?>()
|
||||
|
||||
override var userState: UserStateJson? = null
|
||||
set(value) {
|
||||
@@ -109,6 +110,12 @@ class FakeAuthDiskSource : AuthDiskSource {
|
||||
mutableAccountTokensFlowMap.remove(userId)
|
||||
mutableEphemeralPinProtectedUserKeyEnvelopesFlowMap.remove(userId)
|
||||
mutablePersistentPinProtectedUserKeyEnvelopesFlowMap.remove(userId)
|
||||
|
||||
// Certain values are never removed as required by the feature requirements:
|
||||
// * DeviceKey
|
||||
// * PendingAuthRequest
|
||||
// * OnboardingStatus
|
||||
// * V2EncryptedMigrationsGracePeriodStart
|
||||
}
|
||||
|
||||
override fun getShouldUseKeyConnectorFlow(
|
||||
@@ -178,6 +185,16 @@ class FakeAuthDiskSource : AuthDiskSource {
|
||||
storedV2UpgradeTokens[userId] = v2UpgradeToken
|
||||
}
|
||||
|
||||
override fun getV2EncryptedMigrationsGracePeriodStart(userId: String): Instant? =
|
||||
storedV2EncryptedMigrationsGracePeriodStarts[userId]
|
||||
|
||||
override fun storeV2EncryptedMigrationsGracePeriodStart(
|
||||
userId: String,
|
||||
gracePeriodStart: Instant?,
|
||||
) {
|
||||
storedV2EncryptedMigrationsGracePeriodStarts[userId] = gracePeriodStart
|
||||
}
|
||||
|
||||
override fun getTwoFactorToken(email: String): String? = storedTwoFactorTokens[email]
|
||||
|
||||
override fun storeTwoFactorToken(email: String, twoFactorToken: String?) {
|
||||
@@ -471,6 +488,13 @@ class FakeAuthDiskSource : AuthDiskSource {
|
||||
assertEquals(v2UpgradeToken, storedV2UpgradeTokens[userId])
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert that the [gracePeriodStart] was stored successfully using the [userId].
|
||||
*/
|
||||
fun assertV2EncryptedMigrationsGracePeriodStart(userId: String, gracePeriodStart: Instant?) {
|
||||
assertEquals(gracePeriodStart, storedV2EncryptedMigrationsGracePeriodStarts[userId])
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert that the [twoFactorToken] was stored successfully using the [email].
|
||||
*/
|
||||
|
||||
+44
@@ -214,6 +214,48 @@ class SdkStateBridgeTest {
|
||||
authDiskSource.assertV2UpgradeToken(userId = USER_ID, v2UpgradeToken = null)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `setV2EncryptedMigrationsGracePeriodStart should store the grace period start`() = runTest {
|
||||
stateBridge.setV2EncryptedMigrationsGracePeriodStart(value = GRACE_PERIOD_START)
|
||||
|
||||
authDiskSource.assertV2EncryptedMigrationsGracePeriodStart(
|
||||
userId = USER_ID,
|
||||
gracePeriodStart = GRACE_PERIOD_START,
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `getV2EncryptedMigrationsGracePeriodStart should return the stored grace period start`() =
|
||||
runTest {
|
||||
assertNull(stateBridge.getV2EncryptedMigrationsGracePeriodStart())
|
||||
|
||||
authDiskSource.storeV2EncryptedMigrationsGracePeriodStart(
|
||||
userId = USER_ID,
|
||||
gracePeriodStart = GRACE_PERIOD_START,
|
||||
)
|
||||
|
||||
assertEquals(
|
||||
GRACE_PERIOD_START,
|
||||
stateBridge.getV2EncryptedMigrationsGracePeriodStart(),
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clearV2EncryptedMigrationsGracePeriodStart should clear the grace period start`() =
|
||||
runTest {
|
||||
authDiskSource.storeV2EncryptedMigrationsGracePeriodStart(
|
||||
userId = USER_ID,
|
||||
gracePeriodStart = GRACE_PERIOD_START,
|
||||
)
|
||||
|
||||
stateBridge.clearV2EncryptedMigrationsGracePeriodStart()
|
||||
|
||||
authDiskSource.assertV2EncryptedMigrationsGracePeriodStart(
|
||||
userId = USER_ID,
|
||||
gracePeriodStart = null,
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `setAccountCryptographicState should store the account cryptographic state`() = runTest {
|
||||
val state = createMockWrappedAccountCryptographicState(number = 1)
|
||||
@@ -493,6 +535,8 @@ private val V2_UPGRADE_TOKEN_JSON: V2UpgradeTokenJson = V2UpgradeTokenJson(
|
||||
wrappedUserKey2 = "wrappedUserKey2",
|
||||
)
|
||||
|
||||
private val GRACE_PERIOD_START: Instant = Instant.parse("2024-09-13T01:00:00.00Z")
|
||||
|
||||
private val MASTER_PASSWORD_UNLOCK_DATA: MasterPasswordUnlockData = MasterPasswordUnlockData(
|
||||
kdf = Kdf.Pbkdf2(iterations = 600_000u),
|
||||
masterKeyWrappedUserKey = "masterKeyWrappedUserKey",
|
||||
|
||||
@@ -29,7 +29,7 @@ androidxRoom = "2.8.4"
|
||||
androidxSecurityCrypto = "1.1.0"
|
||||
androidxSplash = "1.2.0"
|
||||
androidxWork = "2.11.2"
|
||||
bitwardenSdk = "3.0.0-8495-c1b859a9"
|
||||
bitwardenSdk = "3.0.0-8671-5d8ae614"
|
||||
crashlytics = "3.0.8"
|
||||
detekt = "1.23.8"
|
||||
firebaseBom = "34.18.0"
|
||||
|
||||
Reference in new issue
Block a user