diff --git a/.github/workflows/regular-build.yml b/.github/workflows/regular-build.yml new file mode 100644 index 0000000000..ceab9f2734 --- /dev/null +++ b/.github/workflows/regular-build.yml @@ -0,0 +1,16 @@ +name: Build + +on: [push] + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + - name: Set up JDK 1.8 + uses: actions/setup-java@v1 + with: + java-version: 1.8 + - name: Build with Gradle + run: ./gradlew build diff --git a/CHANGELOG.md b/CHANGELOG.md index 0bbbc0ccb7..b1203c11fb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,9 @@ * `Common`: * `Version`: - * `MicroUtils`: `0.4.16` -> `0.4.21` + * `MicroUtils`: `0.4.16` -> `0.4.23` + * `Klock`: `0.2.3` -> `0.2.4` + * `Ktor`: `1.5.0` -> `1.5.1` * `Core`: * **BREAKING CHANGE** Now `MediaGroupMessage` have a generic type related to `MediaGroupContent` * Methods and types related to `MediaGroupMessage` have been modified according to their meanings @@ -19,6 +21,8 @@ * `onVisualMediaGroup` now is just an alternative to `onVisualGallery` * `command` and `onCommand` expectations has been added for commands `String` variant * New extensions `BehaviourContext#oneOf`, `BehaviourContext#parallel` and `Deferred#withAction` +* `API`: + * **PASSPORT** New extensions `TelegramBot#setPassportDataErrors` ## 0.31.0 diff --git a/gradle.properties b/gradle.properties index 5017be276e..710eeb454a 100644 --- a/gradle.properties +++ b/gradle.properties @@ -8,11 +8,11 @@ kotlin.incremental.js=true kotlin_version=1.4.21 kotlin_coroutines_version=1.4.2 kotlin_serialisation_runtime_version=1.0.1 -klock_version=2.0.3 +klock_version=2.0.4 uuid_version=0.2.3 -ktor_version=1.5.0 +ktor_version=1.5.1 -micro_utils_version=0.4.21 +micro_utils_version=0.4.23 javax_activation_version=1.1.1 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 7346a72269..44c9955298 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 @@ -379,3 +379,17 @@ const val fileHashField = "file_hash" const val fileHashesField = "file_hashes" const val messageField = "message" const val unspecifiedField = "unspecified" + +const val secureDataField = "secure_data" +const val nonceField = "nonce" + +const val personalDetailsField = "personal_details" +const val passportField = "passport" +const val internalPassportField = "internal_passport" +const val driverLicenseField = "driver_license" +const val identityCardField = "identity_card" +const val utilityBillField = "utility_bill" +const val bankStatementField = "bank_statement" +const val rentalAgreementField = "rental_agreement" +const val passportRegistrationField = "passport_registration" +const val temporaryRegistrationField = "temporary_registration" diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/EncryptedData.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/EncryptedData.kt deleted file mode 100644 index ce198b65da..0000000000 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/EncryptedData.kt +++ /dev/null @@ -1,23 +0,0 @@ -package dev.inmo.tgbotapi.types.passport - -import dev.inmo.micro_utils.serialization.base64.Base64StringSerializer -import dev.inmo.tgbotapi.types.* -import kotlinx.serialization.SerialName -import kotlinx.serialization.Serializable - -typealias EncryptedAndBase64EncodedData = String -typealias EncryptedByBotPublicKeyData = String -typealias EncryptedData = String - -@Serializable -data class EncryptedCredentials( - @SerialName(dataField) - @Serializable(Base64StringSerializer::class) - val data: EncryptedData, - @SerialName(hashField) - @Serializable(Base64StringSerializer::class) - val hash: String, - @SerialName(secretField) - @Serializable(Base64StringSerializer::class) - val secret: EncryptedByBotPublicKeyData -) diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/PassportData.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/PassportData.kt index 9bf4884791..9a55da08ab 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/PassportData.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/PassportData.kt @@ -2,7 +2,8 @@ package dev.inmo.tgbotapi.types.passport import dev.inmo.tgbotapi.types.credentialsField import dev.inmo.tgbotapi.types.dataField -import dev.inmo.tgbotapi.types.passport.encrypted_data.abstracts.EncryptedPassportElement +import dev.inmo.tgbotapi.types.passport.credentials.EncryptedCredentials +import dev.inmo.tgbotapi.types.passport.encrypted.abstracts.EncryptedPassportElement import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/PassportElementError.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/PassportElementError.kt index a3cf28594a..9db2e83596 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/PassportElementError.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/PassportElementError.kt @@ -4,10 +4,10 @@ package dev.inmo.tgbotapi.types.passport import dev.inmo.micro_utils.crypto.MD5 import dev.inmo.micro_utils.crypto.md5 -import dev.inmo.micro_utils.serialization.base64.Base64StringSerializer +import dev.inmo.micro_utils.serialization.base64.Base64BytesToFromStringSerializer import dev.inmo.tgbotapi.types.* -import dev.inmo.tgbotapi.types.passport.encrypted_data.abstracts.* -import dev.inmo.tgbotapi.types.passport.encrypted_data.type +import dev.inmo.tgbotapi.types.passport.encrypted.abstracts.* +import dev.inmo.tgbotapi.types.passport.encrypted.type import dev.inmo.tgbotapi.utils.nonstrictJsonFormat import kotlinx.serialization.* import kotlinx.serialization.descriptors.SerialDescriptor @@ -70,12 +70,12 @@ object PassportElementErrorSerializer : KSerializer { @Serializable sealed class PassportSingleElementError : PassportElementError() { - abstract val elementHash: String + abstract val elementHash: PassportElementHash } @Serializable sealed class PassportMultipleElementsError : PassportElementError() { - abstract val elementsHashes: List + abstract val elementsHashes: List } @Serializable @@ -91,8 +91,8 @@ data class PassportElementErrorDataField( @SerialName(fieldNameField) val fieldName: String, @SerialName(dataHashField) - @Serializable(Base64StringSerializer::class) - override val elementHash: String, + @Serializable(Base64BytesToFromStringSerializer::class) + override val elementHash: PassportElementHash, @SerialName(messageField) override val message: String ) : PassportSingleElementError() { @@ -112,8 +112,8 @@ data class PassportElementErrorFrontSide( @SerialName(typeField) override val type: String, @SerialName(fileHashField) - @Serializable(Base64StringSerializer::class) - override val elementHash: String, + @Serializable(Base64BytesToFromStringSerializer::class) + override val elementHash: PassportElementHash, @SerialName(messageField) override val message: String ) : PassportElementFileError() { @@ -121,7 +121,7 @@ data class PassportElementErrorFrontSide( @Required override val source: String = frontSideField } -fun WithFrontSide.createFrontSideError(message: String, unencryptedFileHash: String) = PassportElementErrorFrontSide( +fun WithFrontSide.createFrontSideError(message: String, unencryptedFileHash: PassportElementHash) = PassportElementErrorFrontSide( type, unencryptedFileHash, message @@ -132,8 +132,8 @@ data class PassportElementErrorReverseSide( @SerialName(typeField) override val type: String, @SerialName(fileHashField) - @Serializable(Base64StringSerializer::class) - override val elementHash: String, + @Serializable(Base64BytesToFromStringSerializer::class) + override val elementHash: PassportElementHash, @SerialName(messageField) override val message: String ) : PassportElementFileError() { @@ -141,7 +141,7 @@ data class PassportElementErrorReverseSide( @Required override val source: String = reverseSideField } -fun WithReverseSide.createReverseSideError(message: String, unencryptedFileHash: String) = PassportElementErrorReverseSide( +fun WithReverseSide.createReverseSideError(message: String, unencryptedFileHash: PassportElementHash) = PassportElementErrorReverseSide( type, unencryptedFileHash, message @@ -151,8 +151,8 @@ data class PassportElementErrorSelfie( @SerialName(typeField) override val type: String, @SerialName(fileHashField) - @Serializable(Base64StringSerializer::class) - override val elementHash: String, + @Serializable(Base64BytesToFromStringSerializer::class) + override val elementHash: PassportElementHash, @SerialName(messageField) override val message: String ) : PassportElementFileError() { @@ -160,7 +160,7 @@ data class PassportElementErrorSelfie( @Required override val source: String = selfieField } -fun WithSelfie.createSelfieError(message: String, unencryptedFileHash: String) = PassportElementErrorSelfie( +fun WithSelfie.createSelfieError(message: String, unencryptedFileHash: PassportElementHash) = PassportElementErrorSelfie( type, unencryptedFileHash, message @@ -172,8 +172,8 @@ data class PassportElementErrorFile( @SerialName(typeField) override val type: String, @SerialName(fileHashField) - @Serializable(Base64StringSerializer::class) - override val elementHash: String, + @Serializable(Base64BytesToFromStringSerializer::class) + override val elementHash: PassportElementHash, @SerialName(messageField) override val message: String ) : PassportElementFileError() { @@ -181,7 +181,7 @@ data class PassportElementErrorFile( @Required override val source: String = fileField } -fun FilesCollection.createFileError(message: String, unencryptedFileHash: String) = PassportElementErrorFile( +fun FilesCollection.createFileError(message: String, unencryptedFileHash: PassportElementHash) = PassportElementErrorFile( type, unencryptedFileHash, message @@ -192,7 +192,7 @@ data class PassportElementErrorFiles( @SerialName(typeField) override val type: String, @SerialName(fileHashesField) - override val elementsHashes: List<@Serializable(Base64StringSerializer::class) String>, + override val elementsHashes: List<@Serializable(Base64BytesToFromStringSerializer::class) PassportElementHash>, @SerialName(messageField) override val message: String ) : PassportElementFilesError() { @@ -200,7 +200,7 @@ data class PassportElementErrorFiles( @Required override val source: String = filesField } -fun FilesCollection.createFilesError(message: String, unencryptedFileHashes: List) = PassportElementErrorFiles( +fun FilesCollection.createFilesError(message: String, unencryptedFileHashes: List) = PassportElementErrorFiles( type, unencryptedFileHashes, message @@ -212,8 +212,8 @@ data class PassportElementErrorTranslationFile( @SerialName(typeField) override val type: String, @SerialName(fileHashField) - @Serializable(Base64StringSerializer::class) - override val elementHash: String, + @Serializable(Base64BytesToFromStringSerializer::class) + override val elementHash: PassportElementHash, @SerialName(messageField) override val message: String ) : PassportElementFileError() { @@ -221,7 +221,7 @@ data class PassportElementErrorTranslationFile( @Required override val source: String = translationFileField } -fun Translatable.createFileError(message: String, unencryptedFileHash: String) = PassportElementErrorTranslationFile( +fun Translatable.createFileError(message: String, unencryptedFileHash: PassportElementHash) = PassportElementErrorTranslationFile( type, unencryptedFileHash, message @@ -231,7 +231,7 @@ data class PassportElementErrorTranslationFiles( @SerialName(typeField) override val type: String, @SerialName(fileHashesField) - override val elementsHashes: List<@Serializable(Base64StringSerializer::class) String>, + override val elementsHashes: List<@Serializable(Base64BytesToFromStringSerializer::class) PassportElementHash>, @SerialName(messageField) override val message: String ) : PassportElementFilesError() { @@ -239,7 +239,7 @@ data class PassportElementErrorTranslationFiles( @Required override val source: String = translationFilesField } -fun Translatable.createFilesError(message: String, unencryptedFileHashes: List) = PassportElementErrorTranslationFiles( +fun Translatable.createFilesError(message: String, unencryptedFileHashes: List) = PassportElementErrorTranslationFiles( type, unencryptedFileHashes, message @@ -250,8 +250,8 @@ data class PassportElementErrorUnspecified( @SerialName(typeField) override val type: String, @SerialName(fileHashField) - @Serializable(Base64StringSerializer::class) - override val elementHash: String, + @Serializable(Base64BytesToFromStringSerializer::class) + override val elementHash: PassportElementHash, @SerialName(messageField) override val message: String ) : PassportElementFileError() { @@ -259,7 +259,7 @@ data class PassportElementErrorUnspecified( @Required override val source: String = unspecifiedField } -fun EncryptedPassportElement.createUnspecifiedError(message: String, elementHash: String) = PassportElementErrorUnspecified( +fun EncryptedPassportElement.createUnspecifiedError(message: String, elementHash: PassportElementHash) = PassportElementErrorUnspecified( type, elementHash, message diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/credentials/DecryptedCredentials.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/credentials/DecryptedCredentials.kt new file mode 100644 index 0000000000..c33a6bcdbf --- /dev/null +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/credentials/DecryptedCredentials.kt @@ -0,0 +1,15 @@ +package dev.inmo.tgbotapi.types.passport.credentials + +import dev.inmo.tgbotapi.types.nonceField +import dev.inmo.tgbotapi.types.passport.decrypted.SecureData +import dev.inmo.tgbotapi.types.secureDataField +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +data class DecryptedCredentials( + @SerialName(secureDataField) + val secureData: SecureData, + @SerialName(nonceField) + val nonce: String +) diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/credentials/EncryptedCredentials.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/credentials/EncryptedCredentials.kt new file mode 100644 index 0000000000..4cd8231c3f --- /dev/null +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/credentials/EncryptedCredentials.kt @@ -0,0 +1,23 @@ +package dev.inmo.tgbotapi.types.passport.credentials + +import dev.inmo.micro_utils.crypto.SourceBytes +import dev.inmo.micro_utils.serialization.base64.Base64BytesToFromStringSerializer +import dev.inmo.tgbotapi.types.* +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +typealias EncryptedByBotPublicKeyData = SourceBytes +typealias EncryptedData = SourceBytes + +@Serializable +data class EncryptedCredentials( + @SerialName(dataField) + @Serializable(Base64BytesToFromStringSerializer::class) + val data: EncryptedData, + @SerialName(hashField) + @Serializable(Base64BytesToFromStringSerializer::class) + val hash: SourceBytes, + @SerialName(secretField) + @Serializable(Base64BytesToFromStringSerializer::class) + val secret: EncryptedByBotPublicKeyData +) diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/credentials/EndDataCredentials.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/credentials/EndDataCredentials.kt new file mode 100644 index 0000000000..7bcc7838b2 --- /dev/null +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/credentials/EndDataCredentials.kt @@ -0,0 +1,35 @@ +package dev.inmo.tgbotapi.types.passport.credentials + +import dev.inmo.micro_utils.crypto.SourceBytes +import dev.inmo.micro_utils.serialization.base64.Base64BytesToFromStringSerializer +import dev.inmo.tgbotapi.types.* +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +sealed class EndDataCredentials { + @Serializable(Base64BytesToFromStringSerializer::class) + abstract val hash: SourceBytes + @Serializable(Base64BytesToFromStringSerializer::class) + abstract val secret: SourceBytes +} + +@Serializable +data class DataCredentials( + @SerialName(dataHashField) + @Serializable(Base64BytesToFromStringSerializer::class) + override val hash: SourceBytes, + @SerialName(secretField) + @Serializable(Base64BytesToFromStringSerializer::class) + override val secret: SourceBytes +) : EndDataCredentials() + +@Serializable +data class FileCredentials( + @SerialName(fileHashField) + @Serializable(Base64BytesToFromStringSerializer::class) + override val hash: SourceBytes, + @SerialName(secretField) + @Serializable(Base64BytesToFromStringSerializer::class) + override val secret: SourceBytes +) : EndDataCredentials() diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/decrypted/AddressSecureValue.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/decrypted/AddressSecureValue.kt new file mode 100644 index 0000000000..d403e11db3 --- /dev/null +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/decrypted/AddressSecureValue.kt @@ -0,0 +1,16 @@ +package dev.inmo.tgbotapi.types.passport.decrypted + +import dev.inmo.tgbotapi.types.dataField +import dev.inmo.tgbotapi.types.passport.credentials.DataCredentials +import dev.inmo.tgbotapi.types.passport.credentials.EndDataCredentials +import dev.inmo.tgbotapi.types.passport.decrypted.abstracts.SecureValueWithData +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +data class AddressSecureValue( + @SerialName(dataField) + override val data: DataCredentials +) : SecureValueWithData { + override val credentials: List = listOf(data) +} \ No newline at end of file diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/decrypted/IdentityWithReverseSideSecureValue.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/decrypted/IdentityWithReverseSideSecureValue.kt new file mode 100644 index 0000000000..c05a7a7692 --- /dev/null +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/decrypted/IdentityWithReverseSideSecureValue.kt @@ -0,0 +1,41 @@ +package dev.inmo.tgbotapi.types.passport.decrypted + +import dev.inmo.tgbotapi.types.* +import dev.inmo.tgbotapi.types.passport.credentials.* +import dev.inmo.tgbotapi.types.passport.decrypted.abstracts.* +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +sealed class IdentityWithReverseSideSecureValue : SecureValueIdentity, SecureValueWithData, SecureValueWithTranslations, SecureValueWithReverseSide { + override val credentials: List + get() = listOfNotNull(data, frontSide, reverseSide, selfie) + translation +} + +@Serializable +data class DriverLicenseSecureValue( + @SerialName(dataField) + override val data: DataCredentials? = null, + @SerialName(frontSideField) + override val frontSide: FileCredentials? = null, + @SerialName(reverseSideField) + override val reverseSide: FileCredentials? = null, + @SerialName(selfieField) + override val selfie: FileCredentials? = null, + @SerialName(translationField) + override val translation: List = emptyList() +) : IdentityWithReverseSideSecureValue() + +@Serializable +data class IdentityCardSecureValue( + @SerialName(dataField) + override val data: DataCredentials? = null, + @SerialName(frontSideField) + override val frontSide: FileCredentials? = null, + @SerialName(reverseSideField) + override val reverseSide: FileCredentials? = null, + @SerialName(selfieField) + override val selfie: FileCredentials? = null, + @SerialName(translationField) + override val translation: List = emptyList() +) : IdentityWithReverseSideSecureValue() diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/decrypted/OtherDocumentsSecureValue.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/decrypted/OtherDocumentsSecureValue.kt new file mode 100644 index 0000000000..778a773cbf --- /dev/null +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/decrypted/OtherDocumentsSecureValue.kt @@ -0,0 +1,56 @@ +package dev.inmo.tgbotapi.types.passport.decrypted + +import dev.inmo.tgbotapi.types.filesField +import dev.inmo.tgbotapi.types.passport.credentials.EndDataCredentials +import dev.inmo.tgbotapi.types.passport.credentials.FileCredentials +import dev.inmo.tgbotapi.types.passport.decrypted.abstracts.SecureValueWithFiles +import dev.inmo.tgbotapi.types.passport.decrypted.abstracts.SecureValueWithTranslations +import dev.inmo.tgbotapi.types.translationField +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +sealed class OtherDocumentsSecureValue : SecureValueWithTranslations, SecureValueWithFiles { + override val credentials: List + get() = translation + files +} + +@Serializable +data class UtilityBillSecureValue( + @SerialName(translationField) + override val translation: List = emptyList(), + @SerialName(filesField) + override val files: List = emptyList() +) : OtherDocumentsSecureValue() + +@Serializable +data class BankStatementSecureValue( + @SerialName(translationField) + override val translation: List = emptyList(), + @SerialName(filesField) + override val files: List = emptyList() +) : OtherDocumentsSecureValue() + +@Serializable +data class RentalAgreementSecureValue( + @SerialName(translationField) + override val translation: List = emptyList(), + @SerialName(filesField) + override val files: List = emptyList() +) : OtherDocumentsSecureValue() + +@Serializable +data class PassportRegistrationSecureValue( + @SerialName(translationField) + override val translation: List = emptyList(), + @SerialName(filesField) + override val files: List = emptyList() +) : OtherDocumentsSecureValue() + +@Serializable +data class TemporalRegistrationSecureValue( + @SerialName(translationField) + override val translation: List = emptyList(), + @SerialName(filesField) + override val files: List = emptyList() +) : OtherDocumentsSecureValue() diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/decrypted/PassportSecureValue.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/decrypted/PassportSecureValue.kt new file mode 100644 index 0000000000..effe727275 --- /dev/null +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/decrypted/PassportSecureValue.kt @@ -0,0 +1,38 @@ +package dev.inmo.tgbotapi.types.passport.decrypted + +import dev.inmo.tgbotapi.types.* +import dev.inmo.tgbotapi.types.passport.credentials.* +import dev.inmo.tgbotapi.types.passport.decrypted.abstracts.* +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +sealed class PassportSecureValue : SecureValueIdentity, SecureValueWithData, SecureValueWithTranslations { + override val credentials: List + get() = listOfNotNull(data, frontSide, selfie) + translation +} + +@Serializable +data class CommonPassportSecureValue( + @SerialName(dataField) + override val data: DataCredentials? = null, + @SerialName(frontSideField) + override val frontSide: FileCredentials? = null, + @SerialName(selfieField) + override val selfie: FileCredentials? = null, + @SerialName(translationField) + override val translation: List = emptyList() +) : PassportSecureValue() + +@Serializable +data class InternalPassportSecureValue( + @SerialName(dataField) + override val data: DataCredentials? = null, + @SerialName(frontSideField) + override val frontSide: FileCredentials? = null, + @SerialName(selfieField) + override val selfie: FileCredentials? = null, + @SerialName(translationField) + override val translation: List = emptyList() +) : PassportSecureValue() + diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/decrypted/PersonalDetailsSecureValue.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/decrypted/PersonalDetailsSecureValue.kt new file mode 100644 index 0000000000..120b2bf77a --- /dev/null +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/decrypted/PersonalDetailsSecureValue.kt @@ -0,0 +1,16 @@ +package dev.inmo.tgbotapi.types.passport.decrypted + +import dev.inmo.tgbotapi.types.dataField +import dev.inmo.tgbotapi.types.passport.credentials.DataCredentials +import dev.inmo.tgbotapi.types.passport.credentials.EndDataCredentials +import dev.inmo.tgbotapi.types.passport.decrypted.abstracts.SecureValueWithData +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +data class PersonalDetailsSecureValue( + @SerialName(dataField) + override val data: DataCredentials +) : SecureValueWithData { + override val credentials: List = listOf(data) +} \ No newline at end of file diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/decrypted/SecureData.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/decrypted/SecureData.kt new file mode 100644 index 0000000000..c2b9092603 --- /dev/null +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/decrypted/SecureData.kt @@ -0,0 +1,42 @@ +package dev.inmo.tgbotapi.types.passport.decrypted + +import dev.inmo.tgbotapi.types.* +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +data class SecureData( + @SerialName(personalDetailsField) + val personalDetails: PersonalDetailsSecureValue? = null, + @SerialName(passportField) + val passport: CommonPassportSecureValue? = null, + @SerialName(internalPassportField) + val internalPassport: InternalPassportSecureValue? = null, + @SerialName(driverLicenseField) + val driverLicense: DriverLicenseSecureValue? = null, + @SerialName(identityCardField) + val identityCard: IdentityCardSecureValue? = null, + @SerialName(utilityBillField) + val utilityBill: UtilityBillSecureValue? = null, + @SerialName(bankStatementField) + val bankStatement: BankStatementSecureValue? = null, + @SerialName(rentalAgreementField) + val rentalAgreement: RentalAgreementSecureValue? = null, + @SerialName(passportRegistrationField) + val passportRegistration: PassportRegistrationSecureValue? = null, + @SerialName(temporaryRegistrationField) + val temporaryRegistration: TemporalRegistrationSecureValue? = null, +) { + val allCredentials by lazy { + (personalDetails ?.credentials ?: emptyList()) + + (passport ?.credentials ?: emptyList()) + + (internalPassport ?.credentials ?: emptyList()) + + (driverLicense ?.credentials ?: emptyList()) + + (identityCard ?.credentials ?: emptyList()) + + (utilityBill ?.credentials ?: emptyList()) + + (bankStatement ?.credentials ?: emptyList()) + + (rentalAgreement ?.credentials ?: emptyList()) + + (passportRegistration ?.credentials ?: emptyList()) + + (temporaryRegistration ?.credentials ?: emptyList()) + } +} diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/decrypted/abstracts/SecureValue.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/decrypted/abstracts/SecureValue.kt new file mode 100644 index 0000000000..b9bb54371c --- /dev/null +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/decrypted/abstracts/SecureValue.kt @@ -0,0 +1,7 @@ +package dev.inmo.tgbotapi.types.passport.decrypted.abstracts + +import dev.inmo.tgbotapi.types.passport.credentials.EndDataCredentials + +interface SecureValue { + val credentials: List +} diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/decrypted/abstracts/SecureValueIdentity.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/decrypted/abstracts/SecureValueIdentity.kt new file mode 100644 index 0000000000..e1de83733a --- /dev/null +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/decrypted/abstracts/SecureValueIdentity.kt @@ -0,0 +1,8 @@ +package dev.inmo.tgbotapi.types.passport.decrypted.abstracts + +import dev.inmo.tgbotapi.types.passport.credentials.FileCredentials + +interface SecureValueIdentity : SecureValue { + val frontSide: FileCredentials? + val selfie: FileCredentials? +} \ No newline at end of file diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/decrypted/abstracts/SecureValueWithData.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/decrypted/abstracts/SecureValueWithData.kt new file mode 100644 index 0000000000..9e984cd3b0 --- /dev/null +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/decrypted/abstracts/SecureValueWithData.kt @@ -0,0 +1,7 @@ +package dev.inmo.tgbotapi.types.passport.decrypted.abstracts + +import dev.inmo.tgbotapi.types.passport.credentials.DataCredentials + +interface SecureValueWithData : SecureValue { + val data: DataCredentials? +} \ No newline at end of file diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/decrypted/abstracts/SecureValueWithFiles.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/decrypted/abstracts/SecureValueWithFiles.kt new file mode 100644 index 0000000000..ea201f1ee8 --- /dev/null +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/decrypted/abstracts/SecureValueWithFiles.kt @@ -0,0 +1,7 @@ +package dev.inmo.tgbotapi.types.passport.decrypted.abstracts + +import dev.inmo.tgbotapi.types.passport.credentials.FileCredentials + +interface SecureValueWithFiles : SecureValue { + val files: List +} \ No newline at end of file diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/decrypted/abstracts/SecureValueWithReverseSide.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/decrypted/abstracts/SecureValueWithReverseSide.kt new file mode 100644 index 0000000000..9706c5d041 --- /dev/null +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/decrypted/abstracts/SecureValueWithReverseSide.kt @@ -0,0 +1,7 @@ +package dev.inmo.tgbotapi.types.passport.decrypted.abstracts + +import dev.inmo.tgbotapi.types.passport.credentials.FileCredentials + +interface SecureValueWithReverseSide : SecureValue { + val reverseSide: FileCredentials? +} \ No newline at end of file diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/decrypted/abstracts/SecureValueWithTranslations.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/decrypted/abstracts/SecureValueWithTranslations.kt new file mode 100644 index 0000000000..f540a2ad7f --- /dev/null +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/decrypted/abstracts/SecureValueWithTranslations.kt @@ -0,0 +1,7 @@ +package dev.inmo.tgbotapi.types.passport.decrypted.abstracts + +import dev.inmo.tgbotapi.types.passport.credentials.FileCredentials + +interface SecureValueWithTranslations : SecureValue { + val translation: List +} \ No newline at end of file diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/encrypted/Email.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/encrypted/Email.kt new file mode 100644 index 0000000000..ca3f3f7f92 --- /dev/null +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/encrypted/Email.kt @@ -0,0 +1,19 @@ +package dev.inmo.tgbotapi.types.passport.encrypted + +import dev.inmo.micro_utils.serialization.base64.Base64BytesToFromStringSerializer +import dev.inmo.tgbotapi.types.emailField +import dev.inmo.tgbotapi.types.hashField +import dev.inmo.tgbotapi.types.passport.encrypted.abstracts.PassportElementHash +import dev.inmo.tgbotapi.types.passport.encrypted.abstracts.WithEmail +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +data class Email( + @SerialName(emailField) + override val email: String, + @SerialName(hashField) + @Serializable(Base64BytesToFromStringSerializer::class) + override val hash: PassportElementHash +) : WithEmail { +} \ No newline at end of file diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/encrypted/EncryptedAddress.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/encrypted/EncryptedAddress.kt new file mode 100644 index 0000000000..6bb91ac32d --- /dev/null +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/encrypted/EncryptedAddress.kt @@ -0,0 +1,18 @@ +package dev.inmo.tgbotapi.types.passport.encrypted + +import dev.inmo.micro_utils.serialization.base64.Base64BytesToFromStringSerializer +import dev.inmo.tgbotapi.types.dataField +import dev.inmo.tgbotapi.types.passport.credentials.EncryptedData +import dev.inmo.tgbotapi.types.passport.encrypted.abstracts.PassportElementHash +import dev.inmo.tgbotapi.types.passport.encrypted.abstracts.WithData +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +data class EncryptedAddress( + @SerialName(dataField) + @Serializable(Base64BytesToFromStringSerializer::class) + override val data: EncryptedData, + @Serializable(Base64BytesToFromStringSerializer::class) + override val hash: PassportElementHash +) : WithData 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/EncryptedElementSerializer.kt similarity index 90% rename from tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/encrypted_data/EncryptedElementSerializer.kt rename to tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/encrypted/EncryptedElementSerializer.kt index 28caca9889..52cb81f1af 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/EncryptedElementSerializer.kt @@ -1,9 +1,10 @@ -package dev.inmo.tgbotapi.types.passport.encrypted_data +package dev.inmo.tgbotapi.types.passport.encrypted +import dev.inmo.micro_utils.crypto.decodeBase64 import dev.inmo.micro_utils.serialization.encapsulator.Encapsulator 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.passport.encrypted.abstracts.EncryptedPassportElement +import dev.inmo.tgbotapi.types.passport.encrypted.abstracts.UnknownEncryptedPassportElement import dev.inmo.tgbotapi.types.typeField import dev.inmo.tgbotapi.utils.RiskFeature import dev.inmo.tgbotapi.utils.nonstrictJsonFormat @@ -45,7 +46,7 @@ object EncryptedElementSerializer : KSerializer { encryptedElementsClassesByTypes[type] ?.serializer ?.let { deserializer -> nonstrictJsonFormat.decodeFromJsonElement(deserializer, json) } - } ?: UnknownEncryptedPassportElement(json, json[hashField] ?.jsonPrimitive ?.content ?: "") + } ?: UnknownEncryptedPassportElement(json, json[hashField] ?.jsonPrimitive ?.content ?.decodeBase64() ?: byteArrayOf()) } override fun serialize(encoder: Encoder, value: EncryptedPassportElement) { diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/encrypted/EncryptedPersonalDetails.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/encrypted/EncryptedPersonalDetails.kt new file mode 100644 index 0000000000..3e79d2370d --- /dev/null +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/encrypted/EncryptedPersonalDetails.kt @@ -0,0 +1,18 @@ +package dev.inmo.tgbotapi.types.passport.encrypted + +import dev.inmo.micro_utils.serialization.base64.Base64BytesToFromStringSerializer +import dev.inmo.tgbotapi.types.dataField +import dev.inmo.tgbotapi.types.passport.credentials.EncryptedData +import dev.inmo.tgbotapi.types.passport.encrypted.abstracts.PassportElementHash +import dev.inmo.tgbotapi.types.passport.encrypted.abstracts.WithData +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +data class EncryptedPersonalDetails( + @SerialName(dataField) + @Serializable(Base64BytesToFromStringSerializer::class) + override val data: EncryptedData, + @Serializable(Base64BytesToFromStringSerializer::class) + override val hash: PassportElementHash +) : WithData diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/encrypted_data/Passport.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/encrypted/Passport.kt similarity index 64% rename from tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/encrypted_data/Passport.kt rename to tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/encrypted/Passport.kt index 882c91c895..c23fb1857f 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/encrypted_data/Passport.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/encrypted/Passport.kt @@ -1,9 +1,9 @@ -package dev.inmo.tgbotapi.types.passport.encrypted_data +package dev.inmo.tgbotapi.types.passport.encrypted -import dev.inmo.micro_utils.serialization.base64.Base64StringSerializer +import dev.inmo.micro_utils.serialization.base64.Base64BytesToFromStringSerializer import dev.inmo.tgbotapi.types.* -import dev.inmo.tgbotapi.types.passport.EncryptedData -import dev.inmo.tgbotapi.types.passport.encrypted_data.abstracts.* +import dev.inmo.tgbotapi.types.passport.credentials.EncryptedData +import dev.inmo.tgbotapi.types.passport.encrypted.abstracts.* import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable @@ -13,7 +13,7 @@ sealed class Passport : WithData, WithFrontSide, WithSelfie, Translatable @Serializable data class CommonPassport( @SerialName(dataField) - @Serializable(Base64StringSerializer::class) + @Serializable(Base64BytesToFromStringSerializer::class) override val data: EncryptedData, @SerialName(frontSideField) override val frontSide: PassportFile? = null, @@ -22,13 +22,13 @@ data class CommonPassport( @SerialName(translationField) override val translations: List = emptyList(), @SerialName(hashField) - @Serializable(Base64StringSerializer::class) - override val hash: String + @Serializable(Base64BytesToFromStringSerializer::class) + override val hash: PassportElementHash ) : Passport() @Serializable data class InternalPassport( @SerialName(dataField) - @Serializable(Base64StringSerializer::class) + @Serializable(Base64BytesToFromStringSerializer::class) override val data: EncryptedData, @SerialName(frontSideField) override val frontSide: PassportFile? = null, @@ -37,6 +37,6 @@ data class InternalPassport( @SerialName(translationField) override val translations: List = emptyList(), @SerialName(hashField) - @Serializable(Base64StringSerializer::class) - override val hash: String + @Serializable(Base64BytesToFromStringSerializer::class) + override val hash: PassportElementHash ) : Passport() diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/encrypted_data/PassportFile.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/encrypted/PassportFile.kt similarity index 92% rename from tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/encrypted_data/PassportFile.kt rename to tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/encrypted/PassportFile.kt index cf00e2fc2a..675105120b 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/encrypted_data/PassportFile.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/encrypted/PassportFile.kt @@ -1,4 +1,4 @@ -package dev.inmo.tgbotapi.types.passport.encrypted_data +package dev.inmo.tgbotapi.types.passport.encrypted import dev.inmo.tgbotapi.requests.abstracts.FileId import dev.inmo.tgbotapi.types.* diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/encrypted/PhoneNumber.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/encrypted/PhoneNumber.kt new file mode 100644 index 0000000000..3d70962190 --- /dev/null +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/encrypted/PhoneNumber.kt @@ -0,0 +1,19 @@ +package dev.inmo.tgbotapi.types.passport.encrypted + +import dev.inmo.micro_utils.serialization.base64.Base64BytesToFromStringSerializer +import dev.inmo.tgbotapi.types.hashField +import dev.inmo.tgbotapi.types.passport.encrypted.abstracts.PassportElementHash +import dev.inmo.tgbotapi.types.passport.encrypted.abstracts.WithPhoneNumber +import dev.inmo.tgbotapi.types.phoneNumberField +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +data class PhoneNumber( + @SerialName(phoneNumberField) + override val phoneNumber: String, + @SerialName(hashField) + @Serializable(Base64BytesToFromStringSerializer::class) + override val hash: PassportElementHash +) : WithPhoneNumber { +} \ No newline at end of file diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/encrypted_data/TranslatableFilesCollection.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/encrypted/TranslatableFilesCollection.kt similarity index 69% rename from tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/encrypted_data/TranslatableFilesCollection.kt rename to tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/encrypted/TranslatableFilesCollection.kt index 4339ad958b..377aad5ce2 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/encrypted_data/TranslatableFilesCollection.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/encrypted/TranslatableFilesCollection.kt @@ -1,9 +1,8 @@ -package dev.inmo.tgbotapi.types.passport.encrypted_data +package dev.inmo.tgbotapi.types.passport.encrypted -import dev.inmo.micro_utils.serialization.base64.Base64StringSerializer +import dev.inmo.micro_utils.serialization.base64.Base64BytesToFromStringSerializer import dev.inmo.tgbotapi.types.* -import dev.inmo.tgbotapi.types.passport.encrypted_data.abstracts.FilesCollection -import dev.inmo.tgbotapi.types.passport.encrypted_data.abstracts.Translatable +import dev.inmo.tgbotapi.types.passport.encrypted.abstracts.* import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable @@ -17,8 +16,8 @@ data class UtilityBill( @SerialName(translationField) override val translations: List = emptyList(), @SerialName(hashField) - @Serializable(Base64StringSerializer::class) - override val hash: String + @Serializable(Base64BytesToFromStringSerializer::class) + override val hash: PassportElementHash ) : TranslatableFilesCollection() @Serializable data class BankStatement( @@ -27,8 +26,8 @@ data class BankStatement( @SerialName(translationField) override val translations: List = emptyList(), @SerialName(hashField) - @Serializable(Base64StringSerializer::class) - override val hash: String + @Serializable(Base64BytesToFromStringSerializer::class) + override val hash: PassportElementHash ) : TranslatableFilesCollection() @Serializable data class RentalAgreement( @@ -37,8 +36,8 @@ data class RentalAgreement( @SerialName(translationField) override val translations: List = emptyList(), @SerialName(hashField) - @Serializable(Base64StringSerializer::class) - override val hash: String + @Serializable(Base64BytesToFromStringSerializer::class) + override val hash: PassportElementHash ) : TranslatableFilesCollection() @Serializable data class PassportRegistration( @@ -47,8 +46,8 @@ data class PassportRegistration( @SerialName(translationField) override val translations: List = emptyList(), @SerialName(hashField) - @Serializable(Base64StringSerializer::class) - override val hash: String + @Serializable(Base64BytesToFromStringSerializer::class) + override val hash: PassportElementHash ) : TranslatableFilesCollection() @Serializable data class TemporaryRegistration( @@ -57,7 +56,7 @@ data class TemporaryRegistration( @SerialName(translationField) override val translations: List = emptyList(), @SerialName(hashField) - @Serializable(Base64StringSerializer::class) - override val hash: String + @Serializable(Base64BytesToFromStringSerializer::class) + override val hash: PassportElementHash ) : TranslatableFilesCollection() diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/encrypted_data/TranslatableIDDocument.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/encrypted/TranslatableIDDocument.kt similarity index 68% rename from tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/encrypted_data/TranslatableIDDocument.kt rename to tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/encrypted/TranslatableIDDocument.kt index 45d874c784..e20de95245 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/encrypted_data/TranslatableIDDocument.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/encrypted/TranslatableIDDocument.kt @@ -1,9 +1,9 @@ -package dev.inmo.tgbotapi.types.passport.encrypted_data +package dev.inmo.tgbotapi.types.passport.encrypted -import dev.inmo.micro_utils.serialization.base64.Base64StringSerializer +import dev.inmo.micro_utils.serialization.base64.Base64BytesToFromStringSerializer import dev.inmo.tgbotapi.types.* -import dev.inmo.tgbotapi.types.passport.EncryptedData -import dev.inmo.tgbotapi.types.passport.encrypted_data.abstracts.* +import dev.inmo.tgbotapi.types.passport.credentials.EncryptedData +import dev.inmo.tgbotapi.types.passport.encrypted.abstracts.* import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable @@ -13,7 +13,7 @@ sealed class TranslatableIDDocument : WithData, WithFrontSide, WithReverseSide, @Serializable data class DriverLicense( @SerialName(dataField) - @Serializable(Base64StringSerializer::class) + @Serializable(Base64BytesToFromStringSerializer::class) override val data: EncryptedData, @SerialName(frontSideField) override val frontSide: PassportFile? = null, @@ -24,14 +24,14 @@ data class DriverLicense( @SerialName(translationField) override val translations: List = emptyList(), @SerialName(hashField) - @Serializable(Base64StringSerializer::class) - override val hash: String + @Serializable(Base64BytesToFromStringSerializer::class) + override val hash: PassportElementHash ) : TranslatableIDDocument() @Serializable data class IdentityCard( @SerialName(dataField) - @Serializable(Base64StringSerializer::class) + @Serializable(Base64BytesToFromStringSerializer::class) override val data: EncryptedData, @SerialName(frontSideField) override val frontSide: PassportFile? = null, @@ -42,6 +42,6 @@ data class IdentityCard( @SerialName(translationField) override val translations: List = emptyList(), @SerialName(hashField) - @Serializable(Base64StringSerializer::class) - override val hash: String + @Serializable(Base64BytesToFromStringSerializer::class) + override val hash: PassportElementHash ) : TranslatableIDDocument() diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/encrypted/abstracts/EncryptedPassportElement.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/encrypted/abstracts/EncryptedPassportElement.kt new file mode 100644 index 0000000000..6bf1d843df --- /dev/null +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/encrypted/abstracts/EncryptedPassportElement.kt @@ -0,0 +1,21 @@ +package dev.inmo.tgbotapi.types.passport.encrypted.abstracts + +import dev.inmo.micro_utils.crypto.SourceBytes +import dev.inmo.micro_utils.serialization.base64.Base64BytesToFromStringSerializer +import dev.inmo.tgbotapi.types.passport.encrypted.EncryptedElementSerializer +import kotlinx.serialization.Serializable +import kotlinx.serialization.json.JsonObject + +typealias PassportElementHash = SourceBytes + +@Serializable(EncryptedElementSerializer::class) +interface EncryptedPassportElement { + val hash: PassportElementHash +} + +@Serializable(EncryptedElementSerializer::class) +data class UnknownEncryptedPassportElement( + val rawJson: JsonObject, + @Serializable(Base64BytesToFromStringSerializer::class) + override val hash: PassportElementHash +) : EncryptedPassportElement diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/encrypted/abstracts/FilesCollection.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/encrypted/abstracts/FilesCollection.kt new file mode 100644 index 0000000000..bf50a864b2 --- /dev/null +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/encrypted/abstracts/FilesCollection.kt @@ -0,0 +1,10 @@ +package dev.inmo.tgbotapi.types.passport.encrypted.abstracts + +import dev.inmo.tgbotapi.types.passport.encrypted.EncryptedElementSerializer +import dev.inmo.tgbotapi.types.passport.encrypted.PassportFile +import kotlinx.serialization.Serializable + +@Serializable(EncryptedElementSerializer::class) +interface FilesCollection : EncryptedPassportElement { + val files: List +} \ No newline at end of file diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/encrypted/abstracts/Translatable.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/encrypted/abstracts/Translatable.kt new file mode 100644 index 0000000000..c538e91d17 --- /dev/null +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/encrypted/abstracts/Translatable.kt @@ -0,0 +1,10 @@ +package dev.inmo.tgbotapi.types.passport.encrypted.abstracts + +import dev.inmo.tgbotapi.types.passport.encrypted.EncryptedElementSerializer +import dev.inmo.tgbotapi.types.passport.encrypted.PassportFile +import kotlinx.serialization.Serializable + +@Serializable(EncryptedElementSerializer::class) +interface Translatable : EncryptedPassportElement { + val translations: List +} \ No newline at end of file diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/encrypted/abstracts/WithData.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/encrypted/abstracts/WithData.kt new file mode 100644 index 0000000000..9e464fec51 --- /dev/null +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/encrypted/abstracts/WithData.kt @@ -0,0 +1,10 @@ +package dev.inmo.tgbotapi.types.passport.encrypted.abstracts + +import dev.inmo.tgbotapi.types.passport.credentials.EncryptedData +import dev.inmo.tgbotapi.types.passport.encrypted.EncryptedElementSerializer +import kotlinx.serialization.Serializable + +@Serializable(EncryptedElementSerializer::class) +interface WithData : EncryptedPassportElement { + val data: EncryptedData +} \ No newline at end of file diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/encrypted_data/abstracts/WithEmail.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/encrypted/abstracts/WithEmail.kt similarity index 52% rename from tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/encrypted_data/abstracts/WithEmail.kt rename to tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/encrypted/abstracts/WithEmail.kt index 57b069a55f..0442d15771 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/encrypted_data/abstracts/WithEmail.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/encrypted/abstracts/WithEmail.kt @@ -1,6 +1,6 @@ -package dev.inmo.tgbotapi.types.passport.encrypted_data.abstracts +package dev.inmo.tgbotapi.types.passport.encrypted.abstracts -import dev.inmo.tgbotapi.types.passport.encrypted_data.EncryptedElementSerializer +import dev.inmo.tgbotapi.types.passport.encrypted.EncryptedElementSerializer import kotlinx.serialization.Serializable @Serializable(EncryptedElementSerializer::class) diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/encrypted/abstracts/WithFrontSide.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/encrypted/abstracts/WithFrontSide.kt new file mode 100644 index 0000000000..396ef60aea --- /dev/null +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/encrypted/abstracts/WithFrontSide.kt @@ -0,0 +1,10 @@ +package dev.inmo.tgbotapi.types.passport.encrypted.abstracts + +import dev.inmo.tgbotapi.types.passport.encrypted.EncryptedElementSerializer +import dev.inmo.tgbotapi.types.passport.encrypted.PassportFile +import kotlinx.serialization.Serializable + +@Serializable(EncryptedElementSerializer::class) +interface WithFrontSide : EncryptedPassportElement { + val frontSide: PassportFile? +} \ No newline at end of file diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/encrypted_data/abstracts/WithPhoneNumber.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/encrypted/abstracts/WithPhoneNumber.kt similarity index 54% rename from tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/encrypted_data/abstracts/WithPhoneNumber.kt rename to tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/encrypted/abstracts/WithPhoneNumber.kt index 47e1ecdf30..9181eba0e4 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/encrypted_data/abstracts/WithPhoneNumber.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/encrypted/abstracts/WithPhoneNumber.kt @@ -1,6 +1,6 @@ -package dev.inmo.tgbotapi.types.passport.encrypted_data.abstracts +package dev.inmo.tgbotapi.types.passport.encrypted.abstracts -import dev.inmo.tgbotapi.types.passport.encrypted_data.EncryptedElementSerializer +import dev.inmo.tgbotapi.types.passport.encrypted.EncryptedElementSerializer import kotlinx.serialization.Serializable @Serializable(EncryptedElementSerializer::class) diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/encrypted/abstracts/WithReverseSide.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/encrypted/abstracts/WithReverseSide.kt new file mode 100644 index 0000000000..47d443c3ec --- /dev/null +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/encrypted/abstracts/WithReverseSide.kt @@ -0,0 +1,10 @@ +package dev.inmo.tgbotapi.types.passport.encrypted.abstracts + +import dev.inmo.tgbotapi.types.passport.encrypted.EncryptedElementSerializer +import dev.inmo.tgbotapi.types.passport.encrypted.PassportFile +import kotlinx.serialization.Serializable + +@Serializable(EncryptedElementSerializer::class) +interface WithReverseSide : EncryptedPassportElement { + val reverseSide: PassportFile? +} \ No newline at end of file diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/encrypted/abstracts/WithSelfie.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/encrypted/abstracts/WithSelfie.kt new file mode 100644 index 0000000000..6928c2c311 --- /dev/null +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/encrypted/abstracts/WithSelfie.kt @@ -0,0 +1,10 @@ +package dev.inmo.tgbotapi.types.passport.encrypted.abstracts + +import dev.inmo.tgbotapi.types.passport.encrypted.EncryptedElementSerializer +import dev.inmo.tgbotapi.types.passport.encrypted.PassportFile +import kotlinx.serialization.Serializable + +@Serializable(EncryptedElementSerializer::class) +interface WithSelfie : EncryptedPassportElement { + val selfie: PassportFile? +} \ No newline at end of file diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/encrypted_data/Email.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/encrypted_data/Email.kt deleted file mode 100644 index c5e83c94d8..0000000000 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/encrypted_data/Email.kt +++ /dev/null @@ -1,18 +0,0 @@ -package dev.inmo.tgbotapi.types.passport.encrypted_data - -import dev.inmo.micro_utils.serialization.base64.Base64StringSerializer -import dev.inmo.tgbotapi.types.emailField -import dev.inmo.tgbotapi.types.hashField -import dev.inmo.tgbotapi.types.passport.encrypted_data.abstracts.WithEmail -import kotlinx.serialization.SerialName -import kotlinx.serialization.Serializable - -@Serializable -data class Email( - @SerialName(emailField) - override val email: String, - @SerialName(hashField) - @Serializable(Base64StringSerializer::class) - override val hash: String -) : WithEmail { -} \ No newline at end of file diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/encrypted_data/EncryptedAddress.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/encrypted_data/EncryptedAddress.kt deleted file mode 100644 index b63f1865bf..0000000000 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/encrypted_data/EncryptedAddress.kt +++ /dev/null @@ -1,17 +0,0 @@ -package dev.inmo.tgbotapi.types.passport.encrypted_data - -import dev.inmo.micro_utils.serialization.base64.Base64StringSerializer -import dev.inmo.tgbotapi.types.dataField -import dev.inmo.tgbotapi.types.passport.EncryptedData -import dev.inmo.tgbotapi.types.passport.encrypted_data.abstracts.WithData -import kotlinx.serialization.SerialName -import kotlinx.serialization.Serializable - -@Serializable -data class EncryptedAddress( - @SerialName(dataField) - @Serializable(Base64StringSerializer::class) - override val data: EncryptedData, - @Serializable(Base64StringSerializer::class) - override val hash: String -) : WithData diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/encrypted_data/EncryptedPersonalDetails.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/encrypted_data/EncryptedPersonalDetails.kt deleted file mode 100644 index 90149a261e..0000000000 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/encrypted_data/EncryptedPersonalDetails.kt +++ /dev/null @@ -1,17 +0,0 @@ -package dev.inmo.tgbotapi.types.passport.encrypted_data - -import dev.inmo.micro_utils.serialization.base64.Base64StringSerializer -import dev.inmo.tgbotapi.types.dataField -import dev.inmo.tgbotapi.types.passport.EncryptedData -import dev.inmo.tgbotapi.types.passport.encrypted_data.abstracts.WithData -import kotlinx.serialization.SerialName -import kotlinx.serialization.Serializable - -@Serializable -data class EncryptedPersonalDetails( - @SerialName(dataField) - @Serializable(Base64StringSerializer::class) - override val data: EncryptedData, - @Serializable(Base64StringSerializer::class) - override val hash: String -) : WithData diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/encrypted_data/PhoneNumber.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/encrypted_data/PhoneNumber.kt deleted file mode 100644 index 563339ade1..0000000000 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/encrypted_data/PhoneNumber.kt +++ /dev/null @@ -1,18 +0,0 @@ -package dev.inmo.tgbotapi.types.passport.encrypted_data - -import dev.inmo.micro_utils.serialization.base64.Base64StringSerializer -import dev.inmo.tgbotapi.types.hashField -import dev.inmo.tgbotapi.types.passport.encrypted_data.abstracts.WithPhoneNumber -import dev.inmo.tgbotapi.types.phoneNumberField -import kotlinx.serialization.SerialName -import kotlinx.serialization.Serializable - -@Serializable -data class PhoneNumber( - @SerialName(phoneNumberField) - override val phoneNumber: String, - @SerialName(hashField) - @Serializable(Base64StringSerializer::class) - override val hash: String -) : WithPhoneNumber { -} \ No newline at end of file diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/encrypted_data/abstracts/EncryptedPassportElement.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/encrypted_data/abstracts/EncryptedPassportElement.kt deleted file mode 100644 index 4716d225d2..0000000000 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/encrypted_data/abstracts/EncryptedPassportElement.kt +++ /dev/null @@ -1,18 +0,0 @@ -package dev.inmo.tgbotapi.types.passport.encrypted_data.abstracts - -import dev.inmo.micro_utils.serialization.base64.Base64StringSerializer -import dev.inmo.tgbotapi.types.passport.encrypted_data.EncryptedElementSerializer -import kotlinx.serialization.Serializable -import kotlinx.serialization.json.JsonObject - -@Serializable(EncryptedElementSerializer::class) -interface EncryptedPassportElement { - val hash: String -} - -@Serializable(EncryptedElementSerializer::class) -data class UnknownEncryptedPassportElement( - val rawJson: JsonObject, - @Serializable(Base64StringSerializer::class) - override val hash: String -) : EncryptedPassportElement diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/encrypted_data/abstracts/FilesCollection.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/encrypted_data/abstracts/FilesCollection.kt deleted file mode 100644 index aa58eb3ecc..0000000000 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/encrypted_data/abstracts/FilesCollection.kt +++ /dev/null @@ -1,10 +0,0 @@ -package dev.inmo.tgbotapi.types.passport.encrypted_data.abstracts - -import dev.inmo.tgbotapi.types.passport.encrypted_data.EncryptedElementSerializer -import dev.inmo.tgbotapi.types.passport.encrypted_data.PassportFile -import kotlinx.serialization.Serializable - -@Serializable(EncryptedElementSerializer::class) -interface FilesCollection : EncryptedPassportElement { - val files: List -} \ No newline at end of file diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/encrypted_data/abstracts/Translatable.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/encrypted_data/abstracts/Translatable.kt deleted file mode 100644 index 0e7d7f0af9..0000000000 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/encrypted_data/abstracts/Translatable.kt +++ /dev/null @@ -1,10 +0,0 @@ -package dev.inmo.tgbotapi.types.passport.encrypted_data.abstracts - -import dev.inmo.tgbotapi.types.passport.encrypted_data.EncryptedElementSerializer -import dev.inmo.tgbotapi.types.passport.encrypted_data.PassportFile -import kotlinx.serialization.Serializable - -@Serializable(EncryptedElementSerializer::class) -interface Translatable : EncryptedPassportElement { - val translations: List -} \ No newline at end of file diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/encrypted_data/abstracts/WithData.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/encrypted_data/abstracts/WithData.kt deleted file mode 100644 index 163b9d43b6..0000000000 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/encrypted_data/abstracts/WithData.kt +++ /dev/null @@ -1,10 +0,0 @@ -package dev.inmo.tgbotapi.types.passport.encrypted_data.abstracts - -import dev.inmo.tgbotapi.types.passport.EncryptedData -import dev.inmo.tgbotapi.types.passport.encrypted_data.EncryptedElementSerializer -import kotlinx.serialization.Serializable - -@Serializable(EncryptedElementSerializer::class) -interface WithData : EncryptedPassportElement { - val data: EncryptedData -} \ No newline at end of file diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/encrypted_data/abstracts/WithFrontSide.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/encrypted_data/abstracts/WithFrontSide.kt deleted file mode 100644 index 400ffae9cd..0000000000 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/encrypted_data/abstracts/WithFrontSide.kt +++ /dev/null @@ -1,10 +0,0 @@ -package dev.inmo.tgbotapi.types.passport.encrypted_data.abstracts - -import dev.inmo.tgbotapi.types.passport.encrypted_data.EncryptedElementSerializer -import dev.inmo.tgbotapi.types.passport.encrypted_data.PassportFile -import kotlinx.serialization.Serializable - -@Serializable(EncryptedElementSerializer::class) -interface WithFrontSide : EncryptedPassportElement { - val frontSide: PassportFile? -} \ No newline at end of file diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/encrypted_data/abstracts/WithReverseSide.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/encrypted_data/abstracts/WithReverseSide.kt deleted file mode 100644 index 059b517955..0000000000 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/encrypted_data/abstracts/WithReverseSide.kt +++ /dev/null @@ -1,10 +0,0 @@ -package dev.inmo.tgbotapi.types.passport.encrypted_data.abstracts - -import dev.inmo.tgbotapi.types.passport.encrypted_data.EncryptedElementSerializer -import dev.inmo.tgbotapi.types.passport.encrypted_data.PassportFile -import kotlinx.serialization.Serializable - -@Serializable(EncryptedElementSerializer::class) -interface WithReverseSide : EncryptedPassportElement { - val reverseSide: PassportFile? -} \ No newline at end of file diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/encrypted_data/abstracts/WithSelfie.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/encrypted_data/abstracts/WithSelfie.kt deleted file mode 100644 index fed2706bab..0000000000 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/encrypted_data/abstracts/WithSelfie.kt +++ /dev/null @@ -1,10 +0,0 @@ -package dev.inmo.tgbotapi.types.passport.encrypted_data.abstracts - -import dev.inmo.tgbotapi.types.passport.encrypted_data.EncryptedElementSerializer -import dev.inmo.tgbotapi.types.passport.encrypted_data.PassportFile -import kotlinx.serialization.Serializable - -@Serializable(EncryptedElementSerializer::class) -interface WithSelfie : EncryptedPassportElement { - val selfie: PassportFile? -} \ No newline at end of file diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/utils/passport/DecryptionContext.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/utils/passport/DecryptionContext.kt index 425970e31e..f179e3f627 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/utils/passport/DecryptionContext.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/utils/passport/DecryptionContext.kt @@ -1,32 +1,15 @@ package dev.inmo.tgbotapi.utils.passport +import dev.inmo.micro_utils.crypto.SourceBytes import dev.inmo.tgbotapi.bot.TelegramBot import dev.inmo.tgbotapi.requests.DownloadFile import dev.inmo.tgbotapi.requests.get.GetFile -import dev.inmo.tgbotapi.types.passport.encrypted_data.PassportFile -import dev.inmo.tgbotapi.types.passport.encrypted_data.abstracts.WithData +import dev.inmo.tgbotapi.types.passport.credentials.EncryptedCredentials +import dev.inmo.tgbotapi.types.passport.credentials.EncryptedData +import dev.inmo.tgbotapi.types.passport.encrypted.PassportFile import dev.inmo.tgbotapi.utils.nonstrictJsonFormat import kotlinx.serialization.json.JsonObject interface Decryptor { - fun ByteArray.decrypt(): ByteArray + fun decrypt(data: EncryptedData): SourceBytes } - -suspend fun Decryptor.decrypt( - file: PassportFile, - bot: TelegramBot -): ByteArray { - return bot.execute( - DownloadFile( - bot.execute( - GetFile(file.fileId) - ).filePath - ) - ).decrypt() -} -fun Decryptor.decryptData( - data: WithData -) = nonstrictJsonFormat.decodeFromString( - JsonObject.serializer(), - data.data.encodeToByteArray().decrypt().decodeToString() -) diff --git a/tgbotapi.core/src/jsTest/kotlin/dev/inmo/tgbotapi/passport/DecryptionTestKeys.kt b/tgbotapi.core/src/jsTest/kotlin/dev/inmo/tgbotapi/passport/DecryptionTestKeys.kt deleted file mode 100644 index e82a07397c..0000000000 --- a/tgbotapi.core/src/jsTest/kotlin/dev/inmo/tgbotapi/passport/DecryptionTestKeys.kt +++ /dev/null @@ -1,32 +0,0 @@ -package dev.inmo.tgbotapi.passport - -import dev.inmo.tgbotapi.types.passport.EncryptedAndBase64EncodedData - -//actual val privateKey = """-----BEGIN RSA PRIVATE KEY----- -//MIIEowIBAAKCAQEAt0hdC7xyjrRAXxqrd5i06haPfKLdAvRWsPy2yWtYTFom5dBj -//atMUnFKekTwsmhKbRPBoqF7Da0RF+/Y9q9zmZv05+tNz2FEYGJ6o7r/gdAEX+pKs -//Hd84avm9RahGOwbZgcE8r8Md/tg/ZJCSMsVElzM/Gw02+U1uJQE4n/E2AATbRl0M -//oWdyXjh6Zk6HMiTCvhtQOHoMa9yI00wmHVAlZonovZSRQ2mqfwPlbkDhjsDUQMZp -//WcSPQblAd8FLcWsR1Mh86rQl1GxZVWYONaNwoeATe4p6Ng438HCL7jO7nc4jXJwp -//xqwGI9eUYlHolApBeMQK7oEYDTQ+e0iTvFryPQIDAQABAoIBAAnV81BW65rm53Fz -//H/KKGmNZlJeuscefzysuVKzYeuOWDvJUTZGFBF0jPekzXn1iNDzt3d/zPe96uXq9 -//CzA26ZJrUno4cMYSDAX+NbiiSWxQRrYmut/bg86R2mtrjWFLi86fzR7tjKWJe1Vt -//QLtCxNyMXn2YJvQYCKopt501t50mjkgR3xM375cfVmpomcZXh1K+z4ZxFVzivjvK -//ZAga3BPQ/hd6dhnwUdB/yFZFao1dDmsvJVjsnjpnWD3uqtciTeg2iqtXVLpaLfbJ -//gWOt5P94uIP5r1+qvyrrPXzUGONm4l+43zgvleEgAXWGxnutsYaFfazVQ6qOVyE7 -//fGMQfcECgYEA5Zt1fwTVoYIohq4Do/y5TnNcoj4AajXZU1OutFcPM3aNex16UPBW -//hP7Gakq3TwTKxEILDqOwo86IJuG+lX18kUwaj1f/3T0kDFvE6iLimiPYRNByog4c -//Z5Kwqn+vrnl4ciRDoz7jJsURms2PE7mYV7bndA24Gb0FZJRWiB1xI+0CgYEAzFm7 -//uTSyzacTsqorkyUFIwoGgMIE5NDBQNCVhflJcrmuHRYNwxkH9HRCXqyeHKLiNPRa -//zAoBo3WynjActoy0tFJ90qZI1203iT9BMRbPDiZEXnMH4MrWmk7e7poAUsPVKaRr -//hxvHjr2gTOLY0ClolMvnyNxZcZ/jBxAG0WwK3ZECgYEAwSkdmbQZfPwg19zBF05f -//Ho6SmbMLak7O+/jkerbbBPJxZ+eOpVTrlIs5pOYifImNg7oDz1cKHWR8yikTynN9 -//PkcF+R2RFTCAiR0S9d5PQFlzccDjD05Lux5/HZC53VA3cd7sQAOB2XXkr5TLD08N -//yI0I/mskPBL23Hymp3ANZKkCgYAO2fqttCnGjnz9ACcYk5ky+biNRQyMAKv65O3p -//BbwTzXDdBkxLwJb2ajikntEC7ceY56VtrNB/q78mhgKgNcuwS0p/s7wZhAOEQwee -//5LR5p8hSQPPyn2tHXbIQDzs0yKzGUP/LmvY+5oMu81Gkl03VephG3dTWUDN0wPJt -//5/dGMQKBgE++3BNLLV8siedqwjhSrRB/KmpbLPtoOUlRJYBfG+oITgl/d/W2NKOg -//C5GztdiZUKlHsvvcYoAAWrgEE3bKg+D7GI15yzAjQQZH6AOgL+CEnunIHBaxEEgG -//RS39yB/kPcn9ZtvcJd9v8myQnQjhco8Z2RUwb6IUIoOBvZlSGhGe -//-----END RSA PRIVATE KEY-----""" -//actual val encryptedLoremIpsum: EncryptedAndBase64EncodedData = "KeuPVezTbMW4MvOGJFTAt34PRaL9iepGb1g4QEi5EQYjKXeXo7RytFOCVx6pW9O/uoMWhl+cX32kNqJVWyK7a22kuhnNT2+aiXqEpuh+madx+LK1zUvGDR1A1Mrf3fFOugcnadCQKICiqvl9cFdqsBkJQOFEs9qj5wiu1F57kekuHLWI7ZnHOojkRNq7l1aCHL0DxcLCfZW5CtWAi8g/zUE5WnGd+vUZ+hqc1vnehDul8JE8YUQbAiIxetzba9XoWouTHYZRZcNCztDbrRBYnq2UCcI5adEwQ3VNcES0lIjRuwn1BBWpvk7VOjqh+4c2tSebDX5AkqrO8XwQYwo8OwvZF+hUXFRK6QLHd4B1JQIdygCaEODG0X353upiEKJXDBqv/ZMXR9KqYZBZEfu48ZM/J6heNjVSOP4TSDrXywJgIOieu8mrQ4d7Or7Twnsu/B+bqS37PvVlfU4wHLl7ehXFj4Kusat6cIrb0R4F/Y3fL4+FcfEsk4ioEAndYBFrc1S11vo/TkcuFnXtqrr181gC5JD5LtsUH6sst36vE/JdL/UwTGqhu+rDUcgvr7FiunkasWBnzCtFs58JJrRycUKPzyKINS16GkY8yYtp7xJXBGPYOFM+J7npcKW7P41j1KceDaUArjph2yIELEXCr8qUZzWXZdrw96Te8gLi99c=" diff --git a/tgbotapi.core/src/jvmMain/kotlin/dev/inmo/tgbotapi/utils/passport/AESDecryptor.kt b/tgbotapi.core/src/jvmMain/kotlin/dev/inmo/tgbotapi/utils/passport/AESDecryptor.kt new file mode 100644 index 0000000000..99b5185bd0 --- /dev/null +++ b/tgbotapi.core/src/jvmMain/kotlin/dev/inmo/tgbotapi/utils/passport/AESDecryptor.kt @@ -0,0 +1,21 @@ +package dev.inmo.tgbotapi.utils.passport + +import dev.inmo.micro_utils.crypto.SourceBytes +import dev.inmo.tgbotapi.types.passport.credentials.EncryptedData +import javax.crypto.Cipher +import javax.crypto.spec.IvParameterSpec +import javax.crypto.spec.SecretKeySpec + +class AESDecryptor(key: SourceBytes, private val iv: ByteArray) : Decryptor { + private val key = SecretKeySpec(key, "AES"); + + override fun decrypt(data: EncryptedData): SourceBytes { + return Cipher.getInstance("AES/CBC/NOPADDING").run { + init(Cipher.DECRYPT_MODE, key, IvParameterSpec(this@AESDecryptor.iv)) + val decryptedCredentials = doFinal(data) + + val padding = decryptedCredentials.first() + decryptedCredentials.copyOfRange(padding.toInt(), decryptedCredentials.size) + } + } +} diff --git a/tgbotapi.core/src/jvmMain/kotlin/dev/inmo/tgbotapi/utils/passport/CredentialsDecrypting.kt b/tgbotapi.core/src/jvmMain/kotlin/dev/inmo/tgbotapi/utils/passport/CredentialsDecrypting.kt new file mode 100644 index 0000000000..7639ee5845 --- /dev/null +++ b/tgbotapi.core/src/jvmMain/kotlin/dev/inmo/tgbotapi/utils/passport/CredentialsDecrypting.kt @@ -0,0 +1,29 @@ +package dev.inmo.tgbotapi.utils.passport + +import dev.inmo.micro_utils.crypto.decodeBase64 +import dev.inmo.tgbotapi.types.passport.credentials.DecryptedCredentials +import dev.inmo.tgbotapi.types.passport.credentials.EncryptedCredentials +import dev.inmo.tgbotapi.utils.nonstrictJsonFormat +import java.security.* +import java.security.spec.PKCS8EncodedKeySpec +import javax.crypto.Cipher +import javax.crypto.spec.IvParameterSpec +import javax.crypto.spec.SecretKeySpec + +private val regexToRemoveFromKey = Regex("(-----(BEGIN|END) ((?:.*? KEY)|CERTIFICATE)-----|[\\s])") + +fun EncryptedCredentials.decryptWithPKCS8PrivateKey(privateKey: PrivateKey): DecryptedCredentials { + val decrypted = Cipher.getInstance("RSA/ECB/OAEPWithSHA-1AndMGF1Padding").run { + init(Cipher.DECRYPT_MODE, privateKey) + doFinal(secret) + } + val dataDecryptor = (decrypted to hash).createDecryptor() + val decryptedCredentials = dataDecryptor.decrypt(data).decodeToString() + return nonstrictJsonFormat.decodeFromString(DecryptedCredentials.serializer(), decryptedCredentials) +} + +fun EncryptedCredentials.decryptWithPKCS8PrivateKey(key: String) = decryptWithPKCS8PrivateKey( + KeyFactory.getInstance("RSA").generatePrivate( + PKCS8EncodedKeySpec(key.replace(regexToRemoveFromKey, "").decodeBase64()) + ) +) diff --git a/tgbotapi.core/src/jvmMain/kotlin/dev/inmo/tgbotapi/utils/passport/DecryptionContextRealization.kt b/tgbotapi.core/src/jvmMain/kotlin/dev/inmo/tgbotapi/utils/passport/DecryptionContextRealization.kt deleted file mode 100644 index 402a295a99..0000000000 --- a/tgbotapi.core/src/jvmMain/kotlin/dev/inmo/tgbotapi/utils/passport/DecryptionContextRealization.kt +++ /dev/null @@ -1,39 +0,0 @@ -package dev.inmo.tgbotapi.utils.passport - -import dev.inmo.micro_utils.crypto.decodeBase64 -import java.security.KeyFactory -import java.security.interfaces.RSAPrivateKey -import java.security.spec.PKCS8EncodedKeySpec -import javax.crypto.Cipher - -private val regexToRemoveFromKey = Regex("(-----(BEGIN|END) ((?:.*? KEY)|CERTIFICATE)-----|[\\s])") - -/** - * @param key PKCS8 - */ -class PKCS8Decryptor (key: String): Decryptor { - private val privateKey: RSAPrivateKey = KeyFactory.getInstance("RSA").generatePrivate( - PKCS8EncodedKeySpec(key.replace(regexToRemoveFromKey, "").decodeBase64()) - ) as RSAPrivateKey - private val chunkSize: Int = privateKey.modulus.bitLength() / 8 - - override fun ByteArray.decrypt(): ByteArray { - return Cipher.getInstance("RSA/ECB/PKCS1Padding").run { - init(Cipher.DECRYPT_MODE, privateKey) - (0 until size step chunkSize).flatMap { - val firstIndex = it - val lastIndexExclusive = if (it + chunkSize > size) { - size - } else { - it + chunkSize - } - doFinal(copyOfRange(firstIndex, lastIndexExclusive)).toList() - }.toByteArray() - } - } -} - -fun Decryptor(key: String) = PKCS8Decryptor(key) - -inline fun doWithDecryptor(decryptor: Decryptor, crossinline block: Decryptor.() -> T) = decryptor.run(block) -inline fun doWithDecryptor(key: String, crossinline block: Decryptor.() -> T) = doWithDecryptor(Decryptor(key), block) diff --git a/tgbotapi.core/src/jvmMain/kotlin/dev/inmo/tgbotapi/utils/passport/ElementDecryptingWithSecureData.kt b/tgbotapi.core/src/jvmMain/kotlin/dev/inmo/tgbotapi/utils/passport/ElementDecryptingWithSecureData.kt new file mode 100644 index 0000000000..e184139b0d --- /dev/null +++ b/tgbotapi.core/src/jvmMain/kotlin/dev/inmo/tgbotapi/utils/passport/ElementDecryptingWithSecureData.kt @@ -0,0 +1,28 @@ +package dev.inmo.tgbotapi.utils.passport + +import dev.inmo.micro_utils.crypto.SourceBytes +import dev.inmo.tgbotapi.bot.TelegramBot +import dev.inmo.tgbotapi.requests.DownloadFile +import dev.inmo.tgbotapi.requests.get.GetFile +import dev.inmo.tgbotapi.types.passport.credentials.* +import dev.inmo.tgbotapi.types.passport.encrypted.PassportFile + +fun EndDataCredentials.decryptData( + bytes: EncryptedData +): SourceBytes { + return createDecryptor().decrypt(bytes) +} + +fun FileCredentials.decryptFile( + fileBytes: ByteArray +): SourceBytes { + return createDecryptor().decrypt(fileBytes) +} +suspend fun FileCredentials.decryptFile( + bot: TelegramBot, + passportFile: PassportFile +): SourceBytes { + val pathedFile = bot.execute(GetFile(passportFile.fileId)) + val bytes = bot.execute(DownloadFile(pathedFile.filePath)) + return decryptFile(bytes) +} diff --git a/tgbotapi.core/src/jvmMain/kotlin/dev/inmo/tgbotapi/utils/passport/EndDataDecryptor.kt b/tgbotapi.core/src/jvmMain/kotlin/dev/inmo/tgbotapi/utils/passport/EndDataDecryptor.kt new file mode 100644 index 0000000000..02a509a53e --- /dev/null +++ b/tgbotapi.core/src/jvmMain/kotlin/dev/inmo/tgbotapi/utils/passport/EndDataDecryptor.kt @@ -0,0 +1,15 @@ +package dev.inmo.tgbotapi.utils.passport + +import dev.inmo.micro_utils.crypto.SourceBytes +import dev.inmo.tgbotapi.types.passport.credentials.EndDataCredentials +import java.security.MessageDigest + +fun Pair.createDecryptor(): Decryptor { + val secretHash = MessageDigest.getInstance("SHA-512").digest(first + second) + val key = secretHash.copyOf(32) + val iv = secretHash.copyOfRange(32, 48) + + return AESDecryptor(key, iv) +} + +fun EndDataCredentials.createDecryptor() = (secret to hash).createDecryptor() diff --git a/tgbotapi.core/src/jvmMain/kotlin/dev/inmo/tgbotapi/utils/passport/PassportDataDecryptionHandling.kt b/tgbotapi.core/src/jvmMain/kotlin/dev/inmo/tgbotapi/utils/passport/PassportDataDecryptionHandling.kt new file mode 100644 index 0000000000..4743dd5ac1 --- /dev/null +++ b/tgbotapi.core/src/jvmMain/kotlin/dev/inmo/tgbotapi/utils/passport/PassportDataDecryptionHandling.kt @@ -0,0 +1,15 @@ +package dev.inmo.tgbotapi.utils.passport + +import dev.inmo.tgbotapi.types.passport.PassportData +import dev.inmo.tgbotapi.types.passport.decrypted.SecureData +import java.security.PrivateKey + +inline fun PassportData.doInDecryptionContextWithPKCS8Key( + pkcs8Key: PrivateKey, + expectedNonce: String? = null, + crossinline block: SecureData.() -> T +): T { + val decryptedCredentials = credentials.decryptWithPKCS8PrivateKey(pkcs8Key) + expectedNonce ?.let { require(expectedNonce == decryptedCredentials.nonce) } + return decryptedCredentials.secureData.run(block) +} diff --git a/tgbotapi.core/src/jvmTest/kotlin/dev/inmo/tgbotapi/passport/DecryptionTest.kt b/tgbotapi.core/src/jvmTest/kotlin/dev/inmo/tgbotapi/passport/DecryptionTest.kt deleted file mode 100644 index 7f9562bffb..0000000000 --- a/tgbotapi.core/src/jvmTest/kotlin/dev/inmo/tgbotapi/passport/DecryptionTest.kt +++ /dev/null @@ -1,52 +0,0 @@ -package dev.inmo.tgbotapi.passport - -import dev.inmo.micro_utils.crypto.decodeBase64 -import dev.inmo.tgbotapi.utils.passport.Decryptor -import dev.inmo.tgbotapi.utils.passport.doWithDecryptor -import kotlin.test.Test -import kotlin.test.assertEquals - -//expect val privateKey: String -//expect val encryptedLoremIpsum: EncryptedAndBase64EncodedData -val privateKey: String = """-----BEGIN PRIVATE KEY----- -MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCaaMFkmMBi6Vl5 -vzy7wQjoZNLN+e9e6Lb/WBekJxfbNMt+EN9Zv7xT9xzfY68DX7v0uGoLcAqS5Mh5 -8ELiJbzg4O8dbxkggt0G+kxcbT+a3ofm1Aqhr+LkpsFh5qbLqbAHSQJAF0HPqrAc -5c6MoQVTZlWGU/j3enCcUFo7Jpsi8La6MqYboF5xGwGEZ9tOA6rMDSekr5Rdm637 -D/w4h284UX7VnqPdpZ/943VK2qvmPjm8HkFSxkSAB8RHlFyjazzm9FNOcVRGLynv -/cq7mWgyxt5nqiCG7w+lFNAFNQNvAO0rfeiTJbEzubquu4Mg31QrvLIuz+fUbsGk -ipfpN1czAgMBAAECggEAPlAoO8CpY0FoqolSqTKttZt6t0U2JMclksaqQ8TDC+Oy -e52zhTSre/ct37kK2AG6iHgj05nTqpRJk2wykbFJGDeuR+Kd8VDeggJg7qvoD0fe -8HiCEd45Yq0pPaknhulj8Iy2K8c29+eaSw8y2+3fiFi0CxG4V6dB6tNClrxtvxtl -IE85Utzmk4PLTCs010zxNVm+FwrvqlpjjhspljzleUuWE1KuldO9tNSlwUUfBr4i -BJJn4jDkQMloXoM/ArZEp7mn57N9+ZuEgVjRMCpRGEAbQI+aLCznBB1kCOY7WL8S -CwkP++SvcptaUpOjoXZZyuGU4CgBnu0+40ORbNchgQKBgQDLIbB9+WHDcZAn1g6M -8jaNDRU4HGu5vJSajFQK8Uaczg87hAxmk6R1GF0LOyoadaVmD5ax93mQxWSE/4hT -wyAPaQOFl7A/i1k/Dx/kURjRwF1sLWDFdMo/8t5bXumzrzb1bHYnHPS7S0lBAU+X -SrbIw+hv69aKawcQqdd54S1OBwKBgQDCmMarwMVn4xnOh+DOuLS4IQzPT84WgzH+ -wKw55hZGMqZ4S3JRVv256daweEbKAeR5NCccPmir0H86jwUW6WFAtxqfPWF4piVi -UD6DrUt0gWwzMGy3kbAp0hLBtsQRp/41mKuAXkvMVQ2ysInn6lmHhZvjduK8lvKh -fMRDMjxidQKBgFiciK5blI86wgTutwg7PRrI40HH/CJZJoZIwvzHBeOvbCutTe+N -ZoeCKkyU8af7PDzKfhWCfHBv+4qdIi5QB3NRfyzO4B7IPhVpFqN10RrnDJn9LaLV -cMj2vJMlU1OEErh7KQuk8QmnLPyDguHfwN7Rv1rbiYp2Z+2X+Zx8Y1QPAoGBAJIf -nq/CJXoJMou/xLP2Rt4tEy1pQ9vr0FL341vmxrsXtaGHJeSmagh861XAO4fdO+83 -llbDFl5ORft3Ad9eiETMOhVxRgwO1uuoTgkazBpERTd7GWgO4jXFJYiI8VpAx8b/ -SWkvZcOd6pdPsX6Qn4IAdjqsPz5WKwPQaJ/8zRMxAoGAGaOuyXaFZNl8IeTGYMDL -OEg9BHa+Du8jSv0vL/fCN2s/2TcvSa9uEnv8KHz59JHevvxoDNbQYlN8Ge8adFv4 -xZYQ3h/qh2ohnTUfrG4hcFUVBuv5HBdwgWhVFm5v98KQsqVzGfKorN2DemEv3/au -PFGkuu4lCPeDqu5u0dBojoA= ------END PRIVATE KEY-----""" -val encryptedLoremIpsum = "KeuPVezTbMW4MvOGJFTAt34PRaL9iepGb1g4QEi5EQYjKXeXo7RytFOCVx6pW9O/uoMWhl+cX32kNqJVWyK7a22kuhnNT2+aiXqEpuh+madx+LK1zUvGDR1A1Mrf3fFOugcnadCQKICiqvl9cFdqsBkJQOFEs9qj5wiu1F57kekuHLWI7ZnHOojkRNq7l1aCHL0DxcLCfZW5CtWAi8g/zUE5WnGd+vUZ+hqc1vnehDul8JE8YUQbAiIxetzba9XoWouTHYZRZcNCztDbrRBYnq2UCcI5adEwQ3VNcES0lIjRuwn1BBWpvk7VOjqh+4c2tSebDX5AkqrO8XwQYwo8OwvZF+hUXFRK6QLHd4B1JQIdygCaEODG0X353upiEKJXDBqv/ZMXR9KqYZBZEfu48ZM/J6heNjVSOP4TSDrXywJgIOieu8mrQ4d7Or7Twnsu/B+bqS37PvVlfU4wHLl7ehXFj4Kusat6cIrb0R4F/Y3fL4+FcfEsk4ioEAndYBFrc1S11vo/TkcuFnXtqrr181gC5JD5LtsUH6sst36vE/JdL/UwTGqhu+rDUcgvr7FiunkasWBnzCtFs58JJrRycUKPzyKINS16GkY8yYtp7xJXBGPYOFM+J7npcKW7P41j1KceDaUArjph2yIELEXCr8qUZzWXZdrw96Te8gLi99c=" - - -class DecryptionTest { - val inputText = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum." - - @Test - fun testThatDecryptionIsWorkingCorrectly() { - doWithDecryptor(privateKey) { - val decrypted = encryptedLoremIpsum.decodeBase64().decrypt().decodeToString() - assertEquals(inputText, decrypted) - } - } -} diff --git a/tgbotapi.extensions.api/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/api/passport/SetPassportDataErrors.kt b/tgbotapi.extensions.api/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/api/passport/SetPassportDataErrors.kt new file mode 100644 index 0000000000..5e19524a04 --- /dev/null +++ b/tgbotapi.extensions.api/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/api/passport/SetPassportDataErrors.kt @@ -0,0 +1,45 @@ +package dev.inmo.tgbotapi.extensions.api.passport + +import dev.inmo.tgbotapi.bot.TelegramBot +import dev.inmo.tgbotapi.requests.SetPassportDataErrors +import dev.inmo.tgbotapi.types.* +import dev.inmo.tgbotapi.types.message.PassportMessage +import dev.inmo.tgbotapi.types.passport.PassportData +import dev.inmo.tgbotapi.types.passport.PassportElementError +import dev.inmo.tgbotapi.types.passport.encrypted.abstracts.EncryptedPassportElement +import dev.inmo.tgbotapi.utils.passport.Decryptor + +suspend fun TelegramBot.setPassportDataErrors( + userId: UserId, + errors: List +) = execute(SetPassportDataErrors(userId, errors)) +suspend fun TelegramBot.setPassportDataErrors( + user: User, + errors: List +) = setPassportDataErrors(user.id, errors) + +suspend fun TelegramBot.setPassportDataErrors( + userId: UserId, + passportData: PassportData, + decryptor: Decryptor, + mapper: suspend Decryptor.(EncryptedPassportElement) -> PassportElementError +): Boolean = setPassportDataErrors( + userId, + passportData.data.map { decryptor.mapper(it) }.also { + if (it.isEmpty()) { + return@setPassportDataErrors false + } + } +) +suspend fun TelegramBot.setPassportDataErrors( + user: User, + passportData: PassportData, + decryptor: Decryptor, + mapper: suspend Decryptor.(EncryptedPassportElement) -> PassportElementError +) = setPassportDataErrors(user.id, passportData, decryptor, mapper) + +suspend fun TelegramBot.setPassportDataErrors( + passportMessage: PassportMessage, + decryptor: Decryptor, + mapper: suspend Decryptor.(EncryptedPassportElement) -> PassportElementError +) = setPassportDataErrors(passportMessage.user, passportMessage.passportData, decryptor, mapper) diff --git a/tgbotapi.extensions.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/expectations/WaitPassportData.kt b/tgbotapi.extensions.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/expectations/WaitPassportData.kt new file mode 100644 index 0000000000..309a4705d0 --- /dev/null +++ b/tgbotapi.extensions.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/expectations/WaitPassportData.kt @@ -0,0 +1,54 @@ +package dev.inmo.tgbotapi.extensions.behaviour_builder.expectations + +import dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContext +import dev.inmo.tgbotapi.extensions.utils.* +import dev.inmo.tgbotapi.requests.abstracts.Request +import dev.inmo.tgbotapi.types.message.PassportMessage +import dev.inmo.tgbotapi.types.passport.PassportData +import dev.inmo.tgbotapi.types.passport.encrypted.abstracts.EncryptedPassportElement +import dev.inmo.tgbotapi.utils.RiskFeature +import kotlinx.coroutines.flow.toList + +typealias PassportMessageMapper = suspend PassportMessage.() -> PassportData + +@RiskFeature("Do not use this message directly, use waitPassportMessagesWith or waitAnyPassportMessages instead") +suspend fun BehaviourContext.waitPassportMessages( + initRequest: Request<*>? = null, + errorFactory: NullableRequestBuilder<*> = { null }, + count: Int = 1, + mapper: suspend PassportMessage.() -> O? +): List = expectFlow( + initRequest, + count, + errorFactory +) { + it.asMessageUpdate() ?.data ?.asPassportMessage() ?.mapper().let(::listOfNotNull) +}.toList().toList() + +suspend inline fun BehaviourContext.waitPassportMessagesWith( + count: Int = 1, + initRequest: Request<*>? = null, + noinline errorFactory: NullableRequestBuilder<*> = { null }, + noinline filter: PassportMessageMapper? = null +) : List = waitPassportMessages( + initRequest, + errorFactory, + count +) { + if (passportData.data.any { it is T }) { + if (filter == null) { + passportData + } else { + filter(this) + } + } else { + null + } +} + +suspend fun BehaviourContext.waitAnyPassportMessages( + initRequest: Request<*>? = null, + errorFactory: NullableRequestBuilder<*> = { null }, + count: Int = 1, + filter: PassportMessageMapper? = null +) = waitPassportMessagesWith(count, initRequest, errorFactory, filter) diff --git a/tgbotapi.extensions.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/triggers_handling/PassportTriggers.kt b/tgbotapi.extensions.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/triggers_handling/PassportTriggers.kt new file mode 100644 index 0000000000..971a55419f --- /dev/null +++ b/tgbotapi.extensions.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/triggers_handling/PassportTriggers.kt @@ -0,0 +1,42 @@ +package dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling + +import dev.inmo.micro_utils.coroutines.subscribeSafelyWithoutExceptions +import dev.inmo.tgbotapi.extensions.behaviour_builder.* +import dev.inmo.tgbotapi.extensions.behaviour_builder.expectations.expectFlow +import dev.inmo.tgbotapi.extensions.utils.* +import dev.inmo.tgbotapi.extensions.utils.extensions.sourceChat +import dev.inmo.tgbotapi.types.message.PassportMessage +import dev.inmo.tgbotapi.types.passport.encrypted.abstracts.EncryptedPassportElement + +suspend inline fun BehaviourContext.onPassportMessageWith( + includeFilterByChatInBehaviourSubContext: Boolean = true, + noinline additionalFilter: (suspend (PassportMessage) -> Boolean)? = null, + noinline scenarioReceiver: BehaviourContextAndTypeReceiver +) = flowsUpdatesFilter.expectFlow(bot) { + it.asMessageUpdate() ?.data ?.asPassportMessage() ?.let { message -> + if (message.passportData.data.any { it is T }) { + if (additionalFilter == null || additionalFilter(message)) message else null + } else { + null + } + }.let(::listOfNotNull) +}.subscribeSafelyWithoutExceptions(scope) { triggerMessage -> + doInSubContextWithUpdatesFilter( + updatesFilter = if (includeFilterByChatInBehaviourSubContext) { + { it.sourceChat() ?.id ?.chatId == triggerMessage.chat.id.chatId } + } else null + ) { + scenarioReceiver(triggerMessage) + } +} + +suspend fun BehaviourContext.onPassportMessage( + includeFilterByChatInBehaviourSubContext: Boolean = true, + additionalFilter: (suspend (PassportMessage) -> Boolean)? = null, + scenarioReceiver: BehaviourContextAndTypeReceiver +) = onPassportMessageWith( + includeFilterByChatInBehaviourSubContext, + additionalFilter, + scenarioReceiver +) + diff --git a/tgbotapi.extensions.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/ClassCasts.kt b/tgbotapi.extensions.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/ClassCasts.kt index 25c0e86e29..9f25cd2f6f 100644 --- a/tgbotapi.extensions.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/ClassCasts.kt +++ b/tgbotapi.extensions.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/ClassCasts.kt @@ -37,6 +37,9 @@ import dev.inmo.tgbotapi.types.message.content.* import dev.inmo.tgbotapi.types.message.content.abstracts.* import dev.inmo.tgbotapi.types.message.content.media.* import dev.inmo.tgbotapi.types.message.payments.InvoiceContent +import dev.inmo.tgbotapi.types.passport.* +import dev.inmo.tgbotapi.types.passport.encrypted.* +import dev.inmo.tgbotapi.types.passport.encrypted.abstracts.* import dev.inmo.tgbotapi.types.polls.* import dev.inmo.tgbotapi.types.update.* import dev.inmo.tgbotapi.types.update.MediaGroupUpdates.* @@ -156,6 +159,182 @@ inline fun CallbackQuery.asUnknownCallbackQueryType(): UnknownCallbackQueryType? @PreviewFeature inline fun CallbackQuery.requireUnknownCallbackQueryType(): UnknownCallbackQueryType = this as UnknownCallbackQueryType @PreviewFeature +inline fun PassportElementError.asPassportElementErrorDataField(): PassportElementErrorDataField? = this as? PassportElementErrorDataField +@PreviewFeature +inline fun PassportElementError.requirePassportElementErrorDataField(): PassportElementErrorDataField = this as PassportElementErrorDataField +@PreviewFeature +inline fun PassportElementError.asPassportElementErrorFile(): PassportElementErrorFile? = this as? PassportElementErrorFile +@PreviewFeature +inline fun PassportElementError.requirePassportElementErrorFile(): PassportElementErrorFile = this as PassportElementErrorFile +@PreviewFeature +inline fun PassportElementError.asPassportElementErrorFiles(): PassportElementErrorFiles? = this as? PassportElementErrorFiles +@PreviewFeature +inline fun PassportElementError.requirePassportElementErrorFiles(): PassportElementErrorFiles = this as PassportElementErrorFiles +@PreviewFeature +inline fun PassportElementError.asPassportElementErrorFrontSide(): PassportElementErrorFrontSide? = this as? PassportElementErrorFrontSide +@PreviewFeature +inline fun PassportElementError.requirePassportElementErrorFrontSide(): PassportElementErrorFrontSide = this as PassportElementErrorFrontSide +@PreviewFeature +inline fun PassportElementError.asPassportElementErrorReverseSide(): PassportElementErrorReverseSide? = this as? PassportElementErrorReverseSide +@PreviewFeature +inline fun PassportElementError.requirePassportElementErrorReverseSide(): PassportElementErrorReverseSide = this as PassportElementErrorReverseSide +@PreviewFeature +inline fun PassportElementError.asPassportElementErrorSelfie(): PassportElementErrorSelfie? = this as? PassportElementErrorSelfie +@PreviewFeature +inline fun PassportElementError.requirePassportElementErrorSelfie(): PassportElementErrorSelfie = this as PassportElementErrorSelfie +@PreviewFeature +inline fun PassportElementError.asPassportElementErrorTranslationFile(): PassportElementErrorTranslationFile? = this as? PassportElementErrorTranslationFile +@PreviewFeature +inline fun PassportElementError.requirePassportElementErrorTranslationFile(): PassportElementErrorTranslationFile = this as PassportElementErrorTranslationFile +@PreviewFeature +inline fun PassportElementError.asPassportElementErrorTranslationFiles(): PassportElementErrorTranslationFiles? = this as? PassportElementErrorTranslationFiles +@PreviewFeature +inline fun PassportElementError.requirePassportElementErrorTranslationFiles(): PassportElementErrorTranslationFiles = this as PassportElementErrorTranslationFiles +@PreviewFeature +inline fun PassportElementError.asPassportElementErrorUnspecified(): PassportElementErrorUnspecified? = this as? PassportElementErrorUnspecified +@PreviewFeature +inline fun PassportElementError.requirePassportElementErrorUnspecified(): PassportElementErrorUnspecified = this as PassportElementErrorUnspecified +@PreviewFeature +inline fun PassportElementError.asPassportElementFileError(): PassportElementFileError? = this as? PassportElementFileError +@PreviewFeature +inline fun PassportElementError.requirePassportElementFileError(): PassportElementFileError = this as PassportElementFileError +@PreviewFeature +inline fun PassportElementError.asPassportElementFilesError(): PassportElementFilesError? = this as? PassportElementFilesError +@PreviewFeature +inline fun PassportElementError.requirePassportElementFilesError(): PassportElementFilesError = this as PassportElementFilesError +@PreviewFeature +inline fun PassportElementError.asPassportMultipleElementsError(): PassportMultipleElementsError? = this as? PassportMultipleElementsError +@PreviewFeature +inline fun PassportElementError.requirePassportMultipleElementsError(): PassportMultipleElementsError = this as PassportMultipleElementsError +@PreviewFeature +inline fun PassportElementError.asPassportSingleElementError(): PassportSingleElementError? = this as? PassportSingleElementError +@PreviewFeature +inline fun PassportElementError.requirePassportSingleElementError(): PassportSingleElementError = this as PassportSingleElementError +@PreviewFeature +inline fun PassportElementError.asUnknownPassportElementError(): UnknownPassportElementError? = this as? UnknownPassportElementError +@PreviewFeature +inline fun PassportElementError.requireUnknownPassportElementError(): UnknownPassportElementError = this as UnknownPassportElementError +@PreviewFeature +inline fun EncryptedPassportElement.asBankStatement(): BankStatement? = this as? BankStatement +@PreviewFeature +inline fun EncryptedPassportElement.requireBankStatement(): BankStatement = this as BankStatement +@PreviewFeature +inline fun EncryptedPassportElement.asCommonPassport(): CommonPassport? = this as? CommonPassport +@PreviewFeature +inline fun EncryptedPassportElement.requireCommonPassport(): CommonPassport = this as CommonPassport +@PreviewFeature +inline fun EncryptedPassportElement.asDriverLicense(): DriverLicense? = this as? DriverLicense +@PreviewFeature +inline fun EncryptedPassportElement.requireDriverLicense(): DriverLicense = this as DriverLicense +@PreviewFeature +inline fun EncryptedPassportElement.asEmail(): Email? = this as? Email +@PreviewFeature +inline fun EncryptedPassportElement.requireEmail(): Email = this as Email +@PreviewFeature +inline fun EncryptedPassportElement.asEncryptedAddress(): EncryptedAddress? = this as? EncryptedAddress +@PreviewFeature +inline fun EncryptedPassportElement.requireEncryptedAddress(): EncryptedAddress = this as EncryptedAddress +@PreviewFeature +inline fun EncryptedPassportElement.asEncryptedPersonalDetails(): EncryptedPersonalDetails? = this as? EncryptedPersonalDetails +@PreviewFeature +inline fun EncryptedPassportElement.requireEncryptedPersonalDetails(): EncryptedPersonalDetails = this as EncryptedPersonalDetails +@PreviewFeature +inline fun EncryptedPassportElement.asIdentityCard(): IdentityCard? = this as? IdentityCard +@PreviewFeature +inline fun EncryptedPassportElement.requireIdentityCard(): IdentityCard = this as IdentityCard +@PreviewFeature +inline fun EncryptedPassportElement.asInternalPassport(): InternalPassport? = this as? InternalPassport +@PreviewFeature +inline fun EncryptedPassportElement.requireInternalPassport(): InternalPassport = this as InternalPassport +@PreviewFeature +inline fun EncryptedPassportElement.asPassport(): Passport? = this as? Passport +@PreviewFeature +inline fun EncryptedPassportElement.requirePassport(): Passport = this as Passport +@PreviewFeature +inline fun EncryptedPassportElement.asPassportRegistration(): PassportRegistration? = this as? PassportRegistration +@PreviewFeature +inline fun EncryptedPassportElement.requirePassportRegistration(): PassportRegistration = this as PassportRegistration +@PreviewFeature +inline fun EncryptedPassportElement.asPhoneNumber(): PhoneNumber? = this as? PhoneNumber +@PreviewFeature +inline fun EncryptedPassportElement.requirePhoneNumber(): PhoneNumber = this as PhoneNumber +@PreviewFeature +inline fun EncryptedPassportElement.asRentalAgreement(): RentalAgreement? = this as? RentalAgreement +@PreviewFeature +inline fun EncryptedPassportElement.requireRentalAgreement(): RentalAgreement = this as RentalAgreement +@PreviewFeature +inline fun EncryptedPassportElement.asTemporaryRegistration(): TemporaryRegistration? = this as? TemporaryRegistration +@PreviewFeature +inline fun EncryptedPassportElement.requireTemporaryRegistration(): TemporaryRegistration = this as TemporaryRegistration +@PreviewFeature +inline fun EncryptedPassportElement.asTranslatableFilesCollection(): TranslatableFilesCollection? = this as? TranslatableFilesCollection +@PreviewFeature +inline fun EncryptedPassportElement.requireTranslatableFilesCollection(): TranslatableFilesCollection = this as TranslatableFilesCollection +@PreviewFeature +inline fun EncryptedPassportElement.asTranslatableIDDocument(): TranslatableIDDocument? = this as? TranslatableIDDocument +@PreviewFeature +inline fun EncryptedPassportElement.requireTranslatableIDDocument(): TranslatableIDDocument = this as TranslatableIDDocument +@PreviewFeature +inline fun EncryptedPassportElement.asUtilityBill(): UtilityBill? = this as? UtilityBill +@PreviewFeature +inline fun EncryptedPassportElement.requireUtilityBill(): UtilityBill = this as UtilityBill +@PreviewFeature +inline fun EncryptedPassportElement.asFilesCollection(): FilesCollection? = this as? FilesCollection +@PreviewFeature +inline fun EncryptedPassportElement.requireFilesCollection(): FilesCollection = this as FilesCollection +@PreviewFeature +inline fun EncryptedPassportElement.asTranslatable(): Translatable? = this as? Translatable +@PreviewFeature +inline fun EncryptedPassportElement.requireTranslatable(): Translatable = this as Translatable +@PreviewFeature +inline fun EncryptedPassportElement.asUnknownEncryptedPassportElement(): UnknownEncryptedPassportElement? = this as? UnknownEncryptedPassportElement +@PreviewFeature +inline fun EncryptedPassportElement.requireUnknownEncryptedPassportElement(): UnknownEncryptedPassportElement = this as UnknownEncryptedPassportElement +@PreviewFeature +inline fun EncryptedPassportElement.asWithData(): WithData? = this as? WithData +@PreviewFeature +inline fun EncryptedPassportElement.requireWithData(): WithData = this as WithData +@PreviewFeature +inline fun EncryptedPassportElement.asWithEmail(): WithEmail? = this as? WithEmail +@PreviewFeature +inline fun EncryptedPassportElement.requireWithEmail(): WithEmail = this as WithEmail +@PreviewFeature +inline fun EncryptedPassportElement.asWithFrontSide(): WithFrontSide? = this as? WithFrontSide +@PreviewFeature +inline fun EncryptedPassportElement.requireWithFrontSide(): WithFrontSide = this as WithFrontSide +@PreviewFeature +inline fun EncryptedPassportElement.asWithPhoneNumber(): WithPhoneNumber? = this as? WithPhoneNumber +@PreviewFeature +inline fun EncryptedPassportElement.requireWithPhoneNumber(): WithPhoneNumber = this as WithPhoneNumber +@PreviewFeature +inline fun EncryptedPassportElement.asWithReverseSide(): WithReverseSide? = this as? WithReverseSide +@PreviewFeature +inline fun EncryptedPassportElement.requireWithReverseSide(): WithReverseSide = this as WithReverseSide +@PreviewFeature +inline fun EncryptedPassportElement.asWithSelfie(): WithSelfie? = this as? WithSelfie +@PreviewFeature +inline fun EncryptedPassportElement.requireWithSelfie(): WithSelfie = this as WithSelfie +@PreviewFeature +inline fun Message.asAnonymousGroupMessageImpl(): AnonymousGroupMessageImpl? = this as? AnonymousGroupMessageImpl +@PreviewFeature +inline fun Message.requireAnonymousGroupMessageImpl(): AnonymousGroupMessageImpl = this as AnonymousGroupMessageImpl +@PreviewFeature +inline fun Message.asChannelMessageImpl(): ChannelMessageImpl? = this as? ChannelMessageImpl +@PreviewFeature +inline fun Message.requireChannelMessageImpl(): ChannelMessageImpl = this as ChannelMessageImpl +@PreviewFeature +inline fun Message.asFromChannelGroupMessageImpl(): FromChannelGroupMessageImpl? = this as? FromChannelGroupMessageImpl +@PreviewFeature +inline fun Message.requireFromChannelGroupMessageImpl(): FromChannelGroupMessageImpl = this as FromChannelGroupMessageImpl +@PreviewFeature +inline fun Message.asPassportMessage(): PassportMessage? = this as? PassportMessage +@PreviewFeature +inline fun Message.requirePassportMessage(): PassportMessage = this as PassportMessage +@PreviewFeature +inline fun Message.asPrivateMessageImpl(): PrivateMessageImpl? = this as? PrivateMessageImpl +@PreviewFeature +inline fun Message.requirePrivateMessageImpl(): PrivateMessageImpl = this as PrivateMessageImpl +@PreviewFeature inline fun Message.asChannelEventMessage(): ChannelEventMessage? = this as? ChannelEventMessage @PreviewFeature inline fun Message.requireChannelEventMessage(): ChannelEventMessage = this as ChannelEventMessage