mirror of
https://github.com/bitwarden/android.git
synced 2024-11-21 17:05:44 +03:00
BIT-636: Rectify sync api response model (#145)
This commit is contained in:
parent
bd8357a0c4
commit
db30504b70
12 changed files with 633 additions and 41 deletions
|
@ -3,6 +3,7 @@ package com.x8bit.bitwarden.data.platform.datasource.network.di
|
|||
import com.jakewharton.retrofit2.converter.kotlinx.serialization.asConverterFactory
|
||||
import com.x8bit.bitwarden.data.platform.datasource.network.core.ResultCallAdapterFactory
|
||||
import com.x8bit.bitwarden.data.platform.datasource.network.interceptor.AuthTokenInterceptor
|
||||
import com.x8bit.bitwarden.data.platform.datasource.network.serializer.LocalDateTimeSerializer
|
||||
import com.x8bit.bitwarden.data.platform.datasource.network.service.ConfigService
|
||||
import com.x8bit.bitwarden.data.platform.datasource.network.service.ConfigServiceImpl
|
||||
import dagger.Module
|
||||
|
@ -11,11 +12,13 @@ import dagger.hilt.InstallIn
|
|||
import dagger.hilt.components.SingletonComponent
|
||||
import kotlinx.serialization.ExperimentalSerializationApi
|
||||
import kotlinx.serialization.json.Json
|
||||
import kotlinx.serialization.modules.SerializersModule
|
||||
import okhttp3.MediaType.Companion.toMediaType
|
||||
import okhttp3.OkHttpClient
|
||||
import okhttp3.logging.HttpLoggingInterceptor
|
||||
import retrofit2.Retrofit
|
||||
import retrofit2.create
|
||||
import java.time.LocalDateTime
|
||||
import javax.inject.Named
|
||||
import javax.inject.Singleton
|
||||
|
||||
|
@ -98,5 +101,8 @@ object NetworkModule {
|
|||
|
||||
// We allow for nullable values to have keys missing in the JSON response.
|
||||
explicitNulls = false
|
||||
serializersModule = SerializersModule {
|
||||
contextual(LocalDateTime::class, LocalDateTimeSerializer())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
package com.x8bit.bitwarden.data.platform.datasource.network.serializer
|
||||
|
||||
import kotlinx.serialization.KSerializer
|
||||
import kotlinx.serialization.descriptors.PrimitiveKind
|
||||
import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor
|
||||
import kotlinx.serialization.descriptors.SerialDescriptor
|
||||
import kotlinx.serialization.encoding.Decoder
|
||||
import kotlinx.serialization.encoding.Encoder
|
||||
import java.time.LocalDateTime
|
||||
import java.time.format.DateTimeFormatter
|
||||
import java.time.format.DateTimeParseException
|
||||
|
||||
/**
|
||||
* Used to serialize and deserialize [LocalDateTime].
|
||||
*/
|
||||
class LocalDateTimeSerializer : KSerializer<LocalDateTime> {
|
||||
private val localDateTimeFormatter =
|
||||
DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SS'Z'")
|
||||
private val localDateTimeFormatterNanoSeconds =
|
||||
DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSSSSS'Z'")
|
||||
override val descriptor: SerialDescriptor
|
||||
get() = PrimitiveSerialDescriptor(serialName = "LocalDateTime", kind = PrimitiveKind.STRING)
|
||||
|
||||
override fun deserialize(decoder: Decoder): LocalDateTime =
|
||||
decoder.decodeString().let { dateString ->
|
||||
try {
|
||||
LocalDateTime
|
||||
.parse(dateString, localDateTimeFormatter)
|
||||
} catch (exception: DateTimeParseException) {
|
||||
LocalDateTime
|
||||
.parse(dateString, localDateTimeFormatterNanoSeconds)
|
||||
}
|
||||
}
|
||||
|
||||
override fun serialize(encoder: Encoder, value: LocalDateTime) {
|
||||
encoder.encodeString(localDateTimeFormatter.format(value))
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
package com.x8bit.bitwarden.data.vault.datasource.network.model
|
||||
|
||||
import com.x8bit.bitwarden.data.platform.datasource.network.serializer.BaseEnumeratedIntSerializer
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
/**
|
||||
* Represents different types of cipher repromt.
|
||||
*/
|
||||
@Serializable(CipherRepromptTypeSerializer::class)
|
||||
enum class CipherRepromptTypeJson {
|
||||
/**
|
||||
* No re-prompt is necessary.
|
||||
*/
|
||||
@SerialName("0")
|
||||
NONE,
|
||||
|
||||
/**
|
||||
* The user should be prompted for their master password prior to using the cipher password.
|
||||
*/
|
||||
@SerialName("1")
|
||||
PASSWORD,
|
||||
}
|
||||
|
||||
private class CipherRepromptTypeSerializer :
|
||||
BaseEnumeratedIntSerializer<CipherRepromptTypeJson>(CipherRepromptTypeJson.values())
|
|
@ -0,0 +1,38 @@
|
|||
package com.x8bit.bitwarden.data.vault.datasource.network.model
|
||||
|
||||
import com.x8bit.bitwarden.data.platform.datasource.network.serializer.BaseEnumeratedIntSerializer
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
/**
|
||||
* Represents different types of ciphers.
|
||||
*/
|
||||
@Serializable(CipherTypeSerializer::class)
|
||||
enum class CipherTypeJson {
|
||||
/**
|
||||
* A login containing a username and password.
|
||||
*/
|
||||
@SerialName("1")
|
||||
LOGIN,
|
||||
|
||||
/**
|
||||
* A secure note.
|
||||
*/
|
||||
@SerialName("2")
|
||||
SECURE_NOTE,
|
||||
|
||||
/**
|
||||
* A credit/debit card.
|
||||
*/
|
||||
@SerialName("3")
|
||||
CARD,
|
||||
|
||||
/**
|
||||
* Personal information for filling out forms.
|
||||
*/
|
||||
@SerialName("4")
|
||||
IDENTITY,
|
||||
}
|
||||
|
||||
private class CipherTypeSerializer :
|
||||
BaseEnumeratedIntSerializer<CipherTypeJson>(CipherTypeJson.values())
|
|
@ -0,0 +1,38 @@
|
|||
package com.x8bit.bitwarden.data.vault.datasource.network.model
|
||||
|
||||
import com.x8bit.bitwarden.data.platform.datasource.network.serializer.BaseEnumeratedIntSerializer
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
/**
|
||||
* Represents different types of fields.
|
||||
*/
|
||||
@Serializable(FieldTypeSerializer::class)
|
||||
enum class FieldTypeJson {
|
||||
/**
|
||||
* The field stores freeform input.
|
||||
*/
|
||||
@SerialName("0")
|
||||
TEXT,
|
||||
|
||||
/**
|
||||
* The field stores freeform input that is hidden from view.
|
||||
*/
|
||||
@SerialName("1")
|
||||
HIDDEN,
|
||||
|
||||
/**
|
||||
* The field stores a boolean value.
|
||||
*/
|
||||
@SerialName("2")
|
||||
BOOLEAN,
|
||||
|
||||
/**
|
||||
* The field value is linked to the item's username or password.
|
||||
*/
|
||||
@SerialName("3")
|
||||
LINKED,
|
||||
}
|
||||
|
||||
private class FieldTypeSerializer :
|
||||
BaseEnumeratedIntSerializer<FieldTypeJson>(FieldTypeJson.values())
|
|
@ -0,0 +1,182 @@
|
|||
package com.x8bit.bitwarden.data.vault.datasource.network.model
|
||||
|
||||
import com.x8bit.bitwarden.data.platform.datasource.network.serializer.BaseEnumeratedIntSerializer
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
/**
|
||||
* Represents different fields that a custom cipher field can be linked to.
|
||||
*/
|
||||
@Serializable(LinkedIdTypeSerializer::class)
|
||||
enum class LinkedIdTypeJson {
|
||||
// region LOGIN
|
||||
/**
|
||||
* The field is linked to the login's username.
|
||||
*/
|
||||
@SerialName("100")
|
||||
LOGIN_USERNAME,
|
||||
|
||||
/**
|
||||
* The field is linked to the login's password.
|
||||
*/
|
||||
@SerialName("101")
|
||||
LOGIN_PASSWORD,
|
||||
// endregion LOGIN
|
||||
|
||||
// region CARD
|
||||
/**
|
||||
* The field is linked to the card's cardholder name.
|
||||
*/
|
||||
@SerialName("300")
|
||||
CARD_CARDHOLDER_NAME,
|
||||
|
||||
/**
|
||||
* The field is linked to the card's expiration month.
|
||||
*/
|
||||
@SerialName("301")
|
||||
CARD_EXP_MONTH,
|
||||
|
||||
/**
|
||||
* The field is linked to the card's expiration year.
|
||||
*/
|
||||
@SerialName("302")
|
||||
CARD_EXP_YEAR,
|
||||
|
||||
/**
|
||||
* The field is linked to the card's code.
|
||||
*/
|
||||
@SerialName("303")
|
||||
CARD_CODE,
|
||||
|
||||
/**
|
||||
* The field is linked to the card's brand.
|
||||
*/
|
||||
@SerialName("304")
|
||||
CARD_BRAND,
|
||||
|
||||
/**
|
||||
* The field is linked to the card's number.
|
||||
*/
|
||||
@SerialName("305")
|
||||
CARD_NUMBER,
|
||||
// endregion CARD
|
||||
|
||||
// region IDENTITY
|
||||
/**
|
||||
* The field is linked to the identity's title.
|
||||
*/
|
||||
@SerialName("400")
|
||||
IDENTITY_TITLE,
|
||||
|
||||
/**
|
||||
* The field is linked to the identity's middle name.
|
||||
*/
|
||||
@SerialName("401")
|
||||
IDENTITY_MIDDLE_NAME,
|
||||
|
||||
/**
|
||||
* The field is linked to the identity's address line 1.
|
||||
*/
|
||||
@SerialName("402")
|
||||
IDENTITY_ADDRESS_1,
|
||||
|
||||
/**
|
||||
* The field is linked to the identity's address line 2.
|
||||
*/
|
||||
@SerialName("403")
|
||||
IDENTITY_ADDRESS_2,
|
||||
|
||||
/**
|
||||
* The field is linked to the identity's address line 3.
|
||||
*/
|
||||
@SerialName("404")
|
||||
IDENTITY_ADDRESS_3,
|
||||
|
||||
/**
|
||||
* The field is linked to the identity's city.
|
||||
*/
|
||||
@SerialName("405")
|
||||
IDENTITY_CITY,
|
||||
|
||||
/**
|
||||
* The field is linked to the identity's state.
|
||||
*/
|
||||
@SerialName("406")
|
||||
IDENTITY_STATE,
|
||||
|
||||
/**
|
||||
* The field is linked to the identity's postal code
|
||||
*/
|
||||
@SerialName("407")
|
||||
IDENTITY_POSTAL_CODE,
|
||||
|
||||
/**
|
||||
* The field is linked to the identity's country.
|
||||
*/
|
||||
@SerialName("408")
|
||||
IDENTITY_COUNTRY,
|
||||
|
||||
/**
|
||||
* The field is linked to the identity's company.
|
||||
*/
|
||||
@SerialName("409")
|
||||
IDENTITY_COMPANY,
|
||||
|
||||
/**
|
||||
* The field is linked to the identity's email.
|
||||
*/
|
||||
@SerialName("410")
|
||||
IDENTITY_EMAIL,
|
||||
|
||||
/**
|
||||
* The field is linked to the identity's phone.
|
||||
*/
|
||||
@SerialName("411")
|
||||
IDENTITY_PHONE,
|
||||
|
||||
/**
|
||||
* The field is linked to the identity's SSN.
|
||||
*/
|
||||
@SerialName("412")
|
||||
IDENTITY_SSN,
|
||||
|
||||
/**
|
||||
* The field is linked to the identity's username.
|
||||
*/
|
||||
@SerialName("413")
|
||||
IDENTITY_USERNAME,
|
||||
|
||||
/**
|
||||
* The field is linked to the identity's passport number.
|
||||
*/
|
||||
@SerialName("414")
|
||||
IDENTITY_PASSPORT_NUMBER,
|
||||
|
||||
/**
|
||||
* The field is linked to the identity's license number.
|
||||
*/
|
||||
@SerialName("415")
|
||||
IDENTITY_LICENSE_NUMBER,
|
||||
|
||||
/**
|
||||
* The field is linked to the identity's first name.
|
||||
*/
|
||||
@SerialName("416")
|
||||
IDENTITY_FIRST_NAME,
|
||||
|
||||
/**
|
||||
* The field is linked to the identity's last name.
|
||||
*/
|
||||
@SerialName("417")
|
||||
IDENTITY_LAST_NAME,
|
||||
|
||||
/**
|
||||
* The field is linked to the identity's full name.
|
||||
*/
|
||||
@SerialName("418")
|
||||
IDENTITY_FULL_NAME,
|
||||
// endregion IDENTITY
|
||||
}
|
||||
|
||||
private class LinkedIdTypeSerializer :
|
||||
BaseEnumeratedIntSerializer<LinkedIdTypeJson>(LinkedIdTypeJson.values())
|
|
@ -0,0 +1,80 @@
|
|||
package com.x8bit.bitwarden.data.vault.datasource.network.model
|
||||
|
||||
import com.x8bit.bitwarden.data.platform.datasource.network.serializer.BaseEnumeratedIntSerializer
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
/**
|
||||
* Represents different types of policies.
|
||||
*/
|
||||
@Serializable(PolicyTypeSerializer::class)
|
||||
enum class PolicyTypeJson {
|
||||
/**
|
||||
* Requires users to have 2FA enabled.
|
||||
*/
|
||||
@SerialName("0")
|
||||
TWO_FACTOR_AUTHENTICATION,
|
||||
|
||||
/**
|
||||
* Sets minimum requirements for master password complexity.
|
||||
*/
|
||||
@SerialName("1")
|
||||
MASTER_PASSWORD,
|
||||
|
||||
/**
|
||||
* Sets minimum requirements/default type for generated passwords/passphrases.
|
||||
*/
|
||||
@SerialName("2")
|
||||
PASSWORD_GENERATOR,
|
||||
|
||||
/**
|
||||
* Allows users to only be apart of one organization.
|
||||
*/
|
||||
@SerialName("3")
|
||||
ONLY_ORG,
|
||||
|
||||
/**
|
||||
* Requires users to authenticate with SSO.
|
||||
*/
|
||||
@SerialName("4")
|
||||
REQUIRE_SSO,
|
||||
|
||||
/**
|
||||
* Disables personal vault ownership for adding/cloning items.
|
||||
*/
|
||||
@SerialName("5")
|
||||
PERSONAL_OWNERSHIP,
|
||||
|
||||
/**
|
||||
* Disables the ability to create and edit Sends.
|
||||
*/
|
||||
@SerialName("6")
|
||||
DISABLE_SEND,
|
||||
|
||||
/**
|
||||
* Sets restrictions or defaults for Bitwarden Sends.
|
||||
*/
|
||||
@SerialName("7")
|
||||
SEND_OPTIONS,
|
||||
|
||||
/**
|
||||
* Allows orgs to use reset password : also can enable auto-enrollment during invite flow.
|
||||
*/
|
||||
@SerialName("8")
|
||||
RESET_PASSWORD,
|
||||
|
||||
/**
|
||||
* Sets the maximum allowed vault timeout.
|
||||
*/
|
||||
@SerialName("9")
|
||||
MAXIMUM_VAULT_TIMEOUT,
|
||||
|
||||
/**
|
||||
* Disable personal vault export.
|
||||
*/
|
||||
@SerialName("10")
|
||||
DISABLE_PERSONAL_VAULT_EXPORT,
|
||||
}
|
||||
|
||||
private class PolicyTypeSerializer :
|
||||
BaseEnumeratedIntSerializer<PolicyTypeJson>(PolicyTypeJson.values())
|
|
@ -0,0 +1,20 @@
|
|||
package com.x8bit.bitwarden.data.vault.datasource.network.model
|
||||
|
||||
import com.x8bit.bitwarden.data.platform.datasource.network.serializer.BaseEnumeratedIntSerializer
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
/**
|
||||
* Represents different types of secure notes.
|
||||
*/
|
||||
@Serializable(SecureNoteTypeSerializer::class)
|
||||
enum class SecureNoteTypeJson {
|
||||
/**
|
||||
* A generic note.
|
||||
*/
|
||||
@SerialName("0")
|
||||
GENERIC,
|
||||
}
|
||||
|
||||
private class SecureNoteTypeSerializer :
|
||||
BaseEnumeratedIntSerializer<SecureNoteTypeJson>(SecureNoteTypeJson.values())
|
|
@ -0,0 +1,26 @@
|
|||
package com.x8bit.bitwarden.data.vault.datasource.network.model
|
||||
|
||||
import com.x8bit.bitwarden.data.platform.datasource.network.serializer.BaseEnumeratedIntSerializer
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
/**
|
||||
* Represents different types of send.
|
||||
*/
|
||||
@Serializable(SendTypeSerializer::class)
|
||||
enum class SendTypeJson {
|
||||
/**
|
||||
* The send contains text data.
|
||||
*/
|
||||
@SerialName("0")
|
||||
TEXT,
|
||||
|
||||
/**
|
||||
* The send contains an attached file.
|
||||
*/
|
||||
@SerialName("1")
|
||||
FILE,
|
||||
}
|
||||
|
||||
private class SendTypeSerializer :
|
||||
BaseEnumeratedIntSerializer<SendTypeJson>(SendTypeJson.values())
|
|
@ -1,7 +1,9 @@
|
|||
package com.x8bit.bitwarden.data.vault.datasource.network.model
|
||||
|
||||
import kotlinx.serialization.Contextual
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
import java.time.LocalDateTime
|
||||
|
||||
/**
|
||||
* Represents the response model for vault data fetched from the server.
|
||||
|
@ -14,7 +16,6 @@ import kotlinx.serialization.Serializable
|
|||
* @property domains A domains object associated with the vault data.
|
||||
* @property sends A list of send objects associated with the vault data (nullable).
|
||||
*/
|
||||
// TODO determine encrypted params and rename them to emphasize encryption in BIT-636
|
||||
@Serializable
|
||||
data class SyncResponseJson(
|
||||
@SerialName("folders")
|
||||
|
@ -68,7 +69,6 @@ data class SyncResponseJson(
|
|||
@SerialName("domains")
|
||||
val domains: List<String>?,
|
||||
|
||||
// TODO Parse type enum in BIT-636
|
||||
@SerialName("type")
|
||||
val type: Int,
|
||||
)
|
||||
|
@ -83,9 +83,9 @@ data class SyncResponseJson(
|
|||
*/
|
||||
@Serializable
|
||||
data class Folder(
|
||||
// TODO Serialize revision date in BIT-636
|
||||
@SerialName("revisionDate")
|
||||
val revisionDate: String?,
|
||||
@Contextual
|
||||
val revisionDate: LocalDateTime?, // Date
|
||||
|
||||
@SerialName("name")
|
||||
val name: String?,
|
||||
|
@ -110,9 +110,8 @@ data class SyncResponseJson(
|
|||
@SerialName("id")
|
||||
val id: String,
|
||||
|
||||
// TODO Parse type enum in BIT-636
|
||||
@SerialName("type")
|
||||
val type: Int,
|
||||
val type: PolicyTypeJson,
|
||||
|
||||
@SerialName("enabled")
|
||||
val isEnabled: Boolean,
|
||||
|
@ -257,7 +256,7 @@ data class SyncResponseJson(
|
|||
|
||||
@SerialName("keyConnectorUrl")
|
||||
val keyConnectorUrl: String?,
|
||||
// TODO Parse type enum in BIT-636
|
||||
|
||||
@SerialName("type")
|
||||
val type: Int,
|
||||
|
||||
|
@ -267,7 +266,6 @@ data class SyncResponseJson(
|
|||
@SerialName("enabled")
|
||||
val isEnabled: Boolean,
|
||||
|
||||
// TODO Parse provider type enum in BIT-636
|
||||
@SerialName("providerType")
|
||||
val providerType: Int,
|
||||
|
||||
|
@ -331,7 +329,6 @@ data class SyncResponseJson(
|
|||
@SerialName("useResetPassword")
|
||||
val shouldUseResetPassword: Boolean,
|
||||
|
||||
// TODO Parse plan product type enum in BIT-636
|
||||
@SerialName("planProductType")
|
||||
val planProductType: Int,
|
||||
|
||||
|
@ -362,9 +359,9 @@ data class SyncResponseJson(
|
|||
@SerialName("useTotp")
|
||||
val shouldUseTotp: Boolean,
|
||||
|
||||
// TODO Serialize family sponsorship last sync date in BIT-636
|
||||
@SerialName("familySponsorshipLastSyncDate")
|
||||
val familySponsorshipLastSyncDate: String?,
|
||||
@Contextual
|
||||
val familySponsorshipLastSyncDate: LocalDateTime?,
|
||||
|
||||
@SerialName("useScim")
|
||||
val shouldUseScim: Boolean,
|
||||
|
@ -412,7 +409,6 @@ data class SyncResponseJson(
|
|||
@SerialName("id")
|
||||
val id: String,
|
||||
|
||||
// TODO Parse type enum in BIT-636
|
||||
@SerialName("type")
|
||||
val type: Int,
|
||||
|
||||
|
@ -532,7 +528,7 @@ data class SyncResponseJson(
|
|||
val shouldOrganizationUseTotp: Boolean,
|
||||
|
||||
@SerialName("reprompt")
|
||||
val reprompt: Int,
|
||||
val reprompt: CipherRepromptTypeJson,
|
||||
|
||||
@SerialName("edit")
|
||||
val shouldEdit: Boolean,
|
||||
|
@ -540,20 +536,19 @@ data class SyncResponseJson(
|
|||
@SerialName("passwordHistory")
|
||||
val passwordHistory: List<PasswordHistory>?,
|
||||
|
||||
// TODO Serialize revision date in BIT-636
|
||||
@SerialName("revisionDate")
|
||||
val revisionDate: String?,
|
||||
@Contextual
|
||||
val revisionDate: LocalDateTime?,
|
||||
|
||||
// TODO Parse type enum in BIT-636
|
||||
@SerialName("type")
|
||||
val type: Int,
|
||||
val type: CipherTypeJson,
|
||||
|
||||
@SerialName("login")
|
||||
val login: Login,
|
||||
|
||||
// TODO Serialize creation date in BIT-636
|
||||
@SerialName("creationDate")
|
||||
val creationDate: String?,
|
||||
@Contextual
|
||||
val creationDate: LocalDateTime?,
|
||||
|
||||
@SerialName("secureNote")
|
||||
val secureNote: SecureNote,
|
||||
|
@ -564,9 +559,9 @@ data class SyncResponseJson(
|
|||
@SerialName("organizationId")
|
||||
val organizationId: String?,
|
||||
|
||||
// TODO Serialize deleted date in BIT-636
|
||||
@SerialName("deletedDate")
|
||||
val deletedDate: String?,
|
||||
@Contextual
|
||||
val deletedDate: LocalDateTime?,
|
||||
|
||||
@SerialName("identity")
|
||||
val identity: Identity,
|
||||
|
@ -657,7 +652,7 @@ data class SyncResponseJson(
|
|||
/**
|
||||
* Represents a field in the vault response.
|
||||
*
|
||||
* @property linkedId The linked ID of the field (nullable).
|
||||
* @property linkedIdType The linked ID of the field (nullable).
|
||||
* @property name The name of the field (nullable).
|
||||
* @property type The type of field.
|
||||
* @property value The value of the field (nullable).
|
||||
|
@ -665,14 +660,13 @@ data class SyncResponseJson(
|
|||
@Serializable
|
||||
data class Field(
|
||||
@SerialName("linkedId")
|
||||
val linkedId: String?,
|
||||
val linkedIdType: LinkedIdTypeJson?,
|
||||
|
||||
@SerialName("name")
|
||||
val name: String?,
|
||||
|
||||
// TODO Parse type enum in BIT-636
|
||||
@SerialName("type")
|
||||
val type: Int,
|
||||
val type: FieldTypeJson,
|
||||
|
||||
@SerialName("value")
|
||||
val value: String?,
|
||||
|
@ -779,9 +773,9 @@ data class SyncResponseJson(
|
|||
@SerialName("password")
|
||||
val password: String?,
|
||||
|
||||
// TODO Serialize password revision date in BIT-636
|
||||
@SerialName("passwordRevisionDate")
|
||||
val passwordRevisionDate: String?,
|
||||
@Contextual
|
||||
val passwordRevisionDate: LocalDateTime?,
|
||||
|
||||
@SerialName("autofillOnPageLoad")
|
||||
val shouldAutofillOnPageLoad: Boolean?,
|
||||
|
@ -795,13 +789,13 @@ data class SyncResponseJson(
|
|||
/**
|
||||
* Represents a URI in the vault response.
|
||||
*
|
||||
* @property match The match of the URI.
|
||||
* @property uriMatchType The match type of the URI.
|
||||
* @property uri The actual string representing the URI (nullable).
|
||||
*/
|
||||
@Serializable
|
||||
data class Uri(
|
||||
@SerialName("match")
|
||||
val match: Int,
|
||||
val uriMatchType: UriMatchTypeJson,
|
||||
|
||||
@SerialName("uri")
|
||||
val uri: String?,
|
||||
|
@ -819,9 +813,9 @@ data class SyncResponseJson(
|
|||
@SerialName("password")
|
||||
val password: String,
|
||||
|
||||
// TODO Serialize last used date in BIT-636
|
||||
@SerialName("lastUsedDate")
|
||||
val lastUsedDate: String,
|
||||
@Contextual
|
||||
val lastUsedDate: LocalDateTime,
|
||||
)
|
||||
|
||||
/**
|
||||
|
@ -831,9 +825,8 @@ data class SyncResponseJson(
|
|||
*/
|
||||
@Serializable
|
||||
data class SecureNote(
|
||||
// TODO Parse type enum in BIT-636
|
||||
@SerialName("type")
|
||||
val type: Int,
|
||||
val type: SecureNoteTypeJson,
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -865,9 +858,9 @@ data class SyncResponseJson(
|
|||
@SerialName("notes")
|
||||
val notes: String?,
|
||||
|
||||
// TODO Serialize revision date in BIT-636
|
||||
@SerialName("revisionDate")
|
||||
val revisionDate: String,
|
||||
@Contextual
|
||||
val revisionDate: LocalDateTime,
|
||||
|
||||
@SerialName("maxAccessCount")
|
||||
val maxAccessCount: Int?,
|
||||
|
@ -875,9 +868,8 @@ data class SyncResponseJson(
|
|||
@SerialName("hideEmail")
|
||||
val shouldHideEmail: Boolean,
|
||||
|
||||
// TODO Parse type enum in BIT-636
|
||||
@SerialName("type")
|
||||
val type: Int,
|
||||
val type: SendTypeJson,
|
||||
|
||||
@SerialName("accessId")
|
||||
val accessId: String?,
|
||||
|
@ -888,9 +880,9 @@ data class SyncResponseJson(
|
|||
@SerialName("file")
|
||||
val file: File,
|
||||
|
||||
// TODO Serialize deletion date in BIT-636
|
||||
@SerialName("deletionDate")
|
||||
val deletionDate: String,
|
||||
@Contextual
|
||||
val deletionDate: LocalDateTime,
|
||||
|
||||
@SerialName("name")
|
||||
val name: String?,
|
||||
|
@ -907,9 +899,9 @@ data class SyncResponseJson(
|
|||
@SerialName("key")
|
||||
val key: String?,
|
||||
|
||||
// TODO Serialize expiration date in BIT-636
|
||||
@SerialName("expirationDate")
|
||||
val expirationDate: String?,
|
||||
@Contextual
|
||||
val expirationDate: LocalDateTime?,
|
||||
) {
|
||||
/**
|
||||
* Represents a file in the vault response.
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
package com.x8bit.bitwarden.data.vault.datasource.network.model
|
||||
|
||||
import com.x8bit.bitwarden.data.platform.datasource.network.serializer.BaseEnumeratedIntSerializer
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
/**
|
||||
* Represents how a URI should be matched for autofill to occur.
|
||||
*/
|
||||
@Serializable(UriMatchTypeSerializer::class)
|
||||
enum class UriMatchTypeJson {
|
||||
/**
|
||||
* Matching of the URI is based on the domain.
|
||||
*/
|
||||
@SerialName("0")
|
||||
DOMAIN,
|
||||
|
||||
/**
|
||||
* Matching of the URI is based on the host.
|
||||
*/
|
||||
@SerialName("1")
|
||||
HOST,
|
||||
|
||||
/**
|
||||
* Matching of the URI is based the start of resource.
|
||||
*/
|
||||
@SerialName("2")
|
||||
STARTS_WITH,
|
||||
|
||||
/**
|
||||
* Matching of the URI requires an exact match.
|
||||
*/
|
||||
@SerialName("3")
|
||||
EXACT,
|
||||
|
||||
/**
|
||||
* Requires users to authenticate with SSO.
|
||||
*/
|
||||
@SerialName("4")
|
||||
REGULAR_EXPRESSION,
|
||||
|
||||
/**
|
||||
* The URI should never be autofilled.
|
||||
*/
|
||||
@SerialName("5")
|
||||
NEVER,
|
||||
}
|
||||
|
||||
private class UriMatchTypeSerializer :
|
||||
BaseEnumeratedIntSerializer<UriMatchTypeJson>(UriMatchTypeJson.values())
|
|
@ -0,0 +1,96 @@
|
|||
package com.x8bit.bitwarden.data.platform.datasource.network.serializer
|
||||
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.json.Json
|
||||
import kotlinx.serialization.json.encodeToJsonElement
|
||||
import kotlinx.serialization.modules.SerializersModule
|
||||
import org.junit.jupiter.api.Assertions.assertEquals
|
||||
import org.junit.jupiter.api.Test
|
||||
import java.time.LocalDateTime
|
||||
|
||||
class LocalDateTimeSerializerTest {
|
||||
private val json = Json {
|
||||
serializersModule = SerializersModule {
|
||||
contextual(LocalDateTime::class, LocalDateTimeSerializer())
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `properly deserializes raw JSON to LocalDate`() {
|
||||
assertEquals(
|
||||
LocalDateTimeData(
|
||||
dataAsLocalDateTime = LocalDateTime.of(
|
||||
2023,
|
||||
10,
|
||||
6,
|
||||
17,
|
||||
22,
|
||||
28,
|
||||
440000000,
|
||||
),
|
||||
),
|
||||
json.decodeFromString<LocalDateTimeData>(
|
||||
"""
|
||||
{
|
||||
"dataAsLocalDateTime": "2023-10-06T17:22:28.44Z"
|
||||
}
|
||||
""",
|
||||
),
|
||||
)
|
||||
}
|
||||
@Test
|
||||
fun `properly deserializes raw JSON with nano seconds to LocalDate`() {
|
||||
assertEquals(
|
||||
LocalDateTimeData(
|
||||
dataAsLocalDateTime = LocalDateTime.of(
|
||||
2023,
|
||||
10,
|
||||
6,
|
||||
17,
|
||||
22,
|
||||
28,
|
||||
446666700,
|
||||
),
|
||||
),
|
||||
json.decodeFromString<LocalDateTimeData>(
|
||||
"""
|
||||
{
|
||||
"dataAsLocalDateTime": "2023-10-06T17:22:28.4466667Z"
|
||||
}
|
||||
""",
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `properly serializes external model back to raw JSON`() {
|
||||
assertEquals(
|
||||
json.parseToJsonElement(
|
||||
"""
|
||||
{
|
||||
"dataAsLocalDateTime": "2023-10-06T17:22:28.44Z"
|
||||
}
|
||||
""",
|
||||
),
|
||||
json.encodeToJsonElement(
|
||||
LocalDateTimeData(
|
||||
dataAsLocalDateTime = LocalDateTime.of(
|
||||
2023,
|
||||
10,
|
||||
6,
|
||||
17,
|
||||
22,
|
||||
28,
|
||||
440000000,
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Serializable
|
||||
private data class LocalDateTimeData(
|
||||
@Serializable(LocalDateTimeSerializer::class)
|
||||
val dataAsLocalDateTime: LocalDateTime,
|
||||
)
|
Loading…
Reference in a new issue