[PM-12408] Updating password revision date on password change (#4044)

This commit is contained in:
aj-rosado 2024-10-09 19:09:03 +02:00 committed by GitHub
parent 57082ff7c1
commit 57d79cd51c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 109 additions and 1 deletions

View file

@ -2,6 +2,7 @@
package com.x8bit.bitwarden.ui.vault.feature.vault.util
import com.bitwarden.core.DateTime
import com.bitwarden.vault.CardView
import com.bitwarden.vault.CipherRepromptType
import com.bitwarden.vault.CipherType
@ -194,7 +195,7 @@ private fun VaultAddEditState.ViewState.Content.ItemType.toLoginView(
LoginView(
username = it.username.orNullIfBlank(),
password = it.password.orNullIfBlank(),
passwordRevisionDate = common.originalCipher?.login?.passwordRevisionDate,
passwordRevisionDate = it.getRevisionDate(common.originalCipher),
uris = it.uriList.toLoginUriView(),
totp = it.totp,
autofillOnPageLoad = common.originalCipher?.login?.autofillOnPageLoad,
@ -262,3 +263,16 @@ private fun List<UriItem>?.toLoginUriView(): List<LoginUriView>? =
?.filter { it.uri?.isNotBlank() == true }
?.map { LoginUriView(uri = it.uri.orEmpty(), match = it.match, uriChecksum = null) }
.takeUnless { it.isNullOrEmpty() }
private fun VaultAddEditState.ViewState.Content.ItemType.Login.getRevisionDate(
originalCipher: CipherView?,
): DateTime? {
val isOriginalPasswordNull = originalCipher?.login?.password.isNullOrEmpty()
val hasPasswordHistory = originalCipher?.passwordHistory?.any() ?: false
val isOriginalAndNewPasswordEqual = originalCipher?.login?.password == this.password
return if ((!isOriginalPasswordNull || hasPasswordHistory) && !isOriginalAndNewPasswordEqual) {
Instant.now()
} else {
originalCipher?.login?.passwordRevisionDate
}
}

View file

@ -25,6 +25,7 @@ import io.mockk.mockkStatic
import io.mockk.unmockkStatic
import org.junit.jupiter.api.AfterEach
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Assertions.assertNotEquals
import org.junit.jupiter.api.Test
import java.time.Instant
@ -754,6 +755,99 @@ class VaultAddItemStateExtensionsTest {
result,
)
}
@Test
fun `toLoginView should update revision date when password differs`() {
mockkStatic(Instant::class)
every { Instant.now() } returns Instant.MAX
val cipherView = DEFAULT_LOGIN_CIPHER_VIEW
val viewState = VaultAddEditState.ViewState.Content(
common = VaultAddEditState.ViewState.Content.Common(
originalCipher = cipherView,
name = "mockName-1",
favorite = true,
masterPasswordReprompt = false,
customFieldData = emptyList(),
),
isIndividualVaultDisabled = false,
type = VaultAddEditState.ViewState.Content.ItemType.Login(
username = "mockUsername-1",
password = "mockPassword-1",
),
)
val result = viewState.toCipherView()
assertNotEquals(
viewState.common.originalCipher?.login?.passwordRevisionDate,
result.login?.passwordRevisionDate,
)
}
@Test
fun `toLoginView should keep revision date when password is equal`() {
mockkStatic(Instant::class)
every { Instant.now() } returns Instant.MAX
val cipherView = DEFAULT_LOGIN_CIPHER_VIEW
val viewState = VaultAddEditState.ViewState.Content(
common = VaultAddEditState.ViewState.Content.Common(
originalCipher = cipherView,
name = "mockName-1",
favorite = true,
masterPasswordReprompt = false,
customFieldData = emptyList(),
),
isIndividualVaultDisabled = false,
type = VaultAddEditState.ViewState.Content.ItemType.Login(
username = "mockUsername-1",
password = cipherView.login?.password ?: "",
),
)
val result = viewState.toCipherView()
assertEquals(
viewState.common.originalCipher?.login?.passwordRevisionDate,
result.login?.passwordRevisionDate,
)
}
@Test
fun `toLoginView should not update revision date when password is null and has no history`() {
mockkStatic(Instant::class)
every { Instant.now() } returns Instant.MAX
val cipherView = DEFAULT_LOGIN_CIPHER_VIEW.copy(
passwordHistory = null,
login = DEFAULT_LOGIN_CIPHER_VIEW.login?.copy(password = null),
)
val viewState = VaultAddEditState.ViewState.Content(
common = VaultAddEditState.ViewState.Content.Common(
originalCipher = cipherView,
name = "mockName-1",
favorite = true,
masterPasswordReprompt = false,
customFieldData = emptyList(),
),
isIndividualVaultDisabled = false,
type = VaultAddEditState.ViewState.Content.ItemType.Login(
username = "mockUsername-1",
password = "updated password",
),
)
val result = viewState.toCipherView()
assertEquals(
viewState.common.originalCipher?.login?.passwordRevisionDate,
result.login?.passwordRevisionDate,
)
}
}
private val DEFAULT_BASE_CIPHER_VIEW: CipherView = CipherView(