diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index 25fb3381c..241a3e548 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -2353,7 +2353,8 @@ call id:int32 user_id:int53 is_outgoing:Bool is_video:Bool state:CallState = Cal //@allow_missed_call Pass true if the authentication code may be sent via a missed call to the specified phone number //@is_current_phone_number Pass true if the authenticated phone number is used on the current device //@allow_sms_retriever_api For official applications only. True, if the application can use Android SMS Retriever API (requires Google Play Services >= 10.2) to automatically receive the authentication code from the SMS. See https://developers.google.com/identity/sms-retriever/ for more details -phoneNumberAuthenticationSettings allow_flash_call:Bool allow_missed_call:Bool is_current_phone_number:Bool allow_sms_retriever_api:Bool = PhoneNumberAuthenticationSettings; +//@authentication_tokens List of authentication tokens, received in updateOption("authentication_token") in previously logged out sessions +phoneNumberAuthenticationSettings allow_flash_call:Bool allow_missed_call:Bool is_current_phone_number:Bool allow_sms_retriever_api:Bool authentication_tokens:vector = PhoneNumberAuthenticationSettings; //@description Represents a list of animations @animations List of animations diff --git a/td/telegram/AuthManager.cpp b/td/telegram/AuthManager.cpp index 74ecc9d95..3d211e621 100644 --- a/td/telegram/AuthManager.cpp +++ b/td/telegram/AuthManager.cpp @@ -672,7 +672,11 @@ void AuthManager::on_log_out_result(NetQueryPtr &result) { if (result->is_ok()) { auto r_log_out = fetch_result(result->ok()); if (r_log_out.is_ok()) { - // auto logged_out = r_log_out.move_as_ok(); + auto logged_out = r_log_out.move_as_ok(); + if (!logged_out->future_auth_token_.empty()) { + G()->shared_config().set_option_string("authentication_token", + base64url_encode(logged_out->future_auth_token_.as_slice())); + } } else { status = r_log_out.move_as_error(); } @@ -811,7 +815,8 @@ void AuthManager::on_result(NetQueryPtr result) { type = net_query_type_; net_query_type_ = NetQueryType::None; if (result->is_error()) { - if ((type == NetQueryType::SignIn || type == NetQueryType::RequestQrCode || type == NetQueryType::ImportQrCode) && + if ((type == NetQueryType::SendCode || type == NetQueryType::SignIn || type == NetQueryType::RequestQrCode || + type == NetQueryType::ImportQrCode) && result->error().code() == 401 && result->error().message() == CSlice("SESSION_PASSWORD_NEEDED")) { auto dc_id = DcId::main(); if (type == NetQueryType::ImportQrCode) { diff --git a/td/telegram/SendCodeHelper.cpp b/td/telegram/SendCodeHelper.cpp index cfd09b781..ec48a528a 100644 --- a/td/telegram/SendCodeHelper.cpp +++ b/td/telegram/SendCodeHelper.cpp @@ -6,6 +6,8 @@ // #include "td/telegram/SendCodeHelper.h" +#include "td/utils/base64.h" + namespace td { void SendCodeHelper::on_sent_code(telegram_api::object_ptr sent_code) { @@ -38,6 +40,7 @@ Result SendCodeHelper::resend_code() { telegram_api::object_ptr SendCodeHelper::get_input_code_settings(const Settings &settings) { int32 flags = 0; + vector logout_tokens; if (settings != nullptr) { if (settings->allow_flash_call_) { flags |= telegram_api::codeSettings::ALLOW_FLASHCALL_MASK; @@ -51,9 +54,22 @@ telegram_api::object_ptr SendCodeHelper::get_input_c if (settings->allow_sms_retriever_api_) { flags |= telegram_api::codeSettings::ALLOW_APP_HASH_MASK; } + constexpr size_t MAX_LOGOUT_TOKENS = 20; // server-side limit + for (const auto &token : settings->authentication_tokens_) { + auto r_logout_token = base64url_decode(token); + if (r_logout_token.is_ok()) { + logout_tokens.push_back(BufferSlice(r_logout_token.ok())); + if (logout_tokens.size() >= MAX_LOGOUT_TOKENS) { + break; + } + } + } + if (!logout_tokens.empty()) { + flags |= telegram_api::codeSettings::LOGOUT_TOKENS_MASK; + } } return telegram_api::make_object( - flags, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, vector()); + flags, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, std::move(logout_tokens)); } telegram_api::auth_sendCode SendCodeHelper::send_code(string phone_number, const Settings &settings, int32 api_id, diff --git a/td/telegram/cli.cpp b/td/telegram/cli.cpp index 0fc17e24c..cbb8568da 100644 --- a/td/telegram/cli.cpp +++ b/td/telegram/cli.cpp @@ -241,6 +241,8 @@ class CliClient final : public Actor { std::unordered_map users_; std::unordered_map username_to_user_id_; + vector authentication_tokens_; + void register_user(const td_api::user &user) { User &new_user = users_[user.id_]; new_user.first_name = user.first_name_; @@ -280,6 +282,10 @@ class CliClient final : public Actor { my_id_ = static_cast(option.value_.get())->value_; LOG(INFO) << "Set my user identifier to " << my_id_; } + if (option.name_ == "authentication_token" && option.value_->get_id() == td_api::optionValueString::ID) { + authentication_tokens_.insert(authentication_tokens_.begin(), + static_cast(option.value_.get())->value_); + } } int64 get_history_chat_id_ = 0; @@ -1576,6 +1582,11 @@ class CliClient final : public Actor { return td_api::make_object(get_background_fill(std::move(colors))); } + td_api::object_ptr get_phone_number_authentication_settings() const { + return td_api::make_object(false, true, false, false, + vector(authentication_tokens_)); + } + static td_api::object_ptr execute(td_api::object_ptr f) { if (combined_log.get_first_verbosity_level() < get_log_tag_verbosity_level("td_requests")) { LOG(ERROR) << "Execute request: " << to_string(f); @@ -1641,8 +1652,9 @@ class CliClient final : public Actor { if (op == "gas") { send_request(td_api::make_object()); - } else if (op == "sap") { - send_request(td_api::make_object(args, nullptr)); + } else if (op == "sap" || op == "sapn") { + send_request( + td_api::make_object(args, get_phone_number_authentication_settings())); } else if (op == "rac") { send_request(td_api::make_object()); } else if (op == "cdek" || op == "CheckDatabaseEncryptionKey") {