diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index a55cc3ae..cab1e4c7 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -836,9 +836,12 @@ passportData type:PassportDataType data:string files:vector selfie:file = //@description Contains information about a Telegram Passport data to save @type Telegram Passport data type @data TODO data should be typed @files List of attached files with a document @selfie Selfie with the document inputPassportData type:PassportDataType data:string files:vector selfie:InputFile = InputPassportData; +//@description Contains information about all filled Telegram Passport data @data All filled Telegram Passport data +allPassportData data:vector = AllPassportData; -//@description Contains information about requested Telegram Passport authorization form @id Authorization form unique identifier @data Available data -passportAuthorizationForm id:int32 data:vector selfie_required:Bool privacy_policy_url:string = PassportAuthorizationForm; + +//@description Contains information about requested Telegram Passport authorization form @id Authorization form unique identifier @data Available data @is_selfie_required True, if selfie is required with a document @privacy_policy_url URL with the service privacy policy +passportAuthorizationForm id:int32 data:vector is_selfie_required:Bool privacy_policy_url:string = PassportAuthorizationForm; //@description Contains an encrypted Telegram Passport data credentials @data The encrypted credentials @hash The decrypted data hash @secret Encrypted by service public key secret for data decryption @@ -2881,6 +2884,9 @@ resetNetworkStatistics = Ok; //@description Returns filled Telegram Passport data @type Data type @password Password of the current user getPassportData type:PassportDataType password:string = PassportData; +//@description Returns all filled Telegram Passport data @password Password of the current user +getAllPassportData password:string = AllPassportData; + //@description Sets Telegram Passport data @data Input Telegram Passport data @password Password of the current user setPassportData data:inputPassportData password:string = PassportData; @@ -2909,10 +2915,10 @@ resendEmailAddressVerificationCode = EmailAddressAuthenticationCodeInfo; checkEmailAddressVerificationCode code:string = Ok; -//@description Returns Telegram Passport authorization form for sharing data with a service @bot_id Service's bot identifier @scope Telegram Passport data types requested by the service @public_key Service's public_key @password Password of the current user -getPassportAuthorizationForm bot_id:int32 scope:string public_key:string payload:string password:string = PassportAuthorizationForm; +//@description Returns Telegram Passport authorization form for sharing data with a service @bot_user_id Service's bot user identifier @scope Telegram Passport data types requested by the service @public_key Service's public_key @payload Authorization form payload provided by the service @password Password of the current user +getPassportAuthorizationForm bot_user_id:int32 scope:string public_key:string payload:string password:string = PassportAuthorizationForm; -//@description Sends Telegram Passport authorization form, effectively sharing data with the service @autorization_form_id Authorization form identifier +//@description Sends Telegram Passport authorization form, effectively sharing data with the service @autorization_form_id Authorization form identifier @types Types of Telegram Passport data chosen by user to complete the authorization form @password Password of the current user sendPassportAuthorizationForm autorization_form_id:int32 types:vector password:string = Ok; diff --git a/td/generate/scheme/td_api.tlo b/td/generate/scheme/td_api.tlo index 8192a445..681ae813 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 7dedeed4..edab392f 100644 --- a/td/generate/scheme/telegram_api.tl +++ b/td/generate/scheme/telegram_api.tl @@ -932,6 +932,7 @@ account.getTmpPassword#4a82327e password_hash:bytes period:int = account.TmpPass account.getWebAuthorizations#182e6d6f = account.WebAuthorizations; account.resetWebAuthorization#2d01b9ef hash:long = Bool; account.resetWebAuthorizations#682d2594 = Bool; +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; diff --git a/td/generate/scheme/telegram_api.tlo b/td/generate/scheme/telegram_api.tlo index deb283d2..1ef5b461 100644 Binary files a/td/generate/scheme/telegram_api.tlo and b/td/generate/scheme/telegram_api.tlo differ diff --git a/td/telegram/MessagesManager.cpp b/td/telegram/MessagesManager.cpp index 815b6488..44a110c4 100644 --- a/td/telegram/MessagesManager.cpp +++ b/td/telegram/MessagesManager.cpp @@ -21554,7 +21554,7 @@ unique_ptr MessagesManager::get_message_action_content( auto secure_values = move_tl_object_as(action); return make_unique( get_encrypted_secure_values(td_->file_manager_.get(), std::move(secure_values->values_)), - get_secure_credentials(std::move(secure_values->credentials_))); + get_encrypted_secure_credentials(std::move(secure_values->credentials_))); } default: UNREACHABLE(); diff --git a/td/telegram/SecureManager.cpp b/td/telegram/SecureManager.cpp index 8197eca8..66fb4a6b 100644 --- a/td/telegram/SecureManager.cpp +++ b/td/telegram/SecureManager.cpp @@ -6,11 +6,14 @@ // #include "td/telegram/SecureManager.h" +#include "td/telegram/files/FileManager.h" #include "td/telegram/Global.h" -#include "td/telegram/PasswordManager.h" #include "td/telegram/net/NetQueryDispatcher.h" +#include "td/telegram/PasswordManager.h" +#include "td/telegram/Td.h" namespace td { + 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)) { @@ -35,7 +38,8 @@ void GetSecureValue::loop() { if (!encrypted_secure_value_ || !secret_) { return; } - auto *file_manager = G()->file_manager().get_actor_unsafe(); + + auto *file_manager = G()->td().get_actor_unsafe()->file_manager_.get(); auto r_secure_value = decrypt_encrypted_secure_value(file_manager, *secret_, *encrypted_secure_value_); if (r_secure_value.is_error()) { return on_error(r_secure_value.move_as_error()); @@ -64,11 +68,72 @@ void GetSecureValue::on_result(NetQueryPtr query) { return on_error(r_result.move_as_error()); } auto result = r_result.move_as_ok(); + if (result.empty()) { + return on_error(Status::Error(404, "Not Found")); + } if (result.size() != 1) { return on_error(Status::Error(PSLICE() << "Expected vector of size 1 got " << result.size())); } LOG(ERROR) << to_string(result[0]); - encrypted_secure_value_ = get_encrypted_secure_value(G()->file_manager().get_actor_unsafe(), std::move(result[0])); + encrypted_secure_value_ = + get_encrypted_secure_value(G()->td().get_actor_unsafe()->file_manager_.get(), std::move(result[0])); + loop(); +} + +GetAllSecureValues::GetAllSecureValues(ActorShared<> parent, std::string password, + Promise promise) + : parent_(std::move(parent)), password_(std::move(password)), promise_(std::move(promise)) { +} + +void GetAllSecureValues::on_error(Status status) { + promise_.set_error(std::move(status)); + stop(); +} + +void GetAllSecureValues::on_secret(Result r_secret, bool dummy) { + LOG_IF(ERROR, r_secret.is_error()) << r_secret.error(); + LOG_IF(ERROR, r_secret.is_ok()) << r_secret.ok().get_hash(); + if (r_secret.is_error()) { + return on_error(r_secret.move_as_error()); + } + secret_ = r_secret.move_as_ok(); + loop(); +} + +void GetAllSecureValues::loop() { + if (!encrypted_secure_values_ || !secret_) { + return; + } + + auto *file_manager = G()->td().get_actor_unsafe()->file_manager_.get(); + auto r_secure_values = decrypt_encrypted_secure_values(file_manager, *secret_, *encrypted_secure_values_); + if (r_secure_values.is_error()) { + return on_error(r_secure_values.move_as_error()); + } + auto secure_values = transform(r_secure_values.move_as_ok(), + [](SecureValueWithCredentials &&value) { return std::move(value.value); }); + promise_.set_result(get_all_passport_data_object(file_manager, std::move(secure_values))); + stop(); +} + +void GetAllSecureValues::start_up() { + auto query = G()->net_query_creator().create(create_storer(telegram_api::account_getAllSecureValues())); + + G()->net_query_dispatcher().dispatch_with_callback(std::move(query), actor_shared(this)); + + send_closure(G()->password_manager(), &PasswordManager::get_secure_secret, password_, optional(), + PromiseCreator::lambda([actor_id = actor_id(this)](Result r_secret) { + send_closure(actor_id, &GetAllSecureValues::on_secret, std::move(r_secret), true); + })); +} + +void GetAllSecureValues::on_result(NetQueryPtr query) { + auto r_result = fetch_result(std::move(query)); + if (r_result.is_error()) { + return on_error(r_result.move_as_error()); + } + encrypted_secure_values_ = + get_encrypted_secure_values(G()->td().get_actor_unsafe()->file_manager_.get(), r_result.move_as_ok()); loop(); } @@ -188,7 +253,7 @@ void SetSecureValue::loop() { if (files_left_to_upload_ != 0) { return; } - auto *file_manager = G()->file_manager().get_actor_unsafe(); + auto *file_manager = G()->td().get_actor_unsafe()->file_manager_.get(); auto input_secure_value = get_input_secure_value_object( file_manager, encrypt_secure_value(file_manager, *secret_, secure_value_), to_upload_, selfie_); auto save_secure_value = @@ -202,7 +267,7 @@ void SetSecureValue::loop() { } void SetSecureValue::tear_down() { - auto *file_manager = G()->file_manager().get_actor_unsafe(); + auto *file_manager = G()->td().get_actor_unsafe()->file_manager_.get(); for (auto &file_info : to_upload_) { file_manager->upload(file_info.file_id, nullptr, 0, 0); } @@ -215,7 +280,7 @@ void SetSecureValue::on_result(NetQueryPtr query) { } auto result = r_result.move_as_ok(); LOG(ERROR) << to_string(result); - auto *file_manager = G()->file_manager().get_actor_unsafe(); + auto *file_manager = G()->td().get_actor_unsafe()->file_manager_.get(); auto encrypted_secure_value = get_encrypted_secure_value(file_manager, std::move(result)); if (secure_value_.files.size() != encrypted_secure_value.files.size()) { return on_error(Status::Error("Different files count")); @@ -248,12 +313,12 @@ void SetSecureValue::merge(FileManager *file_manager, FileId file_id, EncryptedS class GetPassportAuthorizationForm : public NetQueryCallback { public: - GetPassportAuthorizationForm(ActorShared<> parent, string password, int32 authorization_form_id, int32 bot_id, + GetPassportAuthorizationForm(ActorShared<> parent, string password, int32 authorization_form_id, UserId bot_user_id, string scope, string public_key, Promise promise) : parent_(std::move(parent)) , password_(std::move(password)) , authorization_form_id_(authorization_form_id) - , bot_id_(bot_id) + , bot_user_id_(bot_user_id) , scope_(std::move(scope)) , public_key_(std::move(public_key)) , promise_(std::move(promise)) { @@ -263,7 +328,7 @@ class GetPassportAuthorizationForm : public NetQueryCallback { ActorShared<> parent_; string password_; int32 authorization_form_id_; - int32 bot_id_; + UserId bot_user_id_; string scope_; string public_key_; Promise promise_; @@ -287,7 +352,7 @@ class GetPassportAuthorizationForm : public NetQueryCallback { void start_up() override { auto account_get_authorization_form = - telegram_api::account_getAuthorizationForm(bot_id_, std::move(scope_), std::move(public_key_)); + telegram_api::account_getAuthorizationForm(bot_user_id_.get(), std::move(scope_), std::move(public_key_)); auto query = G()->net_query_creator().create(create_storer(account_get_authorization_form)); G()->net_query_dispatcher().dispatch_with_callback(std::move(query), actor_shared(this)); @@ -310,7 +375,7 @@ class GetPassportAuthorizationForm : public NetQueryCallback { if (!secret_ || !authorization_form_) { return; } - auto *file_manager = G()->file_manager().get_actor_unsafe(); + auto *file_manager = G()->td().get_actor_unsafe()->file_manager_.get(); std::vector values; auto types = get_secure_value_types(std::move(authorization_form_->required_types_)); for (auto type : types) { @@ -353,7 +418,7 @@ void SecureManager::get_secure_value(std::string password, SecureValueType type, if (r_secure_value.is_error()) { return promise.set_error(r_secure_value.move_as_error()); } - auto *file_manager = G()->file_manager().get_actor_unsafe(); + auto *file_manager = G()->td().get_actor_unsafe()->file_manager_.get(); promise.set_value(get_passport_data_object(file_manager, r_secure_value.move_as_ok().value)); }); do_get_secure_value(std::move(password), type, std::move(new_promise)); @@ -366,6 +431,12 @@ void SecureManager::do_get_secure_value(std::string password, SecureValueType ty .release(); } +void SecureManager::get_all_secure_values(std::string password, Promise promise) { + refcnt_++; + create_actor("GetAllSecureValues", actor_shared(), std::move(password), std::move(promise)) + .release(); +} + void SecureManager::set_secure_value(string password, SecureValue secure_value, Promise promise) { refcnt_++; auto type = secure_value.type; @@ -374,21 +445,22 @@ void SecureManager::set_secure_value(string password, SecureValue secure_value, if (r_secure_value.is_error()) { return promise.set_error(r_secure_value.move_as_error()); } - auto *file_manager = G()->file_manager().get_actor_unsafe(); + auto *file_manager = G()->td().get_actor_unsafe()->file_manager_.get(); promise.set_value(get_passport_data_object(file_manager, r_secure_value.move_as_ok().value)); }); set_secure_value_queries_[type] = create_actor("SetSecureValue", actor_shared(), std::move(password), std::move(secure_value), std::move(new_promise)); } -void SecureManager::get_passport_authorization_form(string password, int32 bot_id, string scope, string public_key, - string payload, Promise promise) { +void SecureManager::get_passport_authorization_form(string password, UserId bot_user_id, string scope, + string public_key, string payload, + Promise promise) { refcnt_++; auto authorization_form_id = ++authorization_form_id_; - authorization_forms_[authorization_form_id] = AuthorizationForm{bot_id, scope, public_key, payload}; + authorization_forms_[authorization_form_id] = AuthorizationForm{bot_user_id, scope, public_key, payload}; create_actor("GetPassportAuthorizationForm", actor_shared(), std::move(password), - authorization_form_id, bot_id, std::move(scope), std::move(public_key), - std::move(promise)) + authorization_form_id, bot_user_id, std::move(scope), + std::move(public_key), std::move(promise)) .release(); } @@ -465,7 +537,7 @@ void SecureManager::do_send_passport_authorization_form(int32 authorization_form } auto td_query = telegram_api::account_acceptAuthorization( - it->second.bot_id, it->second.scope, it->second.public_key, std::move(hashes), + it->second.bot_user_id.get(), it->second.scope, it->second.public_key, std::move(hashes), get_secure_credentials_encrypted_object(r_encrypted_credentials.move_as_ok())); LOG(ERROR) << to_string(td_query); auto query = G()->net_query_creator().create(create_storer(td_query)); @@ -490,12 +562,14 @@ void SecureManager::hangup() { void SecureManager::hangup_shared() { dec_refcnt(); } + void SecureManager::dec_refcnt() { refcnt_--; if (refcnt_ == 0) { stop(); } } + void SecureManager::on_result(NetQueryPtr query) { auto token = get_link_token(); container_.extract(token).set_value(std::move(query)); @@ -505,4 +579,5 @@ void SecureManager::send_with_promise(NetQueryPtr query, Promise pr auto id = container_.create(std::move(promise)); G()->net_query_dispatcher().dispatch_with_callback(std::move(query), actor_shared(this, id)); } + } // namespace td diff --git a/td/telegram/SecureManager.h b/td/telegram/SecureManager.h index 93a51b1c..9e449913 100644 --- a/td/telegram/SecureManager.h +++ b/td/telegram/SecureManager.h @@ -5,19 +5,24 @@ // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #pragma once + #include "td/actor/actor.h" +#include "td/telegram/files/FileManager.h" #include "td/telegram/net/NetQuery.h" #include "td/telegram/SecureValue.h" -#include "td/telegram/files/FileManager.h" +#include "td/telegram/UserId.h" #include "td/telegram/td_api.h" #include "td/utils/optional.h" namespace td { + using TdApiSecureValue = td_api::object_ptr; +using TdApiAllSecureValues = td_api::object_ptr; using TdApiAuthorizationForm = td_api::object_ptr; + class GetSecureValue : public NetQueryCallback { public: GetSecureValue(ActorShared<> parent, std::string password, SecureValueType type, @@ -39,6 +44,25 @@ class GetSecureValue : public NetQueryCallback { void on_result(NetQueryPtr query) override; }; +class GetAllSecureValues : public NetQueryCallback { + public: + GetAllSecureValues(ActorShared<> parent, std::string password, Promise promise); + + private: + ActorShared<> parent_; + string password_; + Promise promise_; + optional> encrypted_secure_values_; + optional secret_; + + void on_error(Status status); + void on_secret(Result r_secret, bool dummy); + void loop() override; + void start_up() override; + + void on_result(NetQueryPtr query) override; +}; + class SetSecureValue : public NetQueryCallback { public: SetSecureValue(ActorShared<> parent, string password, SecureValue secure_value, @@ -91,13 +115,14 @@ class SetSecureValue : public NetQueryCallback { class SecureManager : public NetQueryCallback { public: - SecureManager(ActorShared<> parent); + explicit SecureManager(ActorShared<> parent); void get_secure_value(std::string password, SecureValueType type, Promise promise); + void get_all_secure_values(std::string password, Promise promise); void set_secure_value(string password, SecureValue secure_value, Promise promise); - void get_passport_authorization_form(string password, int32 bot_id, string scope, string public_key, string payload, - Promise promise); + void get_passport_authorization_form(string password, UserId bot_user_id, string scope, string public_key, + string payload, Promise promise); void send_passport_authorization_form(string password, int32 authorization_form_id, std::vector types, Promise<> promise); @@ -107,7 +132,7 @@ class SecureManager : public NetQueryCallback { std::map> set_secure_value_queries_; struct AuthorizationForm { - int32 bot_id; + UserId bot_user_id; string scope; string public_key; string payload; @@ -127,4 +152,5 @@ class SecureManager : public NetQueryCallback { Container> container_; void send_with_promise(NetQueryPtr query, Promise promise); }; + } // namespace td diff --git a/td/telegram/SecureValue.cpp b/td/telegram/SecureValue.cpp index a51566b3..bc94624f 100644 --- a/td/telegram/SecureValue.cpp +++ b/td/telegram/SecureValue.cpp @@ -7,14 +7,17 @@ #include "td/telegram/SecureValue.h" #include "td/telegram/files/FileManager.h" + #include "td/telegram/td_api.h" #include "td/telegram/telegram_api.h" #include "td/telegram/telegram_api.hpp" +#include "td/utils/base64.h" +#include "td/utils/JsonBuilder.h" #include "td/utils/misc.h" #include "td/utils/overloaded.h" -#include "td/utils/JsonBuilder.h" -#include "td/utils/base64.h" + +#include namespace td { @@ -157,8 +160,8 @@ bool operator!=(const EncryptedSecureFile &lhs, const EncryptedSecureFile &rhs) return !(lhs == rhs); } -EncryptedSecureFile get_secure_file(FileManager *file_manager, - tl_object_ptr &&secure_file_ptr) { +EncryptedSecureFile get_encrypted_secure_file(FileManager *file_manager, + tl_object_ptr &&secure_file_ptr) { CHECK(secure_file_ptr != nullptr); EncryptedSecureFile result; switch (secure_file_ptr->get_id()) { @@ -184,12 +187,12 @@ EncryptedSecureFile get_secure_file(FileManager *file_manager, return result; } -vector get_secure_files(FileManager *file_manager, - vector> &&secure_files) { +vector get_encrypted_secure_files(FileManager *file_manager, + vector> &&secure_files) { vector results; results.reserve(secure_files.size()); for (auto &secure_file : secure_files) { - auto result = get_secure_file(file_manager, std::move(secure_file)); + auto result = get_encrypted_secure_file(file_manager, std::move(secure_file)); if (result.file_id.is_valid()) { results.push_back(std::move(result)); } @@ -250,7 +253,7 @@ bool operator!=(const EncryptedSecureData &lhs, const EncryptedSecureData &rhs) return !(lhs == rhs); } -EncryptedSecureData get_secure_data(tl_object_ptr &&secure_data) { +EncryptedSecureData get_encrypted_secure_data(tl_object_ptr &&secure_data) { CHECK(secure_data != nullptr); EncryptedSecureData result; result.data = secure_data->data_.as_slice().str(); @@ -292,11 +295,11 @@ EncryptedSecureValue get_encrypted_secure_value(FileManager *file_manager, } } if (secure_value->data_ != nullptr) { - result.data = get_secure_data(std::move(secure_value->data_)); + result.data = get_encrypted_secure_data(std::move(secure_value->data_)); } - result.files = get_secure_files(file_manager, std::move(secure_value->files_)); + result.files = get_encrypted_secure_files(file_manager, std::move(secure_value->files_)); if (secure_value->selfie_ != nullptr) { - result.selfie = get_secure_file(file_manager, std::move(secure_value->selfie_)); + result.selfie = get_encrypted_secure_file(file_manager, std::move(secure_value->selfie_)); } result.hash = secure_value->hash_.as_slice().str(); return result; @@ -369,7 +372,7 @@ telegram_api::object_ptr get_secure_cr BufferSlice(credentials.data), BufferSlice(credentials.hash), BufferSlice(credentials.encrypted_secret)); } -EncryptedSecureCredentials get_secure_credentials( +EncryptedSecureCredentials get_encrypted_secure_credentials( tl_object_ptr &&credentials) { CHECK(credentials != nullptr); EncryptedSecureCredentials result; @@ -419,6 +422,12 @@ td_api::object_ptr get_passport_data_object(FileManager *f std::move(files), std::move(selfie)); } +td_api::object_ptr get_all_passport_data_object(FileManager *file_manager, + const vector &value) { + return td_api::make_object(transform( + value, [file_manager](const SecureValue &value) { return get_passport_data_object(file_manager, value); })); +} + Result> decrypt_secure_file(FileManager *file_manager, const secure_storage::Secret &master_secret, const EncryptedSecureFile &secure_file) { @@ -447,6 +456,7 @@ Result, vector>> decrypt_secure_ return std::make_pair(std::move(res), std::move(credentials)); } + Result> decrypt_secure_data(const secure_storage::Secret &master_secret, const EncryptedSecureData &secure_data) { TRY_RESULT(hash, secure_storage::ValueHash::create(secure_data.hash)); @@ -489,6 +499,19 @@ Result decrypt_encrypted_secure_value(FileManager *f return SecureValueWithCredentials{std::move(res), std::move(res_credentials)}; } +Result> decrypt_encrypted_secure_values( + FileManager *file_manager, const secure_storage::Secret &secret, + const vector &encrypted_secure_values) { + vector result; + result.reserve(encrypted_secure_values.size()); + for (auto &encrypted_secure_value : encrypted_secure_values) { + TRY_RESULT(secure_value_with_credentials, + decrypt_encrypted_secure_value(file_manager, secret, encrypted_secure_value)); + result.push_back(std::move(secure_value_with_credentials)); + } + return std::move(result); +} + EncryptedSecureFile encrypt_secure_file(FileManager *file_manager, const secure_storage::Secret &master_secret, FileId file, string &to_hash) { auto file_view = file_manager->get_file_view(file); @@ -560,7 +583,7 @@ EncryptedSecureValue encrypt_secure_value(FileManager *file_manager, const secur template class AsJsonable : public Jsonable { public: - AsJsonable(const T &value) : value_(value) { + explicit AsJsonable(const T &value) : value_(value) { } void store(JsonValueScope *scope) const { *scope + value_; @@ -630,9 +653,9 @@ Slice secure_value_type_as_slice(SecureValueType type) { case SecureValueType::RentalAgreement: return "rental_agreement"; case SecureValueType::PhoneNumber: - return "phone_number"; + return "phone"; case SecureValueType::EmailAddress: - return "email_address"; + return "email"; default: case SecureValueType::None: UNREACHABLE(); @@ -649,10 +672,10 @@ JsonScope &operator+(JsonValueScope &scope, const std::vector &, const Slice &> &credentials) { + const std::tuple &, const Slice &> &credentials) { auto object = scope.enter_object(); - object << ctie("secure_data", as_jsonable(credentials.first)); - object << ctie("payload", credentials.second); + object << ctie("secure_data", as_jsonable(std::get<0>(credentials))); + object << ctie("payload", std::get<1>(credentials)); return scope; } @@ -665,7 +688,7 @@ Result encrypted_credentials(std::vector &&secure_file_ptr); +EncryptedSecureFile get_encrypted_secure_file(FileManager *file_manager, + tl_object_ptr &&secure_file_ptr); -vector get_secure_files(FileManager *file_manager, - vector> &&secure_files); +vector get_encrypted_secure_files(FileManager *file_manager, + vector> &&secure_files); struct SecureInputFile { FileId file_id; @@ -89,7 +88,7 @@ struct EncryptedSecureData { bool operator==(const EncryptedSecureData &lhs, const EncryptedSecureData &rhs); bool operator!=(const EncryptedSecureData &lhs, const EncryptedSecureData &rhs); -EncryptedSecureData get_secure_data(tl_object_ptr &&secure_data); +EncryptedSecureData get_encrypted_secure_data(tl_object_ptr &&secure_data); telegram_api::object_ptr get_secure_data_object(const EncryptedSecureData &data); @@ -128,7 +127,7 @@ struct EncryptedSecureCredentials { bool operator==(const EncryptedSecureCredentials &lhs, const EncryptedSecureCredentials &rhs); bool operator!=(const EncryptedSecureCredentials &lhs, const EncryptedSecureCredentials &rhs); -EncryptedSecureCredentials get_secure_credentials( +EncryptedSecureCredentials get_encrypted_secure_credentials( tl_object_ptr &&credentials); telegram_api::object_ptr get_secure_credentials_encrypted_object( @@ -174,6 +173,9 @@ Result get_secure_value(FileManager *file_manager, td_api::object_ptr get_passport_data_object(FileManager *file_manager, const SecureValue &value); +td_api::object_ptr get_all_passport_data_object(FileManager *file_manager, + const vector &value); + Result> decrypt_secure_file(FileManager *file_manager, const secure_storage::Secret &secret, const EncryptedSecureFile &secure_file); @@ -184,6 +186,9 @@ Result> decrypt_secure_data(const secur Result decrypt_encrypted_secure_value(FileManager *file_manager, const secure_storage::Secret &secret, const EncryptedSecureValue &encrypted_secure_value); +Result> decrypt_encrypted_secure_values( + FileManager *file_manager, const secure_storage::Secret &secret, + const vector &encrypted_secure_values); EncryptedSecureFile encrypt_secure_file(FileManager *file_manager, const secure_storage::Secret &master_secret, FileId file, string &to_hash); diff --git a/td/telegram/Td.cpp b/td/telegram/Td.cpp index 2534d00b..56657453 100644 --- a/td/telegram/Td.cpp +++ b/td/telegram/Td.cpp @@ -6829,14 +6829,23 @@ void Td::on_request(uint64 id, td_api::getPassportData &request) { CHECK_AUTH(); CHECK_IS_USER(); CLEAN_INPUT_STRING(request.password_); - CREATE_REQUEST_PROMISE(promise); if (request.type_ == nullptr) { - return promise.set_error(Status::Error(400, "Type must not be empty")); + return send_error_raw(id, 400, "Type must not be empty"); } + CREATE_REQUEST_PROMISE(promise); send_closure(secure_manager_, &SecureManager::get_secure_value, std::move(request.password_), get_secure_value_type_td_api(std::move(request.type_)), std::move(promise)); } +void Td::on_request(uint64 id, td_api::getAllPassportData &request) { + CHECK_AUTH(); + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.password_); + CREATE_REQUEST_PROMISE(promise); + send_closure(secure_manager_, &SecureManager::get_all_secure_values, std::move(request.password_), + std::move(promise)); +} + void Td::on_request(uint64 id, td_api::setPassportData &request) { CHECK_AUTH(); CHECK_IS_USER(); @@ -6903,8 +6912,12 @@ void Td::on_request(uint64 id, td_api::getPassportAuthorizationForm &request) { CLEAN_INPUT_STRING(request.public_key_); CLEAN_INPUT_STRING(request.scope_); CLEAN_INPUT_STRING(request.payload_); + UserId bot_user_id(request.bot_user_id_); + if (!bot_user_id.is_valid()) { + return send_error_raw(id, 400, "Bot user identifier invalid"); + } CREATE_REQUEST_PROMISE(promise); - send_closure(secure_manager_, &SecureManager::get_passport_authorization_form, request.password_, request.bot_id_, + send_closure(secure_manager_, &SecureManager::get_passport_authorization_form, request.password_, bot_user_id, request.scope_, request.public_key_, request.payload_, std::move(promise)); } diff --git a/td/telegram/Td.h b/td/telegram/Td.h index 1f7c1fad..a0f80707 100644 --- a/td/telegram/Td.h +++ b/td/telegram/Td.h @@ -751,6 +751,8 @@ class Td final : public NetQueryCallback { void on_request(uint64 id, td_api::getPassportData &request); + void on_request(uint64 id, td_api::getAllPassportData &request); + void on_request(uint64 id, td_api::setPassportData &request); void on_request(uint64 id, const td_api::deletePassportData &request); diff --git a/td/telegram/cli.cpp b/td/telegram/cli.cpp index 2b1f678f..abfe0ed6 100644 --- a/td/telegram/cli.cpp +++ b/td/telegram/cli.cpp @@ -1078,7 +1078,7 @@ class CliClient final : public Actor { recovery_email_address = ""; } send_request(make_tl_object(password, new_password, new_hint, true, recovery_email_address)); - } else if (op == "secureid") { + } else if (op == "gpaf" || op == "secureid") { string password; std::tie(password, args) = split(args); ChainBufferWriter writer; @@ -1127,6 +1127,9 @@ class CliClient final : public Actor { string passport_data_type; std::tie(password, passport_data_type) = split(args); send_request(make_tl_object(as_passport_data_type(passport_data_type), password)); + } else if (op == "gapd") { + string password = args; + send_request(make_tl_object(password)); } else if (op == "spd") { string password; string passport_data_type;