mirror of
https://github.com/bitwarden/android.git
synced 2025-01-07 08:47:36 +03:00
overlay offline edits with existing
This commit is contained in:
parent
d7b935031e
commit
b30e52245f
4 changed files with 77 additions and 5 deletions
|
@ -19,10 +19,12 @@ import com.x8bit.bitwarden.data.vault.datasource.network.model.OfflineCipherJson
|
|||
import com.x8bit.bitwarden.data.vault.datasource.network.model.SyncResponseJson
|
||||
import com.x8bit.bitwarden.data.vault.repository.util.toOfflineCipher
|
||||
import com.x8bit.bitwarden.data.vault.repository.util.toOfflineCipherJson
|
||||
import com.x8bit.bitwarden.data.vault.repository.util.toSdkCipherJson
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.awaitAll
|
||||
import kotlinx.coroutines.coroutineScope
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.combine
|
||||
import kotlinx.coroutines.flow.first
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.flow.merge
|
||||
|
@ -83,7 +85,6 @@ class VaultDiskSourceImpl(
|
|||
)
|
||||
}
|
||||
|
||||
|
||||
override fun getOfflineCiphers(
|
||||
userId: String,
|
||||
): Flow<List<OfflineCipherJson>> =
|
||||
|
@ -130,6 +131,16 @@ class VaultDiskSourceImpl(
|
|||
.awaitAll()
|
||||
}
|
||||
},
|
||||
).combine(
|
||||
getOfflineCiphers(userId),
|
||||
{ ciphers, offlineCiphers ->
|
||||
val overlaid = ciphers.map { cipher ->
|
||||
offlineCiphers.find { it.id == cipher.id }?.toSdkCipherJson() ?: cipher
|
||||
}
|
||||
// TODO add new offline items to the vault list
|
||||
// val newOffline = offlineCiphers.filter { it.id.startsWith("create") }.map { it.toSdkCipherJson() }
|
||||
overlaid
|
||||
}
|
||||
)
|
||||
|
||||
override suspend fun deleteCipher(userId: String, cipherId: String) {
|
||||
|
|
|
@ -87,6 +87,5 @@ data class OfflineCipherJson(
|
|||
@SerialName("mergeConflict")
|
||||
val mergeConflict: Boolean
|
||||
|
||||
){
|
||||
// TODO: Add password history, fields, etc
|
||||
) {
|
||||
}
|
|
@ -28,6 +28,7 @@ import com.bitwarden.vault.SecureNoteType
|
|||
import com.bitwarden.vault.SecureNoteView
|
||||
import com.bitwarden.vault.UriMatchType
|
||||
import com.x8bit.bitwarden.data.platform.util.SpecialCharWithPrecedenceComparator
|
||||
import com.x8bit.bitwarden.data.platform.util.isFdroid
|
||||
import com.x8bit.bitwarden.data.vault.datasource.network.model.AttachmentJsonRequest
|
||||
import com.x8bit.bitwarden.data.vault.datasource.network.model.CipherJsonRequest
|
||||
import com.x8bit.bitwarden.data.vault.datasource.network.model.CipherRepromptTypeJson
|
||||
|
@ -41,6 +42,7 @@ import com.x8bit.bitwarden.data.vault.datasource.network.model.UriMatchTypeJson
|
|||
import com.x8bit.bitwarden.data.vault.datasource.sdk.model.OfflineCipher
|
||||
import com.x8bit.bitwarden.data.vault.repository.model.OfflineCipherView
|
||||
import com.x8bit.bitwarden.ui.vault.feature.vault.model.NotificationSummary
|
||||
import kotlinx.coroutines.flow.merge
|
||||
import java.time.ZoneOffset
|
||||
import java.time.ZonedDateTime
|
||||
import java.util.UUID
|
||||
|
@ -118,7 +120,7 @@ fun OfflineCipher.toOfflineCipherJson(id: String): OfflineCipherJson =
|
|||
creationDate = ZonedDateTime.ofInstant(creationDate, ZoneOffset.UTC),
|
||||
deletedDate = deletedDate?.let { ZonedDateTime.ofInstant(deletedDate, ZoneOffset.UTC) },
|
||||
revisionDate = ZonedDateTime.ofInstant(creationDate, ZoneOffset.UTC),
|
||||
mergeConflict = false, // TODO: Copy from the new OfflineCipher type
|
||||
mergeConflict = mergeConflict,
|
||||
)
|
||||
|
||||
fun OfflineCipherView.toNotificationSummary(): NotificationSummary =
|
||||
|
@ -159,6 +161,60 @@ fun CipherView.toOfflineCipherView(offlineCipher: OfflineCipher) =
|
|||
mergeConflict = offlineCipher.mergeConflict
|
||||
)
|
||||
|
||||
fun SyncResponseJson.Cipher.overlayOfflineCipherJson(offlineCipherJson: OfflineCipherJson) =
|
||||
SyncResponseJson.Cipher(
|
||||
notes = offlineCipherJson.notes,
|
||||
attachments = offlineCipherJson.attachments,
|
||||
shouldOrganizationUseTotp = shouldOrganizationUseTotp,
|
||||
reprompt = offlineCipherJson.reprompt,
|
||||
shouldEdit = shouldEdit,
|
||||
passwordHistory = offlineCipherJson.passwordHistory,
|
||||
revisionDate = offlineCipherJson.revisionDate,
|
||||
type = offlineCipherJson.type,
|
||||
login = offlineCipherJson.login,
|
||||
creationDate = offlineCipherJson.creationDate,
|
||||
secureNote = offlineCipherJson.secureNote,
|
||||
folderId = offlineCipherJson.folderId,
|
||||
organizationId = offlineCipherJson.organizationId,
|
||||
deletedDate = offlineCipherJson.deletedDate,
|
||||
identity = offlineCipherJson.identity,
|
||||
collectionIds = offlineCipherJson.collectionIds,
|
||||
name = offlineCipherJson.name,
|
||||
id = id,
|
||||
fields = offlineCipherJson.fields,
|
||||
shouldViewPassword = shouldViewPassword,
|
||||
isFavorite = offlineCipherJson.favorite,
|
||||
card = offlineCipherJson.card,
|
||||
key = offlineCipherJson.key
|
||||
)
|
||||
|
||||
fun OfflineCipherJson.toSdkCipherJson(): SyncResponseJson.Cipher =
|
||||
SyncResponseJson.Cipher(
|
||||
id = id, // TODO, the "create_..." id is invalid, but it's not clear what's better
|
||||
notes = notes,
|
||||
attachments = attachments,
|
||||
shouldOrganizationUseTotp = false, // TODO
|
||||
reprompt = reprompt,
|
||||
shouldEdit = false, // TODO
|
||||
passwordHistory = passwordHistory,
|
||||
revisionDate = revisionDate,
|
||||
type = type,
|
||||
login = login,
|
||||
creationDate = creationDate,
|
||||
secureNote = secureNote,
|
||||
folderId = folderId,
|
||||
organizationId = organizationId,
|
||||
deletedDate = deletedDate,
|
||||
identity = identity,
|
||||
collectionIds = collectionIds,
|
||||
name = name,
|
||||
fields = fields,
|
||||
shouldViewPassword = false, // TODO
|
||||
isFavorite = favorite,
|
||||
card = card,
|
||||
key = key,
|
||||
)
|
||||
|
||||
fun OfflineCipherJson.toOfflineCipher(): OfflineCipher =
|
||||
OfflineCipher(
|
||||
id = if (id.startsWith("create")) null else id,
|
||||
|
|
|
@ -412,10 +412,16 @@ class VaultAddEditViewModel @Inject constructor(
|
|||
}
|
||||
|
||||
is VaultAddEditType.EditItem -> {
|
||||
val result = vaultRepository.updateCipher(
|
||||
var result = vaultRepository.updateCipher(
|
||||
cipherId = vaultAddEditType.vaultItemId,
|
||||
cipherView = content.toCipherView(),
|
||||
)
|
||||
|
||||
if (result is UpdateCipherResult.Error) {
|
||||
// TODO: Ask for permission to store locally
|
||||
result = vaultRepository.updateOfflineCipher(cipherId = vaultAddEditType.vaultItemId, cipherView = content.toCipherView())
|
||||
}
|
||||
|
||||
sendAction(VaultAddEditAction.Internal.UpdateCipherResultReceive(result))
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue