diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/SetPassportDataErrors.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/SetPassportDataErrors.kt new file mode 100644 index 0000000000..3bb3b34e74 --- /dev/null +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/SetPassportDataErrors.kt @@ -0,0 +1,19 @@ +package dev.inmo.tgbotapi.requests + +import dev.inmo.tgbotapi.requests.abstracts.Request +import dev.inmo.tgbotapi.types.* +import dev.inmo.tgbotapi.types.passport.errors.PassportElementError +import kotlinx.serialization.* +import kotlinx.serialization.builtins.serializer + +@Serializable +data class SetPassportDataErrors( + @SerialName(userIdField) + val user: UserId, + @SerialName(errorsField) + val errors: List +) : Request { + override val resultDeserializer: DeserializationStrategy + get() = Boolean.serializer() + override fun method(): String = "setPassportDataErrors" +} diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/Common.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/Common.kt index d73d87bb2c..7346a72269 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/Common.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/Common.kt @@ -362,8 +362,20 @@ const val dataField = "data" const val credentialsField = "credentials" const val hashField = "hash" const val translationField = "translation" +const val translationFileField = "translation_file" +const val fileField = "file" const val filesField = "files" +const val translationFilesField = "translation_files" const val frontSideField = "front_side" const val reverseSideField = "reverse_side" const val selfieField = "selfie" const val secretField = "secret" + +const val errorsField = "errors" +const val sourceField = "source" +const val fieldNameField = "field_name" +const val dataHashField = "data_hash" +const val fileHashField = "file_hash" +const val fileHashesField = "file_hashes" +const val messageField = "message" +const val unspecifiedField = "unspecified" diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/encrypted_data/EncryptedElementSerializer.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/encrypted_data/EncryptedElementSerializer.kt index 5499e76b22..28caca9889 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/encrypted_data/EncryptedElementSerializer.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/encrypted_data/EncryptedElementSerializer.kt @@ -5,6 +5,7 @@ import dev.inmo.tgbotapi.types.hashField import dev.inmo.tgbotapi.types.passport.encrypted_data.abstracts.EncryptedPassportElement import dev.inmo.tgbotapi.types.passport.encrypted_data.abstracts.UnknownEncryptedPassportElement import dev.inmo.tgbotapi.types.typeField +import dev.inmo.tgbotapi.utils.RiskFeature import dev.inmo.tgbotapi.utils.nonstrictJsonFormat import kotlinx.serialization.KSerializer import kotlinx.serialization.Serializer @@ -29,6 +30,10 @@ val encryptedElementsClassesByTypes = mapOf( "email" to Encapsulator(Email::class, Email.serializer()) ) +@RiskFeature("Remember that this method may return \"unknown\" in case if encrypted element was not defined in library") +val EncryptedPassportElement.type: String + get() = encryptedElementsClassesByTypes.keys.firstOrNull { encryptedElementsClassesByTypes.getValue(it).klass.isInstance(this) } ?: "unknown" + @Serializer(EncryptedPassportElement::class) object EncryptedElementSerializer : KSerializer { private val jsonSerializer = JsonObject.serializer() diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/errors/PassportElementError.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/errors/PassportElementError.kt new file mode 100644 index 0000000000..d7526eee44 --- /dev/null +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/errors/PassportElementError.kt @@ -0,0 +1,229 @@ +package dev.inmo.tgbotapi.types.passport.errors + +import dev.inmo.micro_utils.serialization.base64.Base64StringSerializer +import dev.inmo.tgbotapi.types.* +import dev.inmo.tgbotapi.types.passport.encrypted_data.abstracts.* +import dev.inmo.tgbotapi.types.passport.encrypted_data.type +import kotlinx.serialization.* +import kotlinx.serialization.encoding.Encoder + +@Serializable(PassportElementErrorSerializer::class) +sealed class PassportElementError { + abstract val source: String + abstract val type: String + abstract val message: String +} + +@Serializer(PassportElementError::class) +internal object PassportElementErrorSerializer : KSerializer { + override fun serialize(encoder: Encoder, value: PassportElementError) { + val neverMindAboutThisVariable = when (value) { + is PassportElementErrorFrontSide -> PassportElementErrorFrontSide.serializer().serialize(encoder, value) + is PassportElementErrorReverseSide -> PassportElementErrorReverseSide.serializer().serialize(encoder, value) + is PassportElementErrorSelfie -> PassportElementErrorSelfie.serializer().serialize(encoder, value) + is PassportElementErrorFile -> PassportElementErrorFile.serializer().serialize(encoder, value) + is PassportElementErrorTranslationFile -> PassportElementErrorTranslationFile.serializer().serialize(encoder, value) + is PassportElementErrorUnspecified -> PassportElementErrorUnspecified.serializer().serialize(encoder, value) + is PassportElementErrorDataField -> PassportElementErrorDataField.serializer().serialize(encoder, value) + is PassportElementErrorFiles -> PassportElementErrorFiles.serializer().serialize(encoder, value) + is PassportElementErrorTranslationFiles -> PassportElementErrorTranslationFiles.serializer().serialize(encoder, value) + } + } +} + +@Serializable +sealed class PassportSingleElementError : PassportElementError() { + abstract val elementHash: String +} + +@Serializable +sealed class PassportMultipleElementsError : PassportElementError() { + abstract val elementsHashes: List +} + +@Serializable +sealed class PassportElementFileError : PassportSingleElementError() + +@Serializable +sealed class PassportElementFilesError : PassportMultipleElementsError() + +@Serializable +data class PassportElementErrorDataField( + @SerialName(typeField) + override val type: String, + @SerialName(fieldNameField) + val fieldName: String, + @SerialName(dataHashField) + @Serializable(Base64StringSerializer::class) + override val elementHash: String, + @SerialName(messageField) + override val message: String +) : PassportSingleElementError() { + @SerialName(sourceField) + @Required + override val source: String = dataField +} +fun WithData.createDataError(field: String, message: String) = PassportElementErrorDataField( + type, + field, + hash, + message +) + +@Serializable +data class PassportElementErrorFrontSide( + @SerialName(typeField) + override val type: String, + @SerialName(fileHashField) + @Serializable(Base64StringSerializer::class) + override val elementHash: String, + @SerialName(messageField) + override val message: String +) : PassportElementFileError() { + @SerialName(sourceField) + @Required + override val source: String = frontSideField +} +fun WithFrontSide.createFrontSideError(message: String, unencryptedFileHash: String) = PassportElementErrorFrontSide( + type, + unencryptedFileHash, + message +) + +@Serializable +data class PassportElementErrorReverseSide( + @SerialName(typeField) + override val type: String, + @SerialName(fileHashField) + @Serializable(Base64StringSerializer::class) + override val elementHash: String, + @SerialName(messageField) + override val message: String +) : PassportElementFileError() { + @SerialName(sourceField) + @Required + override val source: String = reverseSideField +} +fun WithReverseSide.createReverseSideError(message: String, unencryptedFileHash: String) = PassportElementErrorReverseSide( + type, + unencryptedFileHash, + message +) +@Serializable +data class PassportElementErrorSelfie( + @SerialName(typeField) + override val type: String, + @SerialName(fileHashField) + @Serializable(Base64StringSerializer::class) + override val elementHash: String, + @SerialName(messageField) + override val message: String +) : PassportElementFileError() { + @SerialName(sourceField) + @Required + override val source: String = selfieField +} +fun WithSelfie.createSelfieError(message: String, unencryptedFileHash: String) = PassportElementErrorSelfie( + type, + unencryptedFileHash, + message +) + + +@Serializable +data class PassportElementErrorFile( + @SerialName(typeField) + override val type: String, + @SerialName(fileHashField) + @Serializable(Base64StringSerializer::class) + override val elementHash: String, + @SerialName(messageField) + override val message: String +) : PassportElementFileError() { + @SerialName(sourceField) + @Required + override val source: String = fileField +} +fun FilesCollection.createFileError(message: String, unencryptedFileHash: String) = PassportElementErrorFile( + type, + unencryptedFileHash, + message +) + +@Serializable +data class PassportElementErrorFiles( + @SerialName(typeField) + override val type: String, + @SerialName(fileHashesField) + override val elementsHashes: List<@Serializable(Base64StringSerializer::class) String>, + @SerialName(messageField) + override val message: String +) : PassportElementFilesError() { + @SerialName(sourceField) + @Required + override val source: String = filesField +} +fun FilesCollection.createFilesError(message: String, unencryptedFileHashes: List) = PassportElementErrorFiles( + type, + unencryptedFileHashes, + message +) + + +@Serializable +data class PassportElementErrorTranslationFile( + @SerialName(typeField) + override val type: String, + @SerialName(fileHashField) + @Serializable(Base64StringSerializer::class) + override val elementHash: String, + @SerialName(messageField) + override val message: String +) : PassportElementFileError() { + @SerialName(sourceField) + @Required + override val source: String = translationFileField +} +fun Translatable.createFileError(message: String, unencryptedFileHash: String) = PassportElementErrorTranslationFile( + type, + unencryptedFileHash, + message +) +@Serializable +data class PassportElementErrorTranslationFiles( + @SerialName(typeField) + override val type: String, + @SerialName(fileHashesField) + override val elementsHashes: List<@Serializable(Base64StringSerializer::class) String>, + @SerialName(messageField) + override val message: String +) : PassportElementFilesError() { + @SerialName(sourceField) + @Required + override val source: String = translationFilesField +} +fun Translatable.createFilesError(message: String, unencryptedFileHashes: List) = PassportElementErrorTranslationFiles( + type, + unencryptedFileHashes, + message +) + +@Serializable +data class PassportElementErrorUnspecified( + @SerialName(typeField) + override val type: String, + @SerialName(fileHashField) + @Serializable(Base64StringSerializer::class) + override val elementHash: String, + @SerialName(messageField) + override val message: String +) : PassportElementFileError() { + @SerialName(sourceField) + @Required + override val source: String = unspecifiedField +} +fun EncryptedPassportElement.createUnspecifiedError(message: String, elementHash: String) = PassportElementErrorUnspecified( + type, + elementHash, + message +)