PM-38358: Chore: Remove user key#7004
Conversation
…erKeyWrappedUserKey
🤖 Bitwarden Claude Code ReviewOverall Assessment: APPROVE This PR removes the legacy stored encrypted user key ( Code Review DetailsNo findings. The removed-key fallback path is consistent with |
526a537 to
cd9dc77
Compare
| ?.copy(hasMasterPassword = false) | ||
| ?.copy( | ||
| hasMasterPassword = false, | ||
| masterPasswordUnlock = null, |
There was a problem hiding this comment.
This change ensures that masterPasswordUnlock is cleared as well to avoid any future confusion.
| ?.copy(masterPasswordUnlock = syncUserDecryption.masterPasswordUnlock) | ||
| ?.copy( | ||
| hasMasterPassword = syncUserDecryption.masterPasswordUnlock != null, | ||
| masterPasswordUnlock = syncUserDecryption.masterPasswordUnlock, |
There was a problem hiding this comment.
And this ensures that both code pathways are consistent regardless of whether the userDecryptionOptions are present or not.
| @@ -56,6 +60,13 @@ class AuthDiskSourceTest { | |||
| verify(exactly = 1) { legacySecureStorageMigrator.migrateIfNecessary() } | |||
| } | |||
|
|
|||
| @Test | |||
| fun `initialization should trigger a legacy user key removal`() { | |||
| assertNull( | |||
| fakeSharedPreferences.getString("bwPreferencesStorage:masterKeyEncryptedUserKey", null), | |||
| ) | |||
| } | |||
There was a problem hiding this comment.
removeLegacyUserKeys() runs — it would pass even if the cleanup were deleted.
Details and fix
The legacy user key was stored in the non-encrypted sharedPreferences (see MASTER_KEY_ENCRYPTION_USER_KEY in the "should not be encrypted" group, and getUserKey/storeUserKey previously used getString/putString). removeLegacyUserKeys() calls removeWithPrefix(...), which only iterates sharedPreferences — not the encrypted one.
However, the seed here puts the key into fakeEncryptedSharedPreferences (which is wired as encryptedSharedPreferences), and the assertion then reads from fakeSharedPreferences, which was never populated. The assertion would be vacuously true even if removeLegacyUserKeys() were never called.
Suggested fix — seed the key into the same prefs object that removeWithPrefix operates on:
private val fakeEncryptedSharedPreferences = FakeSharedPreferences()
private val fakeSharedPreferences = FakeSharedPreferences().apply {
edit(commit = true) {
putString("bwPreferencesStorage:masterKeyEncryptedUserKey_userId", "testUserKey")
}
}And then the assertion at line 64-68 will actually verify the removal happened.
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #7004 +/- ##
==========================================
- Coverage 86.49% 86.06% -0.43%
==========================================
Files 873 953 +80
Lines 63852 65902 +2050
Branches 9248 9298 +50
==========================================
+ Hits 55229 56719 +1490
- Misses 5439 5979 +540
- Partials 3184 3204 +20
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
cd9dc77 to
c4e42f3
Compare
🎟️ Tracking
PM-38358
📔 Objective
This PR removes the stored encrypted user key from shared preferences and updates the remaining location that relied on it.