diff --git a/app/src/main/kotlin/com/x8bit/bitwarden/data/vault/repository/util/VaultSdkSendExtensions.kt b/app/src/main/kotlin/com/x8bit/bitwarden/data/vault/repository/util/VaultSdkSendExtensions.kt index 2899442f37..1a8c70547f 100644 --- a/app/src/main/kotlin/com/x8bit/bitwarden/data/vault/repository/util/VaultSdkSendExtensions.kt +++ b/app/src/main/kotlin/com/x8bit/bitwarden/data/vault/repository/util/VaultSdkSendExtensions.kt @@ -1,6 +1,9 @@ +@file:Suppress("TooManyFunctions") + package com.x8bit.bitwarden.data.vault.repository.util import com.bitwarden.core.data.repository.util.SpecialCharWithPrecedenceComparator +import com.bitwarden.network.model.SendAuthTypeJson import com.bitwarden.network.model.SendJsonRequest import com.bitwarden.network.model.SendTypeJson import com.bitwarden.network.model.SyncResponseJson @@ -31,6 +34,8 @@ fun Send.toEncryptedNetworkSend(fileLength: Long? = null): SendJsonRequest = password = password, isDisabled = disabled, shouldHideEmail = hideEmail, + authType = authType.toNetworkSendAuthType(), + emails = emails, ) /** @@ -93,10 +98,31 @@ fun SyncResponseJson.Send.toEncryptedSdkSend(): Send = revisionDate = revisionDate.toInstant(), deletionDate = deletionDate.toInstant(), expirationDate = expirationDate?.toInstant(), - emails = null, - authType = AuthType.NONE, + emails = emails, + authType = authType?.toSdkAuthType() ?: AuthType.NONE, ) +/** + * Converts a Bitwarden SDK [AuthType] object to a corresponding [SendAuthTypeJson] object. + */ +private fun AuthType.toNetworkSendAuthType(): SendAuthTypeJson = + when (this) { + AuthType.EMAIL -> SendAuthTypeJson.EMAIL + AuthType.PASSWORD -> SendAuthTypeJson.PASSWORD + AuthType.NONE -> SendAuthTypeJson.NONE + } + +/** + * Converts a [SendAuthTypeJson] objects to a corresponding + * Bitwarden SDK [AuthType]. + */ +private fun SendAuthTypeJson.toSdkAuthType(): AuthType = + when (this) { + SendAuthTypeJson.PASSWORD -> AuthType.PASSWORD + SendAuthTypeJson.EMAIL -> AuthType.EMAIL + SendAuthTypeJson.NONE -> AuthType.NONE + } + /** * Converts a [SyncResponseJson.Send.Text] object to a corresponding * Bitwarden SDK [SendText] object. diff --git a/app/src/test/kotlin/com/x8bit/bitwarden/data/vault/datasource/disk/VaultDiskSourceTest.kt b/app/src/test/kotlin/com/x8bit/bitwarden/data/vault/datasource/disk/VaultDiskSourceTest.kt index 05c61b2341..02642cb8f7 100644 --- a/app/src/test/kotlin/com/x8bit/bitwarden/data/vault/datasource/disk/VaultDiskSourceTest.kt +++ b/app/src/test/kotlin/com/x8bit/bitwarden/data/vault/datasource/disk/VaultDiskSourceTest.kt @@ -584,7 +584,8 @@ private const val SEND_JSON = """ "text": "mockText-1" }, "key": "mockKey-1", - "expirationDate": "2023-10-27T12:00:00.000Z" + "expirationDate": "2023-10-27T12:00:00.000Z", + "authType": 1 } """ diff --git a/app/src/test/kotlin/com/x8bit/bitwarden/data/vault/datasource/sdk/model/VaultSdkSendUtil.kt b/app/src/test/kotlin/com/x8bit/bitwarden/data/vault/datasource/sdk/model/VaultSdkSendUtil.kt index d52344e0ce..53059c5cfe 100644 --- a/app/src/test/kotlin/com/x8bit/bitwarden/data/vault/datasource/sdk/model/VaultSdkSendUtil.kt +++ b/app/src/test/kotlin/com/x8bit/bitwarden/data/vault/datasource/sdk/model/VaultSdkSendUtil.kt @@ -32,7 +32,7 @@ fun createMockSdkSend( deletionDate = ZonedDateTime.parse("2023-10-27T12:00:00Z").toInstant(), expirationDate = ZonedDateTime.parse("2023-10-27T12:00:00Z").toInstant(), emails = null, - authType = AuthType.NONE, + authType = AuthType.PASSWORD, ) /** diff --git a/network/src/main/kotlin/com/bitwarden/network/model/SendAuthTypeJson.kt b/network/src/main/kotlin/com/bitwarden/network/model/SendAuthTypeJson.kt new file mode 100644 index 0000000000..b97072e1f4 --- /dev/null +++ b/network/src/main/kotlin/com/bitwarden/network/model/SendAuthTypeJson.kt @@ -0,0 +1,36 @@ +package com.bitwarden.network.model + +import androidx.annotation.Keep +import com.bitwarden.core.data.serializer.BaseEnumeratedIntSerializer +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +/** + * Represents different types of send Authentication. + */ +@Serializable(SendAuthTypeSerializer::class) +enum class SendAuthTypeJson { + /** + * Email-based OTP authentication. + */ + @SerialName("0") + EMAIL, + + /** + * Password-based authentication. + */ + @SerialName("1") + PASSWORD, + + /** + * No authentication required. + */ + @SerialName("2") + NONE, +} + +@Keep +private class SendAuthTypeSerializer : BaseEnumeratedIntSerializer( + className = "SendAuthTypeJson", + values = SendAuthTypeJson.entries.toTypedArray(), +) diff --git a/network/src/main/kotlin/com/bitwarden/network/model/SendJsonRequest.kt b/network/src/main/kotlin/com/bitwarden/network/model/SendJsonRequest.kt index 4647c26808..18d2e2c2c0 100644 --- a/network/src/main/kotlin/com/bitwarden/network/model/SendJsonRequest.kt +++ b/network/src/main/kotlin/com/bitwarden/network/model/SendJsonRequest.kt @@ -9,6 +9,7 @@ import java.time.ZonedDateTime * Represents a send request. * * @property type The type of send. + * @property authType The type of authentication method required to access this Send. * @property name The name of the send (nullable). * @property notes The notes of the send (nullable). * @property key The send key. @@ -21,12 +22,16 @@ import java.time.ZonedDateTime * @property password The password protecting this send (nullable). * @property isDisabled Indicate if this send is disabled. * @property shouldHideEmail Should the email address of the sender be hidden (nullable). + * @property emails The emails allowed to authenticate this send (nullable). */ @Serializable data class SendJsonRequest( @SerialName("type") val type: SendTypeJson, + @SerialName("authType") + val authType: SendAuthTypeJson?, + @SerialName("name") val name: String?, @@ -64,4 +69,7 @@ data class SendJsonRequest( @SerialName("hideEmail") val shouldHideEmail: Boolean?, + + @SerialName("emails") + val emails: String?, ) diff --git a/network/src/main/kotlin/com/bitwarden/network/model/SyncResponseJson.kt b/network/src/main/kotlin/com/bitwarden/network/model/SyncResponseJson.kt index 12505132f4..4a6fefed0b 100644 --- a/network/src/main/kotlin/com/bitwarden/network/model/SyncResponseJson.kt +++ b/network/src/main/kotlin/com/bitwarden/network/model/SyncResponseJson.kt @@ -899,8 +899,12 @@ data class SyncResponseJson( * @property maxAccessCount The max access count of the send object (nullable). * @property shouldHideEmail If the send object should hide the email. * @property type The type of send object. + * @property authType Specifies the authentication method required to access this Send. * @property accessId The access ID of the send object (nullable). * @property password The password of the send object (nullable). + * Mutually exclusive with [emails] + * @property emails Comma-separated list of emails that may access the send using OTP + * authentication. Mutually exclusive with [password] * @property file The file of the send object. * @property deletionDate The max access count of the send object. * @property name The name of the send object (nullable). @@ -931,12 +935,18 @@ data class SyncResponseJson( @SerialName("type") val type: SendTypeJson, + @SerialName("authType") + val authType: SendAuthTypeJson?, + @SerialName("accessId") val accessId: String?, @SerialName("password") val password: String?, + @SerialName("emails") + val emails: String?, + @SerialName("file") val file: File?, diff --git a/network/src/test/kotlin/com/bitwarden/network/service/SendsServiceTest.kt b/network/src/test/kotlin/com/bitwarden/network/service/SendsServiceTest.kt index a18e3e34a4..5292f3346a 100644 --- a/network/src/test/kotlin/com/bitwarden/network/service/SendsServiceTest.kt +++ b/network/src/test/kotlin/com/bitwarden/network/service/SendsServiceTest.kt @@ -226,7 +226,8 @@ private const val CREATE_UPDATE_SEND_SUCCESS_JSON = """ "revisionDate": "2023-10-27T12:00:00.00Z", "expirationDate": "2023-10-27T12:00:00.00Z", "deletionDate": "2023-10-27T12:00:00.00Z", - "hideEmail": false + "hideEmail": false, + "authType": 1, } """ @@ -258,7 +259,8 @@ private const val CREATE_FILE_SEND_SUCCESS_JSON = """ "revisionDate": "2023-10-27T12:00:00.00Z", "expirationDate": "2023-10-27T12:00:00.00Z", "deletionDate": "2023-10-27T12:00:00.00Z", - "hideEmail": false + "hideEmail": false, + "authType": 1 } } """ diff --git a/network/src/test/kotlin/com/bitwarden/network/service/SyncServiceTest.kt b/network/src/test/kotlin/com/bitwarden/network/service/SyncServiceTest.kt index 4d6d0515ab..bf134c98c4 100644 --- a/network/src/test/kotlin/com/bitwarden/network/service/SyncServiceTest.kt +++ b/network/src/test/kotlin/com/bitwarden/network/service/SyncServiceTest.kt @@ -388,7 +388,8 @@ private const val SYNC_SUCCESS_JSON = """ "text": "mockText-1" }, "key": "mockKey-1", - "expirationDate": "2023-10-27T12:00:00.00Z" + "expirationDate": "2023-10-27T12:00:00.00Z", + "authType": 1 } ] } diff --git a/network/src/testFixtures/kotlin/com/bitwarden/network/model/SendJsonRequestUtil.kt b/network/src/testFixtures/kotlin/com/bitwarden/network/model/SendJsonRequestUtil.kt index 974154c956..2a83e3d72d 100644 --- a/network/src/testFixtures/kotlin/com/bitwarden/network/model/SendJsonRequestUtil.kt +++ b/network/src/testFixtures/kotlin/com/bitwarden/network/model/SendJsonRequestUtil.kt @@ -21,6 +21,8 @@ fun createMockSendJsonRequest( password: String? = "mockPassword-$number", isDisabled: Boolean = false, shouldHideEmail: Boolean? = false, + authTypeJson: SendAuthTypeJson = SendAuthTypeJson.PASSWORD, + emails: String? = null, ): SendJsonRequest = SendJsonRequest( name = name, @@ -36,4 +38,6 @@ fun createMockSendJsonRequest( password = password, isDisabled = isDisabled, shouldHideEmail = shouldHideEmail, + authType = authTypeJson, + emails = emails, ) diff --git a/network/src/testFixtures/kotlin/com/bitwarden/network/model/SyncResponseSendUtil.kt b/network/src/testFixtures/kotlin/com/bitwarden/network/model/SyncResponseSendUtil.kt index 7b53b48492..495c96f3e7 100644 --- a/network/src/testFixtures/kotlin/com/bitwarden/network/model/SyncResponseSendUtil.kt +++ b/network/src/testFixtures/kotlin/com/bitwarden/network/model/SyncResponseSendUtil.kt @@ -39,6 +39,8 @@ fun createMockSend( text: SyncResponseJson.Send.Text? = createMockText(number = number), key: String? = "mockKey-$number", expirationDate: ZonedDateTime? = ZonedDateTime.parse("2023-10-27T12:00:00Z"), + authTypeJson: SendAuthTypeJson = SendAuthTypeJson.PASSWORD, + emails: String? = null, ): SyncResponseJson.Send = SyncResponseJson.Send( accessCount = accessCount, @@ -57,6 +59,8 @@ fun createMockSend( text = text, key = key, expirationDate = expirationDate, + authType = authTypeJson, + emails = emails, ) /**