mirror of
https://github.com/bitwarden/android.git
synced 2025-01-07 08:47:36 +03:00
wip
This commit is contained in:
parent
425b085a96
commit
028d382a5b
5 changed files with 110 additions and 18 deletions
|
@ -22,6 +22,7 @@ import com.x8bit.bitwarden.data.vault.repository.model.DeleteSendResult
|
|||
import com.x8bit.bitwarden.data.vault.repository.model.DomainsData
|
||||
import com.x8bit.bitwarden.data.vault.repository.model.ExportVaultDataResult
|
||||
import com.x8bit.bitwarden.data.vault.repository.model.GenerateTotpResult
|
||||
import com.x8bit.bitwarden.data.vault.repository.model.OfflineCipherView
|
||||
import com.x8bit.bitwarden.data.vault.repository.model.RemovePasswordSendResult
|
||||
import com.x8bit.bitwarden.data.vault.repository.model.SendData
|
||||
import com.x8bit.bitwarden.data.vault.repository.model.SyncVaultDataResult
|
||||
|
@ -62,7 +63,7 @@ interface VaultRepository : CipherManager, VaultLockManager {
|
|||
* Note that the [StateFlow.value] will return the last known value but the [StateFlow] itself
|
||||
* must be collected in order to trigger state changes.
|
||||
*/
|
||||
val offlineCiphersStateFlow: StateFlow<DataState<List<CipherView>>>
|
||||
val offlineCiphersStateFlow: StateFlow<DataState<List<OfflineCipherView>>>
|
||||
/**
|
||||
* Flow that represents all ciphers for the active user.
|
||||
*
|
||||
|
|
|
@ -63,6 +63,7 @@ import com.x8bit.bitwarden.data.vault.repository.model.DeleteSendResult
|
|||
import com.x8bit.bitwarden.data.vault.repository.model.DomainsData
|
||||
import com.x8bit.bitwarden.data.vault.repository.model.ExportVaultDataResult
|
||||
import com.x8bit.bitwarden.data.vault.repository.model.GenerateTotpResult
|
||||
import com.x8bit.bitwarden.data.vault.repository.model.OfflineCipherView
|
||||
import com.x8bit.bitwarden.data.vault.repository.model.RemovePasswordSendResult
|
||||
import com.x8bit.bitwarden.data.vault.repository.model.SendData
|
||||
import com.x8bit.bitwarden.data.vault.repository.model.SyncVaultDataResult
|
||||
|
@ -83,6 +84,8 @@ import com.x8bit.bitwarden.data.vault.repository.util.toEncryptedSdkFolder
|
|||
import com.x8bit.bitwarden.data.vault.repository.util.toEncryptedSdkFolderList
|
||||
import com.x8bit.bitwarden.data.vault.repository.util.toEncryptedSdkSend
|
||||
import com.x8bit.bitwarden.data.vault.repository.util.toEncryptedSdkSendList
|
||||
import com.x8bit.bitwarden.data.vault.repository.util.toOfflineCipher
|
||||
import com.x8bit.bitwarden.data.vault.repository.util.toOfflineCipherView
|
||||
import com.x8bit.bitwarden.ui.vault.feature.vault.model.VaultFilterType
|
||||
import com.x8bit.bitwarden.ui.vault.feature.vault.util.toFilteredList
|
||||
import kotlinx.coroutines.CancellationException
|
||||
|
@ -158,7 +161,7 @@ class VaultRepositoryImpl(
|
|||
private val mutableSendDataStateFlow = MutableStateFlow<DataState<SendData>>(DataState.Loading)
|
||||
|
||||
private val mutableOfflineCiphersStateFlow =
|
||||
MutableStateFlow<DataState<List<CipherView>>>(DataState.Loading)
|
||||
MutableStateFlow<DataState<List<OfflineCipherView>>>(DataState.Loading)
|
||||
|
||||
private val mutableCiphersStateFlow =
|
||||
MutableStateFlow<DataState<List<CipherView>>>(DataState.Loading)
|
||||
|
@ -208,8 +211,8 @@ class VaultRepositoryImpl(
|
|||
override val totpCodeFlow: Flow<TotpCodeResult>
|
||||
get() = mutableTotpCodeResultFlow.asSharedFlow()
|
||||
|
||||
override val offlineCiphersStateFlow: StateFlow<DataState<List<CipherView>>>
|
||||
get() = mutableOfflineCiphersStateFlow.asStateFlow();
|
||||
override val offlineCiphersStateFlow: StateFlow<DataState<List<OfflineCipherView>>>
|
||||
get() = mutableOfflineCiphersStateFlow.asStateFlow()
|
||||
|
||||
override val ciphersStateFlow: StateFlow<DataState<List<CipherView>>>
|
||||
get() = mutableCiphersStateFlow.asStateFlow()
|
||||
|
@ -945,18 +948,21 @@ class VaultRepositoryImpl(
|
|||
|
||||
private fun observeVaultDiskOfflineCiphers(
|
||||
userId: String,
|
||||
): Flow<DataState<List<CipherView>>> =
|
||||
): Flow<DataState<List<OfflineCipherView>>> =
|
||||
vaultDiskSource.getOfflineCiphers(userId = userId)
|
||||
.onStart { mutableOfflineCiphersStateFlow.updateToPendingOrLoading() }
|
||||
.map {
|
||||
.map { ciphers ->
|
||||
waitUntilUnlocked(userId = userId)
|
||||
vaultSdkSource
|
||||
.decryptCipherList(
|
||||
userId = userId,
|
||||
cipherList = it.toCipherList(),
|
||||
cipherList = ciphers.toCipherList(),
|
||||
)
|
||||
.map {
|
||||
it.zip(ciphers).map { (cipher, offlineJson) -> cipher.toOfflineCipherView(offlineJson.toOfflineCipher()) }
|
||||
}
|
||||
.fold(
|
||||
onSuccess = { ciphers -> DataState.Loaded(ciphers.sortAlphabetically()) },
|
||||
onSuccess = { views -> DataState.Loaded(views) },
|
||||
onFailure = { throwable -> DataState.Error(throwable) },
|
||||
)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
package com.x8bit.bitwarden.data.vault.repository.model
|
||||
|
||||
import com.bitwarden.core.DateTime
|
||||
import com.bitwarden.core.Uuid
|
||||
import com.bitwarden.crypto.EncString
|
||||
import com.bitwarden.vault.AttachmentView
|
||||
import com.bitwarden.vault.CardView
|
||||
import com.bitwarden.vault.CipherRepromptType
|
||||
import com.bitwarden.vault.CipherType
|
||||
import com.bitwarden.vault.FieldView
|
||||
import com.bitwarden.vault.IdentityView
|
||||
import com.bitwarden.vault.LocalDataView
|
||||
import com.bitwarden.vault.LoginView
|
||||
import com.bitwarden.vault.PasswordHistoryView
|
||||
import com.bitwarden.vault.SecureNoteView
|
||||
|
||||
data class OfflineCipherView (
|
||||
val id: Uuid?,
|
||||
val organizationId: Uuid?,
|
||||
val folderId: Uuid?,
|
||||
val collectionIds: List<Uuid>,
|
||||
/**
|
||||
* Temporary, required to support re-encrypting existing items.
|
||||
*/
|
||||
val key: EncString?,
|
||||
val name: String,
|
||||
val notes: String?,
|
||||
val type: CipherType,
|
||||
val login: LoginView?,
|
||||
val identity: IdentityView?,
|
||||
val card: CardView?,
|
||||
val secureNote: SecureNoteView?,
|
||||
val favorite: Boolean,
|
||||
val reprompt: CipherRepromptType,
|
||||
val organizationUseTotp: Boolean,
|
||||
val edit: Boolean,
|
||||
val viewPassword: Boolean,
|
||||
val localData: LocalDataView?,
|
||||
val attachments: List<AttachmentView>?,
|
||||
val fields: List<FieldView>?,
|
||||
val passwordHistory: List<PasswordHistoryView>?,
|
||||
val creationDate: DateTime,
|
||||
val deletedDate: DateTime?,
|
||||
val revisionDate: DateTime,
|
||||
val mergeConflict: Boolean
|
||||
)
|
|
@ -17,7 +17,7 @@ import com.bitwarden.vault.FolderView
|
|||
* @param fido2CredentialAutofillViewList List of decrypted fido 2 credentials.
|
||||
*/
|
||||
data class VaultData(
|
||||
val offlineCipherViewList: List<CipherView>,
|
||||
val offlineCipherViewList: List<OfflineCipherView>,
|
||||
val cipherViewList: List<CipherView>,
|
||||
val collectionViewList: List<CollectionView>,
|
||||
val folderViewList: List<FolderView>,
|
||||
|
|
|
@ -4,7 +4,9 @@ package com.x8bit.bitwarden.data.vault.repository.util
|
|||
|
||||
import com.bitwarden.core.DateTime
|
||||
import com.bitwarden.vault.Attachment
|
||||
import com.bitwarden.vault.AttachmentView
|
||||
import com.bitwarden.vault.Card
|
||||
import com.bitwarden.vault.CardView
|
||||
import com.bitwarden.vault.Cipher
|
||||
import com.bitwarden.vault.CipherRepromptType
|
||||
import com.bitwarden.vault.CipherType
|
||||
|
@ -12,12 +14,18 @@ import com.bitwarden.vault.CipherView
|
|||
import com.bitwarden.vault.Fido2Credential
|
||||
import com.bitwarden.vault.Field
|
||||
import com.bitwarden.vault.FieldType
|
||||
import com.bitwarden.vault.FieldView
|
||||
import com.bitwarden.vault.Identity
|
||||
import com.bitwarden.vault.IdentityView
|
||||
import com.bitwarden.vault.LocalDataView
|
||||
import com.bitwarden.vault.Login
|
||||
import com.bitwarden.vault.LoginUri
|
||||
import com.bitwarden.vault.LoginView
|
||||
import com.bitwarden.vault.PasswordHistory
|
||||
import com.bitwarden.vault.PasswordHistoryView
|
||||
import com.bitwarden.vault.SecureNote
|
||||
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.vault.datasource.network.model.AttachmentJsonRequest
|
||||
|
@ -31,6 +39,7 @@ import com.x8bit.bitwarden.data.vault.datasource.network.model.SecureNoteTypeJso
|
|||
import com.x8bit.bitwarden.data.vault.datasource.network.model.SyncResponseJson
|
||||
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 java.time.ZoneOffset
|
||||
import java.time.ZonedDateTime
|
||||
|
@ -63,7 +72,7 @@ fun Cipher.toEncryptedNetworkCipher(): CipherJsonRequest =
|
|||
)
|
||||
|
||||
fun Cipher.toOfflineCipher(): OfflineCipher =
|
||||
OfflineCipher (
|
||||
OfflineCipher(
|
||||
id = id,
|
||||
organizationId = organizationId,
|
||||
folderId = folderId,
|
||||
|
@ -108,19 +117,51 @@ fun OfflineCipher.toOfflineCipherJson(): OfflineCipherJson =
|
|||
passwordHistory = passwordHistory?.toEncryptedNetworkPasswordHistoryList(),
|
||||
creationDate = ZonedDateTime.ofInstant(creationDate, ZoneOffset.UTC),
|
||||
deletedDate = deletedDate?.let { ZonedDateTime.ofInstant(deletedDate, ZoneOffset.UTC) },
|
||||
revisionDate = ZonedDateTime.ofInstant(creationDate, ZoneOffset.UTC),
|
||||
revisionDate = ZonedDateTime.ofInstant(creationDate, ZoneOffset.UTC),
|
||||
mergeConflict = false, // TODO: Copy from the new OfflineCipher type
|
||||
)
|
||||
)
|
||||
|
||||
fun CipherView.toNotificationSummary(): NotificationSummary =
|
||||
fun OfflineCipherView.toNotificationSummary(): NotificationSummary =
|
||||
NotificationSummary(
|
||||
title = name,
|
||||
subtitle = "edited on ${revisionDate.toString()}",
|
||||
subtitle = "edited on $revisionDate. Has Merge Conflict: $mergeConflict",
|
||||
)
|
||||
|
||||
fun CipherView.toOfflineCipherView(offlineCipher: OfflineCipher) =
|
||||
OfflineCipherView(
|
||||
id = id,
|
||||
organizationId = organizationId,
|
||||
folderId = folderId,
|
||||
collectionIds = collectionIds,
|
||||
/**
|
||||
* Temporary, required to support re-encrypting existing items.
|
||||
*/
|
||||
key = key,
|
||||
name = name,
|
||||
notes = notes,
|
||||
type = type,
|
||||
login = login,
|
||||
identity = identity,
|
||||
card = card,
|
||||
secureNote = secureNote,
|
||||
favorite = favorite,
|
||||
reprompt = reprompt,
|
||||
organizationUseTotp = organizationUseTotp,
|
||||
edit = edit,
|
||||
viewPassword = viewPassword,
|
||||
localData = localData,
|
||||
attachments = attachments,
|
||||
fields = fields,
|
||||
passwordHistory = passwordHistory,
|
||||
creationDate = creationDate,
|
||||
deletedDate = deletedDate,
|
||||
revisionDate = revisionDate,
|
||||
mergeConflict = offlineCipher.mergeConflict
|
||||
)
|
||||
|
||||
fun OfflineCipherJson.toOfflineCipher(): OfflineCipher =
|
||||
OfflineCipher(
|
||||
id = if(id.startsWith("create")) null else id,
|
||||
id = if (id.startsWith("create")) null else id,
|
||||
organizationId = organizationId,
|
||||
folderId = folderId,
|
||||
collectionIds = collectionIds.orEmpty(),
|
||||
|
@ -143,8 +184,6 @@ fun OfflineCipherJson.toOfflineCipher(): OfflineCipher =
|
|||
mergeConflict = mergeConflict
|
||||
)
|
||||
|
||||
|
||||
|
||||
fun OfflineCipher.toCipher(): Cipher =
|
||||
Cipher(
|
||||
id = id,
|
||||
|
@ -440,7 +479,7 @@ fun List<SyncResponseJson.Cipher>.toEncryptedSdkCipherList(): List<Cipher> =
|
|||
* Converts a list of [OfflineCipherJson] objects to a list of corresponding
|
||||
* Bitwarden SDK [Cipher] objects.
|
||||
*/
|
||||
fun List<OfflineCipherJson>.toCipherList(): List<Cipher> =
|
||||
fun List<OfflineCipherJson>.toCipherList(): List<Cipher> =
|
||||
map { it.toOfflineCipher().toCipher() }
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in a new issue