Skip to content

Commit cbe13d2

Browse files
PM-31735: Add the archivedDate property to the updateCipher API (#6483)
1 parent f728c15 commit cbe13d2

File tree

7 files changed

+106
-22
lines changed

7 files changed

+106
-22
lines changed

app/src/main/kotlin/com/x8bit/bitwarden/data/vault/repository/util/VaultSdkCipherExtensions.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ fun Cipher.toEncryptedNetworkCipher(
6868
card = card?.toEncryptedNetworkCard(),
6969
key = key,
7070
sshKey = sshKey?.toEncryptedNetworkSshKey(),
71+
archivedDate = archivedDate?.let { ZonedDateTime.ofInstant(it, ZoneOffset.UTC) },
7172
encryptedFor = encryptedFor,
7273
)
7374

app/src/main/kotlin/com/x8bit/bitwarden/ui/vault/feature/addedit/VaultAddEditViewModel.kt

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -433,7 +433,10 @@ class VaultAddEditViewModel @Inject constructor(
433433
handleCreatePublicKeyCredentialRequest(
434434
request = createPublicKeyCredentialRequest,
435435
callingAppInfo = this.callingAppInfo,
436-
cipherView = content.toCipherView(clock = clock),
436+
cipherView = content.toCipherView(
437+
clock = clock,
438+
isPremiumUser = state.hasPremium,
439+
),
437440
)
438441
return@onContent
439442
}
@@ -449,7 +452,10 @@ class VaultAddEditViewModel @Inject constructor(
449452
is VaultAddEditType.EditItem -> {
450453
val result = vaultRepository.updateCipher(
451454
cipherId = vaultAddEditType.vaultItemId,
452-
cipherView = content.toCipherView(clock = clock),
455+
cipherView = content.toCipherView(
456+
clock = clock,
457+
isPremiumUser = state.hasPremium,
458+
),
453459
)
454460
sendAction(VaultAddEditAction.Internal.UpdateCipherResultReceive(result))
455461
}
@@ -695,7 +701,10 @@ class VaultAddEditViewModel @Inject constructor(
695701
handleCreatePublicKeyCredentialRequest(
696702
request = createPublicKeyCredentialRequest,
697703
callingAppInfo = request.callingAppInfo,
698-
cipherView = content.toCipherView(clock = clock),
704+
cipherView = content.toCipherView(
705+
clock = clock,
706+
isPremiumUser = state.hasPremium,
707+
),
699708
)
700709
}
701710
}
@@ -726,7 +735,10 @@ class VaultAddEditViewModel @Inject constructor(
726735
handleCreatePublicKeyCredentialRequest(
727736
request = createPublicKeyCredentialRequest,
728737
callingAppInfo = request.callingAppInfo,
729-
cipherView = content.toCipherView(clock = clock),
738+
cipherView = content.toCipherView(
739+
clock = clock,
740+
isPremiumUser = state.hasPremium,
741+
),
730742
)
731743
}
732744
}
@@ -2348,11 +2360,16 @@ class VaultAddEditViewModel @Inject constructor(
23482360
?.map { it.id }
23492361
?.let {
23502362
vaultRepository.createCipherInOrganization(
2351-
cipherView = toCipherView(clock = clock),
2363+
cipherView = toCipherView(
2364+
clock = clock,
2365+
isPremiumUser = state.hasPremium,
2366+
),
23522367
collectionIds = it,
23532368
)
23542369
}
2355-
?: vaultRepository.createCipher(cipherView = toCipherView(clock = clock))
2370+
?: vaultRepository.createCipher(
2371+
cipherView = toCipherView(clock = clock, isPremiumUser = state.hasPremium),
2372+
)
23562373
}
23572374

23582375
private fun List<VaultAddEditState.Owner>.toUpdatedOwners(

app/src/main/kotlin/com/x8bit/bitwarden/ui/vault/feature/vault/util/VaultAddItemStateExtensions.kt

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,10 @@ import java.time.Instant
2828
/**
2929
* Transforms [VaultAddEditState.ViewState.Content] into [CipherView].
3030
*/
31-
fun VaultAddEditState.ViewState.Content.toCipherView(clock: Clock): CipherView =
31+
fun VaultAddEditState.ViewState.Content.toCipherView(
32+
clock: Clock,
33+
isPremiumUser: Boolean,
34+
): CipherView =
3235
CipherView(
3336
// Pulled from original cipher when editing, otherwise uses defaults
3437
id = common.originalCipher?.id,
@@ -44,7 +47,7 @@ fun VaultAddEditState.ViewState.Content.toCipherView(clock: Clock): CipherView =
4447
creationDate = common.originalCipher?.creationDate ?: clock.instant(),
4548
deletedDate = common.originalCipher?.deletedDate,
4649
revisionDate = common.originalCipher?.revisionDate ?: clock.instant(),
47-
archivedDate = common.originalCipher?.archivedDate,
50+
archivedDate = common.originalCipher?.archivedDate?.takeIf { isPremiumUser },
4851
attachmentDecryptionFailures = common.originalCipher?.attachmentDecryptionFailures,
4952

5053
// Type specific section

app/src/test/kotlin/com/x8bit/bitwarden/data/vault/repository/util/VaultSdkCipherExtensionsTest.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ class VaultSdkCipherExtensionsTest {
8383
createMockCipherJsonRequest(
8484
number = 1,
8585
login = createMockLogin(number = 1, uri = null),
86+
archivedDate = ZonedDateTime.ofInstant(FIXED_CLOCK.instant(), ZoneOffset.UTC),
8687
),
8788
syncCipher,
8889
)
@@ -363,6 +364,7 @@ class VaultSdkCipherExtensionsTest {
363364
createMockCipherJsonRequest(
364365
number = 1,
365366
login = createMockLogin(number = 1, uri = null),
367+
archivedDate = ZonedDateTime.ofInstant(FIXED_CLOCK.instant(), ZoneOffset.UTC),
366368
),
367369
encryptionContext.toEncryptedNetworkCipher(),
368370
)

app/src/test/kotlin/com/x8bit/bitwarden/ui/vault/feature/vault/util/VaultAddItemStateExtensionsTest.kt

Lines changed: 68 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ class VaultAddItemStateExtensionsTest {
6060
),
6161
)
6262

63-
val result = loginItemType.toCipherView(clock = FIXED_CLOCK)
63+
val result = loginItemType.toCipherView(clock = FIXED_CLOCK, isPremiumUser = true)
6464

6565
assertEquals(
6666
CipherView(
@@ -146,7 +146,7 @@ class VaultAddItemStateExtensionsTest {
146146
),
147147
)
148148

149-
val result = viewState.toCipherView(clock = FIXED_CLOCK)
149+
val result = viewState.toCipherView(clock = FIXED_CLOCK, isPremiumUser = true)
150150

151151
assertEquals(
152152
@Suppress("MaxLineLength")
@@ -238,7 +238,7 @@ class VaultAddItemStateExtensionsTest {
238238
type = VaultAddEditState.ViewState.Content.ItemType.SecureNotes,
239239
)
240240

241-
val result = viewState.toCipherView(clock = FIXED_CLOCK)
241+
val result = viewState.toCipherView(clock = FIXED_CLOCK, isPremiumUser = true)
242242

243243
assertEquals(
244244
CipherView(
@@ -312,7 +312,7 @@ class VaultAddItemStateExtensionsTest {
312312
type = VaultAddEditState.ViewState.Content.ItemType.SecureNotes,
313313
)
314314

315-
val result = viewState.toCipherView(clock = FIXED_CLOCK)
315+
val result = viewState.toCipherView(clock = FIXED_CLOCK, isPremiumUser = true)
316316

317317
assertEquals(
318318
cipherView.copy(
@@ -369,7 +369,7 @@ class VaultAddItemStateExtensionsTest {
369369
),
370370
)
371371

372-
val result = viewState.toCipherView(clock = FIXED_CLOCK)
372+
val result = viewState.toCipherView(clock = FIXED_CLOCK, isPremiumUser = true)
373373

374374
assertEquals(
375375
CipherView(
@@ -471,7 +471,7 @@ class VaultAddItemStateExtensionsTest {
471471
),
472472
)
473473

474-
val result = viewState.toCipherView(clock = FIXED_CLOCK)
474+
val result = viewState.toCipherView(clock = FIXED_CLOCK, isPremiumUser = true)
475475

476476
assertEquals(
477477
@Suppress("MaxLineLength")
@@ -566,7 +566,7 @@ class VaultAddItemStateExtensionsTest {
566566
),
567567
)
568568

569-
val result = viewState.toCipherView(clock = FIXED_CLOCK)
569+
val result = viewState.toCipherView(clock = FIXED_CLOCK, isPremiumUser = true)
570570

571571
assertEquals(
572572
CipherView(
@@ -644,7 +644,7 @@ class VaultAddItemStateExtensionsTest {
644644
),
645645
)
646646

647-
val result = viewState.toCipherView(clock = FIXED_CLOCK)
647+
val result = viewState.toCipherView(clock = FIXED_CLOCK, isPremiumUser = true)
648648

649649
assertEquals(
650650
cipherView.copy(
@@ -714,7 +714,7 @@ class VaultAddItemStateExtensionsTest {
714714
),
715715
)
716716

717-
val result = viewState.toCipherView(clock = FIXED_CLOCK)
717+
val result = viewState.toCipherView(clock = FIXED_CLOCK, isPremiumUser = true)
718718

719719
assertEquals(
720720
CipherView(
@@ -755,6 +755,60 @@ class VaultAddItemStateExtensionsTest {
755755
)
756756
}
757757

758+
@Suppress("MaxLineLength")
759+
@Test
760+
fun `toCipherView without premium should delete the archive date from the original cipher`() {
761+
val cipherView = DEFAULT_BASE_CIPHER_VIEW.copy(
762+
notes = null,
763+
fields = emptyList(),
764+
login = LoginView(
765+
username = "mockUsername-1",
766+
password = "mockPassword-1",
767+
passwordRevisionDate = FIXED_CLOCK.instant(),
768+
uris = null,
769+
totp = null,
770+
autofillOnPageLoad = false,
771+
fido2Credentials = createMockSdkFido2CredentialList(1),
772+
),
773+
archivedDate = FIXED_CLOCK.instant(),
774+
)
775+
776+
val viewState = VaultAddEditState.ViewState.Content(
777+
common = VaultAddEditState.ViewState.Content.Common(
778+
originalCipher = cipherView,
779+
name = "mockName-1",
780+
customFieldData = emptyList(),
781+
masterPasswordReprompt = true,
782+
),
783+
isIndividualVaultDisabled = false,
784+
type = VaultAddEditState.ViewState.Content.ItemType.Login(
785+
username = "mockUsername-1",
786+
password = "mockPassword-1",
787+
totp = null,
788+
fido2CredentialCreationDateTime = null,
789+
),
790+
)
791+
792+
val result = viewState.toCipherView(clock = FIXED_CLOCK, isPremiumUser = false)
793+
794+
assertEquals(
795+
cipherView.copy(
796+
name = "mockName-1",
797+
login = LoginView(
798+
username = "mockUsername-1",
799+
password = "mockPassword-1",
800+
totp = null,
801+
fido2Credentials = null,
802+
uris = null,
803+
passwordRevisionDate = FIXED_CLOCK.instant(),
804+
autofillOnPageLoad = false,
805+
),
806+
archivedDate = null,
807+
),
808+
result,
809+
)
810+
}
811+
758812
@Suppress("MaxLineLength")
759813
@Test
760814
fun `toLoginView should transform Login ItemType to LoginView deleting fido2Credentials with original cipher`() {
@@ -789,7 +843,7 @@ class VaultAddItemStateExtensionsTest {
789843
),
790844
)
791845

792-
val result = viewState.toCipherView(clock = FIXED_CLOCK)
846+
val result = viewState.toCipherView(clock = FIXED_CLOCK, isPremiumUser = true)
793847

794848
assertEquals(
795849
cipherView.copy(
@@ -833,7 +887,7 @@ class VaultAddItemStateExtensionsTest {
833887

834888
// We need to pass in a future clock to make sure that when the
835889
// revision date is updated it is updated to a new time
836-
val result = viewState.toCipherView(clock = futureClock)
890+
val result = viewState.toCipherView(clock = futureClock, isPremiumUser = true)
837891

838892
assertNotEquals(
839893
viewState.common.originalCipher?.login?.passwordRevisionDate,
@@ -866,7 +920,7 @@ class VaultAddItemStateExtensionsTest {
866920

867921
// We need to pass in a future clock to make sure that if the
868922
// revision date were to be updated it would be updated to a new time
869-
val result = viewState.toCipherView(clock = futureClock)
923+
val result = viewState.toCipherView(clock = futureClock, isPremiumUser = true)
870924

871925
assertEquals(
872926
viewState.common.originalCipher?.login?.passwordRevisionDate,
@@ -902,7 +956,7 @@ class VaultAddItemStateExtensionsTest {
902956

903957
// We need to pass in a future clock to make sure that if the
904958
// revision date were to be updated it would be updated to a new time
905-
val result = viewState.toCipherView(clock = futureClock)
959+
val result = viewState.toCipherView(clock = futureClock, isPremiumUser = true)
906960

907961
assertEquals(
908962
viewState.common.originalCipher?.login?.passwordRevisionDate,
@@ -978,7 +1032,7 @@ private val DEFAULT_BASE_CIPHER_VIEW: CipherView = CipherView(
9781032
creationDate = FIXED_CLOCK.instant(),
9791033
deletedDate = null,
9801034
revisionDate = FIXED_CLOCK.instant(),
981-
archivedDate = null,
1035+
archivedDate = FIXED_CLOCK.instant(),
9821036
sshKey = null,
9831037
attachmentDecryptionFailures = null,
9841038
)

network/src/main/kotlin/com/bitwarden/network/model/CipherJsonRequest.kt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import java.time.ZonedDateTime
2323
* @property isFavorite If the cipher is a favorite.
2424
* @property card The card of the cipher.
2525
* @property key The key of the cipher (nullable).
26+
* @property archivedDate The archived date of the cipher (nullable).
2627
* @property encryptedFor ID of the user who the cipher is encrypted by.
2728
*/
2829
@Serializable
@@ -79,6 +80,10 @@ data class CipherJsonRequest(
7980
@SerialName("key")
8081
val key: String?,
8182

83+
@SerialName("archivedDate")
84+
@Contextual
85+
val archivedDate: ZonedDateTime?,
86+
8287
@SerialName("encryptedFor")
8388
val encryptedFor: String?,
8489
)

network/src/testFixtures/kotlin/com/bitwarden/network/model/CipherJsonRequestUtil.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ fun createMockCipherJsonRequest(
2929
reprompt: CipherRepromptTypeJson = CipherRepromptTypeJson.NONE,
3030
lastKnownRevisionDate: ZonedDateTime? = ZonedDateTime.parse("2023-10-27T12:00:00Z"),
3131
key: String? = "mockKey-$number",
32+
archivedDate: ZonedDateTime? = ZonedDateTime.parse("2023-10-27T12:00:00Z"),
3233
encryptedFor: String? = "mockEncryptedFor-$number",
3334
): CipherJsonRequest =
3435
CipherJsonRequest(
@@ -49,5 +50,6 @@ fun createMockCipherJsonRequest(
4950
reprompt = reprompt,
5051
lastKnownRevisionDate = lastKnownRevisionDate,
5152
key = key,
53+
archivedDate = archivedDate,
5254
encryptedFor = encryptedFor,
5355
)

0 commit comments

Comments
 (0)