diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index 24311fd9..441fe7a4 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -930,6 +930,18 @@ encryptedCredentials data:bytes hash:bytes secret:bytes = EncryptedCredentials; encryptedPassportData type:PassportDataType data:bytes files:vector value:string selfie:file = EncryptedPassportData; +//@class PassportDataError @description Contains description of an error in a Telegram Passport data; for bots only + +//@description Some field value contains an error @type Data type @field_name Field name @hash Current field value hash @message Error message +passportDataErrorField type:PassportDataType field_name:string hash:bytes message:string = PassportDataError; + +//@description Some files contain an error @type Data type @hashes Hashes of files with an error @message Error message +passportDataErrorFiles type:PassportDataType hashes:vector message:string = PassportDataError; + +//@description Selfie contains an error @type Data type @hash Current selfie hash @message Error message +passportDataErrorSelfie type:PassportDataType hash:bytes message:string = PassportDataError; + + //@class MessageContent @description Contains the content of a message //@description A text message @text Text of the message @web_page A preview of the web page that's mentioned in the text; may be null @@ -2980,6 +2992,9 @@ setPassportData data:InputPassportData password:string = PassportData; //@description Deletes Telegram Passport data @type Data type deletePassportData type:PassportDataType = Ok; +//@description Informs a user that some Telegram Passport data contains errors; for bots only. The user will not be able to resend data, until the errors are fixed @user_id User identifier @errors The errors +setPassportDataErrors user_id:int32 errors:vector = Ok; + //@description Sends phone number verification code for Telegram Passport //@phone_number The phone number of the user, in international format @allow_flash_call Pass true if the authentication code may be sent via flash call to the specified phone number @is_current_phone_number Pass true if the phone number is used on the current device. Ignored if allow_flash_call is false diff --git a/td/generate/scheme/td_api.tlo b/td/generate/scheme/td_api.tlo index 656ae89b..7ec64431 100644 Binary files a/td/generate/scheme/td_api.tlo and b/td/generate/scheme/td_api.tlo differ diff --git a/td/generate/scheme/telegram_api.tl b/td/generate/scheme/telegram_api.tl index e4f89356..28594dc4 100644 --- a/td/generate/scheme/telegram_api.tl +++ b/td/generate/scheme/telegram_api.tl @@ -861,9 +861,14 @@ inputSecureValue#c0da30f0 flags:# type:SecureValueType data:flags.0?SecureData f secureValueHash#ed1ecdb0 type:SecureValueType hash:bytes = SecureValueHash; +secureValueErrorData#e8a40bd9 type:SecureValueType data_hash:bytes field:string text:string = SecureValueError; +secureValueErrorFile#7a700873 type:SecureValueType file_hash:bytes text:string = SecureValueError; +secureValueErrorFiles#666220e9 type:SecureValueType file_hash:Vector text:string = SecureValueError; +secureValueErrorSelfie#e537ced6 type:SecureValueType file_hash:bytes text:string = SecureValueError; + secureCredentialsEncrypted#33f0ea47 data:bytes hash:bytes secret:bytes = SecureCredentialsEncrypted; -account.authorizationForm#b9d3d1f0 flags:# selfie_required:flags.1?true required_types:Vector values:Vector users:Vector privacy_policy_url:flags.0?string = account.AuthorizationForm; +account.authorizationForm#cb976d53 flags:# selfie_required:flags.1?true required_types:Vector values:Vector errors:Vector users:Vector privacy_policy_url:flags.0?string = account.AuthorizationForm; account.sentEmailCode#811f854f email_pattern:string length:int = account.SentEmailCode; @@ -930,6 +935,7 @@ account.getAllSecureValues#b288bc7d = Vector; account.getSecureValue#73665bc2 types:Vector = Vector; account.saveSecureValue#899fe31d value:InputSecureValue secure_secret_id:long = SecureValue; account.deleteSecureValue#b880bc4b types:Vector = Bool; +account.setSecureValueErrors#d0093ce4 user_id:InputUser errors:Vector = Bool; account.getAuthorizationForm#b86ba8e1 bot_id:int scope:string public_key:string = account.AuthorizationForm; account.acceptAuthorization#e7027c94 bot_id:int scope:string public_key:string value_hashes:Vector credentials:SecureCredentialsEncrypted = Bool; account.sendVerifyPhoneCode#823380b4 flags:# allow_flashcall:flags.0?true phone_number:string current_number:flags.0?Bool = auth.SentCode; diff --git a/td/generate/scheme/telegram_api.tlo b/td/generate/scheme/telegram_api.tlo index 72e7b4df..bb5a1471 100644 Binary files a/td/generate/scheme/telegram_api.tlo and b/td/generate/scheme/telegram_api.tlo differ diff --git a/td/generate/tl_writer_c.h b/td/generate/tl_writer_c.h index 9402bae7..d3276f33 100644 --- a/td/generate/tl_writer_c.h +++ b/td/generate/tl_writer_c.h @@ -229,6 +229,10 @@ class TlWriterCCommon : public tl::TL_writer { "#ifdef __cplusplus\n" "extern \"C\" {\n" "#endif\n" + "struct TdBytes {\n" + " unsigned char *data;\n" + " int len;\n" + "};\n" "#define TDC_VECTOR(tdc_type_name,tdc_type) \\\n" " struct TdVector ## tdc_type_name { \\\n" " int len;\\\n" @@ -238,6 +242,7 @@ class TlWriterCCommon : public tl::TL_writer { "TDC_VECTOR(Int,int)\n" "TDC_VECTOR(Long,long long)\n" "TDC_VECTOR(String,char *)\n" + "TDC_VECTOR(Bytes,TdBytes)\n" "struct TdStackStorerMethods {\n" " void (*pack_string)(const char *s);\n" " void (*pack_bytes)(const unsigned char *s, int len);\n" @@ -259,10 +264,6 @@ class TlWriterCCommon : public tl::TL_writer { " void (*get_arr_field)(int idx);\n" " int (*get_arr_size)(void);\n" " int (*is_nil)(void);\n" - "};\n" - "struct TdBytes {\n" - " unsigned char *data;\n" - " int len;\n" "};\n"; } if (is_header_ == -1) { diff --git a/td/telegram/SecureManager.cpp b/td/telegram/SecureManager.cpp index 43595ba0..00499e77 100644 --- a/td/telegram/SecureManager.cpp +++ b/td/telegram/SecureManager.cpp @@ -9,6 +9,7 @@ #include "td/telegram/ContactsManager.h" #include "td/telegram/files/FileManager.h" #include "td/telegram/Global.h" +#include "td/telegram/misc.h" #include "td/telegram/net/NetQueryDispatcher.h" #include "td/telegram/PasswordManager.h" #include "td/telegram/Td.h" @@ -22,6 +23,35 @@ namespace td { +class SetSecureValueErrorsQuery : public Td::ResultHandler { + Promise promise_; + + public: + explicit SetSecureValueErrorsQuery(Promise &&promise) : promise_(std::move(promise)) { + } + + void send(tl_object_ptr input_user, + vector> input_errors) { + send_query(G()->net_query_creator().create( + create_storer(telegram_api::account_setSecureValueErrors(std::move(input_user), std::move(input_errors))))); + } + + void on_result(uint64 id, BufferSlice packet) override { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(id, result_ptr.move_as_error()); + } + + bool ptr = result_ptr.move_as_ok(); + LOG(DEBUG) << "Receive result for SetSecureValueErrorsQuery " << ptr; + promise_.set_value(Unit()); + } + + void on_error(uint64 id, Status status) override { + promise_.set_error(std::move(status)); + } +}; + GetSecureValue::GetSecureValue(ActorShared<> parent, std::string password, SecureValueType type, Promise promise) : parent_(std::move(parent)), password_(std::move(password)), type_(type), promise_(std::move(promise)) { @@ -483,6 +513,74 @@ void SecureManager::delete_secure_value(SecureValueType type, Promise prom // TODO } +void SecureManager::set_secure_value_errors(Td *td, tl_object_ptr input_user, + vector> errors, + Promise promise) { + CHECK(td != nullptr); + CHECK(input_user != nullptr); + vector> input_errors; + for (auto &error_ptr : errors) { + if (error_ptr == nullptr) { + return promise.set_error(Status::Error(400, "Error must be non-empty")); + } + switch (error_ptr->get_id()) { + case td_api::passportDataErrorField::ID: { + auto error = td_api::move_object_as(error_ptr); + if (error->type_ == nullptr) { + return promise.set_error(Status::Error(400, "Type must be non-empty")); + } + if (!clean_input_string(error->message_)) { + return promise.set_error(Status::Error(400, "Error message must be encoded in UTF-8")); + } + if (!clean_input_string(error->field_name_)) { + return promise.set_error(Status::Error(400, "Field name must be encoded in UTF-8")); + } + + auto type = get_secure_value_type_object(get_secure_value_type_td_api(error->type_)); + input_errors.push_back(make_tl_object( + std::move(type), BufferSlice(error->hash_), error->field_name_, error->message_)); + break; + } + case td_api::passportDataErrorFiles::ID: { + auto error = td_api::move_object_as(error_ptr); + if (error->type_ == nullptr) { + return promise.set_error(Status::Error(400, "Type must be non-empty")); + } + if (!clean_input_string(error->message_)) { + return promise.set_error(Status::Error(400, "Error message must be encoded in UTF-8")); + } + if (error->hashes_.empty()) { + return promise.set_error(Status::Error(400, "Error hashes must be non-empty")); + } + + auto type = get_secure_value_type_object(get_secure_value_type_td_api(error->type_)); + auto hashes = transform(error->hashes_, [](Slice hash) { return BufferSlice(hash); }); + input_errors.push_back( + make_tl_object(std::move(type), std::move(hashes), error->message_)); + break; + } + case td_api::passportDataErrorSelfie::ID: { + auto error = td_api::move_object_as(error_ptr); + if (error->type_ == nullptr) { + return promise.set_error(Status::Error(400, "Type must be non-empty")); + } + if (!clean_input_string(error->message_)) { + return promise.set_error(Status::Error(400, "Error message must be encoded in UTF-8")); + } + + auto type = get_secure_value_type_object(get_secure_value_type_td_api(error->type_)); + input_errors.push_back(make_tl_object( + std::move(type), BufferSlice(error->hash_), error->message_)); + break; + } + default: + UNREACHABLE(); + } + } + td->create_handler(std::move(promise)) + ->send(std::move(input_user), std::move(input_errors)); +} + void SecureManager::get_passport_authorization_form(string password, UserId bot_user_id, string scope, string public_key, string payload, Promise promise) { diff --git a/td/telegram/SecureManager.h b/td/telegram/SecureManager.h index f7a185fb..b40dcc7a 100644 --- a/td/telegram/SecureManager.h +++ b/td/telegram/SecureManager.h @@ -26,6 +26,8 @@ namespace td { +class Td; + using TdApiSecureValue = td_api::object_ptr; using TdApiAllSecureValues = td_api::object_ptr; using TdApiAuthorizationForm = td_api::object_ptr; @@ -128,6 +130,8 @@ class SecureManager : public NetQueryCallback { void get_all_secure_values(std::string password, Promise promise); void set_secure_value(string password, SecureValue secure_value, Promise promise); void delete_secure_value(SecureValueType type, Promise promise); + void set_secure_value_errors(Td *td, tl_object_ptr input_user, + vector> errors, Promise promise); void get_passport_authorization_form(string password, UserId bot_user_id, string scope, string public_key, string payload, Promise promise); diff --git a/td/telegram/Td.cpp b/td/telegram/Td.cpp index 9288cca6..f958ac29 100644 --- a/td/telegram/Td.cpp +++ b/td/telegram/Td.cpp @@ -6892,6 +6892,19 @@ void Td::on_request(uint64 id, const td_api::deletePassportData &request) { std::move(promise)); } +void Td::on_request(uint64 id, td_api::setPassportDataErrors &request) { + CHECK_AUTH(); + CHECK_IS_BOT(); + UserId user_id(request.user_id_); + auto input_user = contacts_manager_->get_input_user(user_id); + if (input_user == nullptr) { + return send_error_raw(id, 400, "User not found"); + } + CREATE_OK_REQUEST_PROMISE(promise); + send_closure(secure_manager_, &SecureManager::set_secure_value_errors, this, std::move(input_user), + std::move(request.errors_), std::move(promise)); +} + void Td::on_request(uint64 id, td_api::sendPhoneNumberVerificationCode &request) { CHECK_AUTH(); CHECK_IS_USER(); diff --git a/td/telegram/Td.h b/td/telegram/Td.h index bf99bc71..74051602 100644 --- a/td/telegram/Td.h +++ b/td/telegram/Td.h @@ -753,6 +753,8 @@ class Td final : public NetQueryCallback { void on_request(uint64 id, const td_api::deletePassportData &request); + void on_request(uint64 id, td_api::setPassportDataErrors &request); + void on_request(uint64 id, td_api::sendPhoneNumberVerificationCode &request); void on_request(uint64 id, const td_api::resendPhoneNumberVerificationCode &request);