mirror of
https://github.com/bitwarden/android.git
synced 2026-06-09 08:09:16 -05:00
BIT-897 Decrypt sync response (#181)
This commit is contained in:
committed by
Álison Fernandes
parent
4a3e88f939
commit
b31b859516
@@ -1,7 +1,8 @@
|
||||
package com.x8bit.bitwarden.data.vault.datasource.network.di
|
||||
|
||||
import com.x8bit.bitwarden.data.vault.datasource.network.service.SyncService
|
||||
import com.x8bit.bitwarden.data.vault.datasource.network.service.SyncServiceImpl
|
||||
import com.x8bit.bitwarden.data.platform.datasource.network.retrofit.Retrofits
|
||||
import com.x8bit.bitwarden.data.vault.datasource.network.api.SyncApi
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import dagger.hilt.InstallIn
|
||||
@@ -18,7 +19,9 @@ object VaultNetworkModule {
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideSyncApiService(
|
||||
fun provideSyncService(
|
||||
retrofits: Retrofits,
|
||||
): SyncApi = retrofits.authenticatedApiRetrofit.create()
|
||||
): SyncService = SyncServiceImpl(
|
||||
syncApi = retrofits.authenticatedApiRetrofit.create(),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -8,19 +8,19 @@ import kotlinx.serialization.Serializable
|
||||
* Represents different fields that a custom cipher field can be linked to.
|
||||
*/
|
||||
@Serializable(LinkedIdTypeSerializer::class)
|
||||
enum class LinkedIdTypeJson {
|
||||
enum class LinkedIdTypeJson(val value: UInt) {
|
||||
// region LOGIN
|
||||
/**
|
||||
* The field is linked to the login's username.
|
||||
*/
|
||||
@SerialName("100")
|
||||
LOGIN_USERNAME,
|
||||
LOGIN_USERNAME(value = 100U),
|
||||
|
||||
/**
|
||||
* The field is linked to the login's password.
|
||||
*/
|
||||
@SerialName("101")
|
||||
LOGIN_PASSWORD,
|
||||
LOGIN_PASSWORD(value = 101U),
|
||||
// endregion LOGIN
|
||||
|
||||
// region CARD
|
||||
@@ -28,37 +28,37 @@ enum class LinkedIdTypeJson {
|
||||
* The field is linked to the card's cardholder name.
|
||||
*/
|
||||
@SerialName("300")
|
||||
CARD_CARDHOLDER_NAME,
|
||||
CARD_CARDHOLDER_NAME(value = 300U),
|
||||
|
||||
/**
|
||||
* The field is linked to the card's expiration month.
|
||||
*/
|
||||
@SerialName("301")
|
||||
CARD_EXP_MONTH,
|
||||
CARD_EXP_MONTH(value = 301U),
|
||||
|
||||
/**
|
||||
* The field is linked to the card's expiration year.
|
||||
*/
|
||||
@SerialName("302")
|
||||
CARD_EXP_YEAR,
|
||||
CARD_EXP_YEAR(value = 302U),
|
||||
|
||||
/**
|
||||
* The field is linked to the card's code.
|
||||
*/
|
||||
@SerialName("303")
|
||||
CARD_CODE,
|
||||
CARD_CODE(value = 303U),
|
||||
|
||||
/**
|
||||
* The field is linked to the card's brand.
|
||||
*/
|
||||
@SerialName("304")
|
||||
CARD_BRAND,
|
||||
CARD_BRAND(value = 304U),
|
||||
|
||||
/**
|
||||
* The field is linked to the card's number.
|
||||
*/
|
||||
@SerialName("305")
|
||||
CARD_NUMBER,
|
||||
CARD_NUMBER(value = 305U),
|
||||
// endregion CARD
|
||||
|
||||
// region IDENTITY
|
||||
@@ -66,115 +66,115 @@ enum class LinkedIdTypeJson {
|
||||
* The field is linked to the identity's title.
|
||||
*/
|
||||
@SerialName("400")
|
||||
IDENTITY_TITLE,
|
||||
IDENTITY_TITLE(value = 400U),
|
||||
|
||||
/**
|
||||
* The field is linked to the identity's middle name.
|
||||
*/
|
||||
@SerialName("401")
|
||||
IDENTITY_MIDDLE_NAME,
|
||||
IDENTITY_MIDDLE_NAME(value = 401U),
|
||||
|
||||
/**
|
||||
* The field is linked to the identity's address line 1.
|
||||
*/
|
||||
@SerialName("402")
|
||||
IDENTITY_ADDRESS_1,
|
||||
IDENTITY_ADDRESS_1(value = 402U),
|
||||
|
||||
/**
|
||||
* The field is linked to the identity's address line 2.
|
||||
*/
|
||||
@SerialName("403")
|
||||
IDENTITY_ADDRESS_2,
|
||||
IDENTITY_ADDRESS_2(value = 403U),
|
||||
|
||||
/**
|
||||
* The field is linked to the identity's address line 3.
|
||||
*/
|
||||
@SerialName("404")
|
||||
IDENTITY_ADDRESS_3,
|
||||
IDENTITY_ADDRESS_3(value = 404U),
|
||||
|
||||
/**
|
||||
* The field is linked to the identity's city.
|
||||
*/
|
||||
@SerialName("405")
|
||||
IDENTITY_CITY,
|
||||
IDENTITY_CITY(value = 405U),
|
||||
|
||||
/**
|
||||
* The field is linked to the identity's state.
|
||||
*/
|
||||
@SerialName("406")
|
||||
IDENTITY_STATE,
|
||||
IDENTITY_STATE(value = 406U),
|
||||
|
||||
/**
|
||||
* The field is linked to the identity's postal code
|
||||
*/
|
||||
@SerialName("407")
|
||||
IDENTITY_POSTAL_CODE,
|
||||
IDENTITY_POSTAL_CODE(value = 407U),
|
||||
|
||||
/**
|
||||
* The field is linked to the identity's country.
|
||||
*/
|
||||
@SerialName("408")
|
||||
IDENTITY_COUNTRY,
|
||||
IDENTITY_COUNTRY(value = 408U),
|
||||
|
||||
/**
|
||||
* The field is linked to the identity's company.
|
||||
*/
|
||||
@SerialName("409")
|
||||
IDENTITY_COMPANY,
|
||||
IDENTITY_COMPANY(value = 409U),
|
||||
|
||||
/**
|
||||
* The field is linked to the identity's email.
|
||||
*/
|
||||
@SerialName("410")
|
||||
IDENTITY_EMAIL,
|
||||
IDENTITY_EMAIL(value = 410U),
|
||||
|
||||
/**
|
||||
* The field is linked to the identity's phone.
|
||||
*/
|
||||
@SerialName("411")
|
||||
IDENTITY_PHONE,
|
||||
IDENTITY_PHONE(value = 411U),
|
||||
|
||||
/**
|
||||
* The field is linked to the identity's SSN.
|
||||
*/
|
||||
@SerialName("412")
|
||||
IDENTITY_SSN,
|
||||
IDENTITY_SSN(value = 412U),
|
||||
|
||||
/**
|
||||
* The field is linked to the identity's username.
|
||||
*/
|
||||
@SerialName("413")
|
||||
IDENTITY_USERNAME,
|
||||
IDENTITY_USERNAME(value = 413U),
|
||||
|
||||
/**
|
||||
* The field is linked to the identity's passport number.
|
||||
*/
|
||||
@SerialName("414")
|
||||
IDENTITY_PASSPORT_NUMBER,
|
||||
IDENTITY_PASSPORT_NUMBER(value = 414U),
|
||||
|
||||
/**
|
||||
* The field is linked to the identity's license number.
|
||||
*/
|
||||
@SerialName("415")
|
||||
IDENTITY_LICENSE_NUMBER,
|
||||
IDENTITY_LICENSE_NUMBER(value = 415U),
|
||||
|
||||
/**
|
||||
* The field is linked to the identity's first name.
|
||||
*/
|
||||
@SerialName("416")
|
||||
IDENTITY_FIRST_NAME,
|
||||
IDENTITY_FIRST_NAME(value = 416U),
|
||||
|
||||
/**
|
||||
* The field is linked to the identity's last name.
|
||||
*/
|
||||
@SerialName("417")
|
||||
IDENTITY_LAST_NAME,
|
||||
IDENTITY_LAST_NAME(value = 417U),
|
||||
|
||||
/**
|
||||
* The field is linked to the identity's full name.
|
||||
*/
|
||||
@SerialName("418")
|
||||
IDENTITY_FULL_NAME,
|
||||
IDENTITY_FULL_NAME(value = 418U),
|
||||
// endregion IDENTITY
|
||||
}
|
||||
|
||||
|
||||
@@ -77,7 +77,7 @@ data class SyncResponseJson(
|
||||
/**
|
||||
* Represents a folder in the vault response.
|
||||
*
|
||||
* @property revisionDate The revision date of the folder (nullable).
|
||||
* @property revisionDate The revision date of the folder.
|
||||
* @property name The name of the folder (nullable).
|
||||
* @property id The ID of the folder.
|
||||
*/
|
||||
@@ -85,7 +85,7 @@ data class SyncResponseJson(
|
||||
data class Folder(
|
||||
@SerialName("revisionDate")
|
||||
@Contextual
|
||||
val revisionDate: LocalDateTime?, // Date
|
||||
val revisionDate: LocalDateTime,
|
||||
|
||||
@SerialName("name")
|
||||
val name: String?,
|
||||
@@ -236,7 +236,7 @@ data class SyncResponseJson(
|
||||
* @property shouldUseActivateAutofillPolicy If the organization should
|
||||
* use auto fill policy.
|
||||
* @property shouldUseEvents If the organization should use events.
|
||||
* @property isFamilySponsorshipFriendlyName If the family sponsorship is a friendly name.
|
||||
* @property familySponsorshipFriendlyName If the family sponsorship is a friendly name.
|
||||
* @property isKeyConnectorEnabled If the key connector is enabled.
|
||||
* @property shouldUseTotp If he organization should use TOTP.
|
||||
* @property familySponsorshipLastSyncDate The last date the family sponsorship
|
||||
@@ -351,7 +351,7 @@ data class SyncResponseJson(
|
||||
val shouldUseEvents: Boolean,
|
||||
|
||||
@SerialName("familySponsorshipFriendlyName")
|
||||
val isFamilySponsorshipFriendlyName: String?,
|
||||
val familySponsorshipFriendlyName: String?,
|
||||
|
||||
@SerialName("keyConnectorEnabled")
|
||||
val isKeyConnectorEnabled: Boolean,
|
||||
@@ -376,7 +376,8 @@ data class SyncResponseJson(
|
||||
val isSsoBound: Boolean,
|
||||
|
||||
@SerialName("familySponsorshipValidUntil")
|
||||
val familySponsorshipValidUntil: String?,
|
||||
@Contextual
|
||||
val familySponsorshipValidUntil: LocalDateTime?,
|
||||
|
||||
@SerialName("status")
|
||||
val status: Int,
|
||||
@@ -499,10 +500,10 @@ data class SyncResponseJson(
|
||||
* @property shouldEdit If the cipher can edit.
|
||||
* @property passwordHistory A list of password history objects
|
||||
* associated with the cipher (nullable).
|
||||
* @property revisionDate The revision date of the cipher (nullable).
|
||||
* @property revisionDate The revision date of the cipher.
|
||||
* @property type The type of cipher.
|
||||
* @property login The login of the cipher.
|
||||
* @property creationDate The creation date of the cipher (nullable).
|
||||
* @property creationDate The creation date of the cipher.
|
||||
* @property secureNote The secure note of the cipher.
|
||||
* @property folderId The folder ID of the cipher (nullable).
|
||||
* @property organizationId The organization ID of the cipher (nullable).
|
||||
@@ -538,20 +539,20 @@ data class SyncResponseJson(
|
||||
|
||||
@SerialName("revisionDate")
|
||||
@Contextual
|
||||
val revisionDate: LocalDateTime?,
|
||||
val revisionDate: LocalDateTime,
|
||||
|
||||
@SerialName("type")
|
||||
val type: CipherTypeJson,
|
||||
|
||||
@SerialName("login")
|
||||
val login: Login,
|
||||
val login: Login?,
|
||||
|
||||
@SerialName("creationDate")
|
||||
@Contextual
|
||||
val creationDate: LocalDateTime?,
|
||||
val creationDate: LocalDateTime,
|
||||
|
||||
@SerialName("secureNote")
|
||||
val secureNote: SecureNote,
|
||||
val secureNote: SecureNote?,
|
||||
|
||||
@SerialName("folderId")
|
||||
val folderId: String?,
|
||||
@@ -564,7 +565,7 @@ data class SyncResponseJson(
|
||||
val deletedDate: LocalDateTime?,
|
||||
|
||||
@SerialName("identity")
|
||||
val identity: Identity,
|
||||
val identity: Identity?,
|
||||
|
||||
@SerialName("collectionIds")
|
||||
val collectionIds: List<String>?,
|
||||
@@ -585,7 +586,7 @@ data class SyncResponseJson(
|
||||
val isFavorite: Boolean,
|
||||
|
||||
@SerialName("card")
|
||||
val card: Card,
|
||||
val card: Card?,
|
||||
) {
|
||||
/**
|
||||
* Represents an attachment in the vault response.
|
||||
@@ -795,7 +796,7 @@ data class SyncResponseJson(
|
||||
@Serializable
|
||||
data class Uri(
|
||||
@SerialName("match")
|
||||
val uriMatchType: UriMatchTypeJson,
|
||||
val uriMatchType: UriMatchTypeJson?,
|
||||
|
||||
@SerialName("uri")
|
||||
val uri: String?,
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.x8bit.bitwarden.data.vault.datasource.network.service
|
||||
|
||||
import com.x8bit.bitwarden.data.vault.datasource.network.model.SyncResponseJson
|
||||
|
||||
/**
|
||||
* Provides an API for querying sync endpoints.
|
||||
*/
|
||||
interface SyncService {
|
||||
/**
|
||||
* Make sync request to get vault items.
|
||||
*/
|
||||
suspend fun sync(): Result<SyncResponseJson>
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package com.x8bit.bitwarden.data.vault.datasource.network.service
|
||||
|
||||
import com.x8bit.bitwarden.data.vault.datasource.network.api.SyncApi
|
||||
import com.x8bit.bitwarden.data.vault.datasource.network.model.SyncResponseJson
|
||||
|
||||
class SyncServiceImpl constructor(
|
||||
private val syncApi: SyncApi,
|
||||
) : SyncService {
|
||||
override suspend fun sync(): Result<SyncResponseJson> = syncApi.sync()
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package com.x8bit.bitwarden.data.vault.datasource.sdk
|
||||
|
||||
import com.bitwarden.core.Cipher
|
||||
import com.bitwarden.core.CipherListView
|
||||
import com.bitwarden.core.CipherView
|
||||
import com.bitwarden.core.Folder
|
||||
import com.bitwarden.core.FolderView
|
||||
|
||||
/**
|
||||
* Source of vault information and functionality from the Bitwarden SDK.
|
||||
*/
|
||||
interface VaultSdkSource {
|
||||
/**
|
||||
* Decrypts a [Cipher] returning a [CipherView] wrapped in a [Result].
|
||||
*/
|
||||
suspend fun decryptCipher(cipher: Cipher): Result<CipherView>
|
||||
|
||||
/**
|
||||
* Decrypts a list of [Cipher]s returning a list of [CipherListView] wrapped in a [Result].
|
||||
*/
|
||||
suspend fun decryptCipherList(cipherList: List<Cipher>): Result<List<CipherListView>>
|
||||
|
||||
/**
|
||||
* Decrypts a [Folder] returning a [FolderView] wrapped in a [Result].
|
||||
*/
|
||||
suspend fun decryptFolder(folder: Folder): Result<FolderView>
|
||||
|
||||
/**
|
||||
* Decrypts a list of [Folder]s returning a list of [FolderView] wrapped in a [Result].
|
||||
*/
|
||||
suspend fun decryptFolderList(folderList: List<Folder>): Result<List<FolderView>>
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package com.x8bit.bitwarden.data.vault.datasource.sdk
|
||||
|
||||
import com.bitwarden.core.Cipher
|
||||
import com.bitwarden.core.CipherListView
|
||||
import com.bitwarden.core.CipherView
|
||||
import com.bitwarden.core.Folder
|
||||
import com.bitwarden.core.FolderView
|
||||
import com.bitwarden.sdk.ClientVault
|
||||
|
||||
/**
|
||||
* Primary implementation of [VaultSdkSource] that serves as a convenience wrapper around a
|
||||
* [ClientVault].
|
||||
*/
|
||||
class VaultSdkSourceImpl(
|
||||
private val clientVault: ClientVault,
|
||||
) : VaultSdkSource {
|
||||
|
||||
override suspend fun decryptCipher(cipher: Cipher): Result<CipherView> =
|
||||
runCatching { clientVault.ciphers().decrypt(cipher) }
|
||||
|
||||
override suspend fun decryptCipherList(cipherList: List<Cipher>): Result<List<CipherListView>> =
|
||||
runCatching { clientVault.ciphers().decryptList(cipherList) }
|
||||
|
||||
override suspend fun decryptFolder(folder: Folder): Result<FolderView> =
|
||||
runCatching { clientVault.folders().decrypt(folder) }
|
||||
|
||||
override suspend fun decryptFolderList(folderList: List<Folder>): Result<List<FolderView>> =
|
||||
runCatching { clientVault.folders().decryptList(folderList) }
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.x8bit.bitwarden.data.vault.datasource.sdk.di
|
||||
|
||||
import com.bitwarden.sdk.Client
|
||||
import com.x8bit.bitwarden.data.vault.datasource.sdk.VaultSdkSource
|
||||
import com.x8bit.bitwarden.data.vault.datasource.sdk.VaultSdkSourceImpl
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import dagger.hilt.InstallIn
|
||||
import dagger.hilt.components.SingletonComponent
|
||||
import javax.inject.Singleton
|
||||
|
||||
/**
|
||||
* Provides SDK-related dependencies for the vault package.
|
||||
*/
|
||||
@Module
|
||||
@InstallIn(SingletonComponent::class)
|
||||
class VaultSdkModule {
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun providesVaultSdkSource(
|
||||
client: Client,
|
||||
): VaultSdkSource = VaultSdkSourceImpl(clientVault = client.vault())
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package com.x8bit.bitwarden.data.vault.repository
|
||||
|
||||
/**
|
||||
* Responsible for managing vault data inside the network layer.
|
||||
*/
|
||||
interface VaultRepository {
|
||||
|
||||
/**
|
||||
* Attempt to sync the vault data.
|
||||
*/
|
||||
suspend fun sync()
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
package com.x8bit.bitwarden.data.vault.repository
|
||||
|
||||
import com.x8bit.bitwarden.data.vault.datasource.network.service.SyncService
|
||||
import com.x8bit.bitwarden.data.vault.datasource.sdk.VaultSdkSource
|
||||
import com.x8bit.bitwarden.data.vault.repository.util.toEncryptedSdkCipherList
|
||||
import com.x8bit.bitwarden.data.vault.repository.util.toEncryptedSdkFolderList
|
||||
import kotlinx.coroutines.CoroutineDispatcher
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
/**
|
||||
* Default implementation of [VaultRepository].
|
||||
*/
|
||||
class VaultRepositoryImpl constructor(
|
||||
private val syncService: SyncService,
|
||||
private val vaultSdkSource: VaultSdkSource,
|
||||
dispatcher: CoroutineDispatcher,
|
||||
) : VaultRepository {
|
||||
|
||||
private val scope = CoroutineScope(dispatcher)
|
||||
|
||||
private var syncJob: Job = Job().apply { complete() }
|
||||
|
||||
override suspend fun sync() {
|
||||
if (!syncJob.isCompleted) return
|
||||
syncJob = scope.launch {
|
||||
syncService
|
||||
.sync()
|
||||
.fold(
|
||||
onSuccess = { syncResponse ->
|
||||
// TODO transform into domain object consumable by VaultViewModel BIT-205.
|
||||
|
||||
// TODO initialize crypto in BIT-990
|
||||
syncResponse.ciphers?.let { networkCiphers ->
|
||||
vaultSdkSource.decryptCipherList(
|
||||
cipherList = networkCiphers.toEncryptedSdkCipherList(),
|
||||
)
|
||||
}
|
||||
syncResponse.folders?.let { networkFolders ->
|
||||
vaultSdkSource.decryptFolderList(
|
||||
folderList = networkFolders.toEncryptedSdkFolderList(),
|
||||
)
|
||||
}
|
||||
},
|
||||
onFailure = {
|
||||
// TODO handle failure BIT-205.
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package com.x8bit.bitwarden.data.vault.repository.di
|
||||
|
||||
import com.x8bit.bitwarden.data.vault.datasource.network.service.SyncService
|
||||
import com.x8bit.bitwarden.data.vault.datasource.sdk.VaultSdkSource
|
||||
import com.x8bit.bitwarden.data.vault.repository.VaultRepository
|
||||
import com.x8bit.bitwarden.data.vault.repository.VaultRepositoryImpl
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import dagger.hilt.InstallIn
|
||||
import dagger.hilt.components.SingletonComponent
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import javax.inject.Singleton
|
||||
|
||||
/**
|
||||
* Provides repositories in the vault package.
|
||||
*/
|
||||
@Module
|
||||
@InstallIn(SingletonComponent::class)
|
||||
class VaultRepositoryModule {
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun providesVaultRepository(
|
||||
syncService: SyncService,
|
||||
vaultSdkSource: VaultSdkSource,
|
||||
): VaultRepository = VaultRepositoryImpl(
|
||||
syncService = syncService,
|
||||
vaultSdkSource = vaultSdkSource,
|
||||
dispatcher = Dispatchers.IO,
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,243 @@
|
||||
@file:Suppress("TooManyFunctions")
|
||||
package com.x8bit.bitwarden.data.vault.repository.util
|
||||
|
||||
import com.bitwarden.core.Attachment
|
||||
import com.bitwarden.core.Card
|
||||
import com.bitwarden.core.Cipher
|
||||
import com.bitwarden.core.CipherRepromptType
|
||||
import com.bitwarden.core.CipherType
|
||||
import com.bitwarden.core.Field
|
||||
import com.bitwarden.core.FieldType
|
||||
import com.bitwarden.core.Identity
|
||||
import com.bitwarden.core.Login
|
||||
import com.bitwarden.core.LoginUri
|
||||
import com.bitwarden.core.PasswordHistory
|
||||
import com.bitwarden.core.SecureNote
|
||||
import com.bitwarden.core.SecureNoteType
|
||||
import com.bitwarden.core.UriMatchType
|
||||
import com.x8bit.bitwarden.data.vault.datasource.network.model.CipherRepromptTypeJson
|
||||
import com.x8bit.bitwarden.data.vault.datasource.network.model.CipherTypeJson
|
||||
import com.x8bit.bitwarden.data.vault.datasource.network.model.FieldTypeJson
|
||||
import com.x8bit.bitwarden.data.vault.datasource.network.model.SecureNoteTypeJson
|
||||
import com.x8bit.bitwarden.data.vault.datasource.network.model.SyncResponseJson
|
||||
import com.x8bit.bitwarden.data.vault.datasource.network.model.UriMatchTypeJson
|
||||
import java.time.ZoneOffset
|
||||
|
||||
/**
|
||||
* Converts a list of [SyncResponseJson.Cipher] objects to a list of corresponding
|
||||
* Bitwarden SDK [Cipher] objects.
|
||||
*/
|
||||
fun List<SyncResponseJson.Cipher>.toEncryptedSdkCipherList(): List<Cipher> =
|
||||
map { it.toEncryptedSdkCipher() }
|
||||
|
||||
/**
|
||||
* Converts a of [SyncResponseJson.Cipher] object to a corresponding
|
||||
* Bitwarden SDK [Cipher] object.
|
||||
*/
|
||||
fun SyncResponseJson.Cipher.toEncryptedSdkCipher(): Cipher =
|
||||
Cipher(
|
||||
id = id,
|
||||
organizationId = organizationId,
|
||||
folderId = folderId,
|
||||
collectionIds = collectionIds.orEmpty(),
|
||||
name = name.orEmpty(),
|
||||
notes = notes,
|
||||
type = type.toSdkCipherType(),
|
||||
login = login?.toSdkLogin(),
|
||||
identity = identity?.toSdkIdentity(),
|
||||
card = card?.toSdkCard(),
|
||||
secureNote = secureNote?.toSdkSecureNote(),
|
||||
favorite = isFavorite,
|
||||
reprompt = reprompt.toSdkRepromptType(),
|
||||
organizationUseTotp = shouldOrganizationUseTotp,
|
||||
edit = shouldEdit,
|
||||
viewPassword = shouldViewPassword,
|
||||
localData = null,
|
||||
attachments = attachments?.toSdkAttachmentList(),
|
||||
fields = fields?.toSdkFieldList(),
|
||||
passwordHistory = passwordHistory?.toSdkPasswordHistoryList(),
|
||||
creationDate = creationDate.toInstant(ZoneOffset.UTC),
|
||||
deletedDate = deletedDate?.toInstant(ZoneOffset.UTC),
|
||||
revisionDate = revisionDate.toInstant(ZoneOffset.UTC),
|
||||
)
|
||||
|
||||
/**
|
||||
* Transforms a [SyncResponseJson.Cipher.Login] into the corresponding Bitwarden SDK [Login].
|
||||
*/
|
||||
fun SyncResponseJson.Cipher.Login.toSdkLogin(): Login =
|
||||
Login(
|
||||
username = username,
|
||||
password = password,
|
||||
passwordRevisionDate = passwordRevisionDate?.toInstant(ZoneOffset.UTC),
|
||||
uris = uris?.toSdkLoginUriList(),
|
||||
totp = totp,
|
||||
autofillOnPageLoad = shouldAutofillOnPageLoad,
|
||||
)
|
||||
|
||||
/**
|
||||
* Transforms a [SyncResponseJson.Cipher.Identity] into the corresponding Bitwarden SDK [Identity].
|
||||
*/
|
||||
fun SyncResponseJson.Cipher.Identity.toSdkIdentity(): Identity =
|
||||
Identity(
|
||||
title = title,
|
||||
middleName = middleName,
|
||||
firstName = firstName,
|
||||
lastName = lastName,
|
||||
address1 = address1,
|
||||
address2 = address2,
|
||||
address3 = address3,
|
||||
city = city,
|
||||
state = state,
|
||||
postalCode = postalCode,
|
||||
country = country,
|
||||
company = company,
|
||||
email = email,
|
||||
phone = phone,
|
||||
ssn = ssn,
|
||||
username = username,
|
||||
passportNumber = passportNumber,
|
||||
licenseNumber = licenseNumber,
|
||||
)
|
||||
|
||||
/**
|
||||
* Transforms a [SyncResponseJson.Cipher.Card] into the corresponding Bitwarden SDK [Card].
|
||||
*/
|
||||
fun SyncResponseJson.Cipher.Card.toSdkCard(): Card =
|
||||
Card(
|
||||
cardholderName = cardholderName,
|
||||
expMonth = expMonth,
|
||||
expYear = expirationYear,
|
||||
code = code,
|
||||
brand = brand,
|
||||
number = number,
|
||||
)
|
||||
|
||||
/**
|
||||
* Transforms a [SyncResponseJson.Cipher.SecureNote] into
|
||||
* the corresponding Bitwarden SDK [SecureNote].
|
||||
*/
|
||||
fun SyncResponseJson.Cipher.SecureNote.toSdkSecureNote(): SecureNote =
|
||||
SecureNote(
|
||||
type = when (type) {
|
||||
SecureNoteTypeJson.GENERIC -> SecureNoteType.GENERIC
|
||||
},
|
||||
)
|
||||
|
||||
/**
|
||||
* Transforms a list of [SyncResponseJson.Cipher.Login.Uri] into
|
||||
* a corresponding list of Bitwarden SDK [LoginUri].
|
||||
*/
|
||||
fun List<SyncResponseJson.Cipher.Login.Uri>.toSdkLoginUriList(): List<LoginUri> =
|
||||
map { it.toSdkLoginUri() }
|
||||
|
||||
/**
|
||||
* Transforms a [SyncResponseJson.Cipher.Login.Uri] into
|
||||
* a corresponding Bitwarden SDK [LoginUri].
|
||||
*/
|
||||
fun SyncResponseJson.Cipher.Login.Uri.toSdkLoginUri(): LoginUri =
|
||||
LoginUri(
|
||||
uri = uri,
|
||||
match = uriMatchType?.toSdkMatchType(),
|
||||
)
|
||||
|
||||
/**
|
||||
* Transforms a list of [SyncResponseJson.Cipher.Attachment] into
|
||||
* a corresponding list of Bitwarden SDK [Attachment].
|
||||
*/
|
||||
fun List<SyncResponseJson.Cipher.Attachment>.toSdkAttachmentList(): List<Attachment> =
|
||||
map { it.toSdkAttachment() }
|
||||
|
||||
/**
|
||||
* Transforms a [SyncResponseJson.Cipher.Attachment] into
|
||||
* a corresponding Bitwarden SDK [Attachment].
|
||||
*/
|
||||
fun SyncResponseJson.Cipher.Attachment.toSdkAttachment(): Attachment =
|
||||
Attachment(
|
||||
id = id,
|
||||
url = url,
|
||||
size = size.toString(),
|
||||
sizeName = sizeName,
|
||||
fileName = fileName,
|
||||
key = key,
|
||||
)
|
||||
|
||||
/**
|
||||
* Transforms a list of [SyncResponseJson.Cipher.Field] into
|
||||
* a corresponding list of Bitwarden SDK [Field].
|
||||
*/
|
||||
fun List<SyncResponseJson.Cipher.Field>.toSdkFieldList(): List<Field> =
|
||||
map { it.toSdkField() }
|
||||
|
||||
/**
|
||||
* Transforms a [SyncResponseJson.Cipher.Field] into
|
||||
* a corresponding Bitwarden SDK [Field].
|
||||
*/
|
||||
fun SyncResponseJson.Cipher.Field.toSdkField(): Field =
|
||||
Field(
|
||||
name = name,
|
||||
value = value,
|
||||
type = type.toSdkFieldType(),
|
||||
linkedId = linkedIdType?.value,
|
||||
)
|
||||
|
||||
/**
|
||||
* Transforms a list of [SyncResponseJson.Cipher.PasswordHistory] into
|
||||
* a corresponding list of Bitwarden SDK [PasswordHistory].
|
||||
*/
|
||||
@Suppress("MaxLineLength")
|
||||
fun List<SyncResponseJson.Cipher.PasswordHistory>.toSdkPasswordHistoryList(): List<PasswordHistory> =
|
||||
map { it.toSdkPasswordHistory() }
|
||||
|
||||
/**
|
||||
* Transforms a [SyncResponseJson.Cipher.PasswordHistory] into
|
||||
* a corresponding Bitwarden SDK [PasswordHistory].
|
||||
*/
|
||||
fun SyncResponseJson.Cipher.PasswordHistory.toSdkPasswordHistory(): PasswordHistory =
|
||||
PasswordHistory(
|
||||
password = password,
|
||||
lastUsedDate = lastUsedDate.toInstant(ZoneOffset.UTC),
|
||||
)
|
||||
|
||||
/**
|
||||
* Transforms a [CipherTypeJson] to the corresponding Bitwarden SDK [CipherType].
|
||||
*/
|
||||
fun CipherTypeJson.toSdkCipherType(): CipherType =
|
||||
when (this) {
|
||||
CipherTypeJson.LOGIN -> CipherType.LOGIN
|
||||
CipherTypeJson.SECURE_NOTE -> CipherType.SECURE_NOTE
|
||||
CipherTypeJson.CARD -> CipherType.CARD
|
||||
CipherTypeJson.IDENTITY -> CipherType.IDENTITY
|
||||
}
|
||||
|
||||
/**
|
||||
* Transforms a [UriMatchTypeJson] to the corresponding Bitwarden SDK [UriMatchType].
|
||||
*/
|
||||
fun UriMatchTypeJson.toSdkMatchType(): UriMatchType =
|
||||
when (this) {
|
||||
UriMatchTypeJson.DOMAIN -> UriMatchType.DOMAIN
|
||||
UriMatchTypeJson.HOST -> UriMatchType.HOST
|
||||
UriMatchTypeJson.STARTS_WITH -> UriMatchType.STARTS_WITH
|
||||
UriMatchTypeJson.EXACT -> UriMatchType.EXACT
|
||||
UriMatchTypeJson.REGULAR_EXPRESSION -> UriMatchType.REGULAR_EXPRESSION
|
||||
UriMatchTypeJson.NEVER -> UriMatchType.NEVER
|
||||
}
|
||||
|
||||
/**
|
||||
* Transforms a [CipherRepromptTypeJson] to the corresponding Bitwarden SDK [CipherRepromptType].
|
||||
*/
|
||||
fun CipherRepromptTypeJson.toSdkRepromptType(): CipherRepromptType =
|
||||
when (this) {
|
||||
CipherRepromptTypeJson.NONE -> CipherRepromptType.NONE
|
||||
CipherRepromptTypeJson.PASSWORD -> CipherRepromptType.PASSWORD
|
||||
}
|
||||
|
||||
/**
|
||||
* Transforms a [FieldTypeJson] to the corresponding Bitwarden SDK [FieldType].
|
||||
*/
|
||||
fun FieldTypeJson.toSdkFieldType(): FieldType =
|
||||
when (this) {
|
||||
FieldTypeJson.TEXT -> FieldType.TEXT
|
||||
FieldTypeJson.HIDDEN -> FieldType.HIDDEN
|
||||
FieldTypeJson.BOOLEAN -> FieldType.BOOLEAN
|
||||
FieldTypeJson.LINKED -> FieldType.LINKED
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package com.x8bit.bitwarden.data.vault.repository.util
|
||||
|
||||
import com.bitwarden.core.Folder
|
||||
import com.x8bit.bitwarden.data.vault.datasource.network.model.SyncResponseJson
|
||||
import java.time.ZoneOffset
|
||||
|
||||
/**
|
||||
* Converts a list of [SyncResponseJson.Folder] objects to a list of corresponding
|
||||
* Bitwarden SDK [Folder] objects.
|
||||
*/
|
||||
fun List<SyncResponseJson.Folder>.toEncryptedSdkFolderList(): List<Folder> =
|
||||
map { it.toEncryptedSdkFolder() }
|
||||
|
||||
/**
|
||||
* Converts a [SyncResponseJson.Folder] objects to a corresponding
|
||||
* Bitwarden SDK [Folder] object.
|
||||
*/
|
||||
fun SyncResponseJson.Folder.toEncryptedSdkFolder(): Folder =
|
||||
Folder(
|
||||
id = id,
|
||||
name = name.orEmpty(),
|
||||
revisionDate = revisionDate.toInstant(ZoneOffset.UTC),
|
||||
)
|
||||
Reference in New Issue
Block a user