diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index 53f34bbd8..204235846 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -92,10 +92,14 @@ authorizationStateWaitEncryptionKey is_encrypted:Bool = AuthorizationState; //@description TDLib needs the user's phone number to authorize. Call `setAuthenticationPhoneNumber` to provide the phone number, or use `requestQrCodeAuthentication`, or `checkAuthenticationBotToken` for other authentication options authorizationStateWaitPhoneNumber = AuthorizationState; -//@description TDLib needs the user's email address to authorize. Call `setAuthenticationEmailAddress` to provide the email address, or directly call `setAuthenticationEmailCode` with Apple ID/Google ID token if allowed +//@description TDLib needs the user's email address to authorize. Call `setAuthenticationEmailAddress` to provide the email address, or directly call `checkAuthenticationEmailCode` with Apple ID/Google ID token if allowed //@allow_apple_id True, if authorization through Apple ID is allowed @allow_google_id True, if authorization through Google ID is allowed authorizationStateWaitEmailAddress allow_apple_id:Bool allow_google_id:Bool = AuthorizationState; +//@description TDLib needs the user's authentication code sent to an email address to authorize. Call `checkAuthenticationEmailCode` to provide the code +//@allow_apple_id True, if authorization through Apple ID is allowed @allow_google_id True, if authorization through Google ID is allowed @code_info Information about the sent authentication code +authorizationStateWaitEmailCode allow_apple_id:Bool allow_google_id:Bool code_info:emailAddressAuthenticationCodeInfo = AuthorizationState; + //@description TDLib needs the user's authentication code to authorize @code_info Information about the authorization code that was sent authorizationStateWaitCode code_info:authenticationCodeInfo = AuthorizationState; diff --git a/td/telegram/AuthManager.cpp b/td/telegram/AuthManager.cpp index 46ce73db5..90f4eb8d9 100644 --- a/td/telegram/AuthManager.cpp +++ b/td/telegram/AuthManager.cpp @@ -109,6 +109,9 @@ tl_object_ptr AuthManager::get_authorization_state_o return make_tl_object(); case State::WaitEmailAddress: return make_tl_object(allow_apple_id_, allow_google_id_); + case State::WaitEmailCode: + return make_tl_object( + allow_apple_id_, allow_google_id_, email_code_.get_email_address_authentication_code_info_object()); case State::WaitCode: return send_code_helper_.get_authorization_state_wait_code(); case State::WaitQrCodeConfirmation: @@ -176,8 +179,8 @@ void AuthManager::check_bot_token(uint64 query_id, string bot_token) { void AuthManager::request_qr_code_authentication(uint64 query_id, vector other_user_ids) { if (state_ != State::WaitPhoneNumber) { - if ((state_ == State::WaitEmailAddress || state_ == State::WaitCode || state_ == State::WaitPassword || - state_ == State::WaitRegistration) && + if ((state_ == State::WaitEmailAddress || state_ == State::WaitEmailCode || state_ == State::WaitCode || + state_ == State::WaitPassword || state_ == State::WaitRegistration) && net_query_id_ == 0) { // ok } else { @@ -242,8 +245,8 @@ void AuthManager::on_update_login_token() { void AuthManager::set_phone_number(uint64 query_id, string phone_number, td_api::object_ptr settings) { if (state_ != State::WaitPhoneNumber) { - if ((state_ == State::WaitEmailAddress || state_ == State::WaitCode || state_ == State::WaitPassword || - state_ == State::WaitRegistration) && + if ((state_ == State::WaitEmailAddress || state_ == State::WaitEmailCode || state_ == State::WaitCode || + state_ == State::WaitPassword || state_ == State::WaitRegistration) && net_query_id_ == 0) { // ok } else { @@ -261,6 +264,11 @@ void AuthManager::set_phone_number(uint64 query_id, string phone_number, other_user_ids_.clear(); was_qr_code_request_ = false; + allow_apple_id_ = false; + allow_google_id_ = false; + email_address_ = {}; + email_code_ = {}; + if (send_code_helper_.phone_number() != phone_number) { send_code_helper_ = SendCodeHelper(); terms_of_service_ = TermsOfService(); @@ -274,7 +282,11 @@ void AuthManager::set_phone_number(uint64 query_id, string phone_number, void AuthManager::set_email_address(uint64 query_id, string email_address) { if (state_ != State::WaitEmailAddress) { - return on_query_error(query_id, Status::Error(400, "Call to setAuthenticationEmailAddress unexpected")); + if (state_ == State::WaitEmailCode && net_query_id_ == 0) { + // ok + } else { + return on_query_error(query_id, Status::Error(400, "Call to setAuthenticationEmailAddress unexpected")); + } } if (email_address.empty()) { return on_query_error(query_id, Status::Error(400, "Email address must be non-empty")); @@ -532,6 +544,12 @@ void AuthManager::on_send_email_code_result(NetQueryPtr &result) { LOG(INFO) << "Receive " << to_string(sent_code); + email_code_ = SentEmailCode(std::move(sent_code)); + if (email_code_.is_empty()) { + return on_query_error(Status::Error(500, "Receive invalid response")); + } + + update_state(State::WaitEmailCode, true); on_query_ok(); } @@ -1035,6 +1053,7 @@ bool AuthManager::load_state() { case State::WaitRegistration: return 86400; case State::WaitEmailAddress: + case State::WaitEmailCode: case State::WaitCode: case State::WaitQrCodeConfirmation: return 5 * 60; @@ -1054,6 +1073,12 @@ bool AuthManager::load_state() { allow_apple_id_ = db_state.allow_apple_id_; allow_google_id_ = db_state.allow_google_id_; send_code_helper_ = std::move(db_state.send_code_helper_); + } else if (db_state.state_ == State::WaitEmailCode) { + allow_apple_id_ = db_state.allow_apple_id_; + allow_google_id_ = db_state.allow_google_id_; + email_address_ = std::move(db_state.email_address_); + email_code_ = std::move(db_state.email_code_); + send_code_helper_ = std::move(db_state.send_code_helper_); } else if (db_state.state_ == State::WaitCode) { send_code_helper_ = std::move(db_state.send_code_helper_); } else if (db_state.state_ == State::WaitQrCodeConfirmation) { @@ -1073,8 +1098,8 @@ bool AuthManager::load_state() { } void AuthManager::save_state() { - if (state_ != State::WaitEmailAddress && state_ != State::WaitCode && state_ != State::WaitQrCodeConfirmation && - state_ != State::WaitPassword && state_ != State::WaitRegistration) { + if (state_ != State::WaitEmailAddress && state_ != State::WaitEmailCode && state_ != State::WaitCode && + state_ != State::WaitQrCodeConfirmation && state_ != State::WaitPassword && state_ != State::WaitRegistration) { if (state_ != State::Closing) { G()->td_db()->get_binlog_pmc()->erase("auth_state"); } @@ -1084,6 +1109,9 @@ void AuthManager::save_state() { DbState db_state = [&] { if (state_ == State::WaitEmailAddress) { return DbState::wait_email_address(api_id_, api_hash_, allow_apple_id_, allow_google_id_, send_code_helper_); + } else if (state_ == State::WaitEmailCode) { + return DbState::wait_email_code(api_id_, api_hash_, allow_apple_id_, allow_google_id_, email_address_, + email_code_, send_code_helper_); } else if (state_ == State::WaitCode) { return DbState::wait_code(api_id_, api_hash_, send_code_helper_); } else if (state_ == State::WaitQrCodeConfirmation) { diff --git a/td/telegram/AuthManager.h b/td/telegram/AuthManager.h index 06b43c691..b9da53708 100644 --- a/td/telegram/AuthManager.h +++ b/td/telegram/AuthManager.h @@ -9,6 +9,7 @@ #include "td/telegram/net/NetActor.h" #include "td/telegram/net/NetQuery.h" #include "td/telegram/SendCodeHelper.h" +#include "td/telegram/SentEmailCode.h" #include "td/telegram/td_api.h" #include "td/telegram/telegram_api.h" #include "td/telegram/TermsOfService.h" @@ -67,6 +68,7 @@ class AuthManager final : public NetActor { WaitPassword, WaitRegistration, WaitEmailAddress, + WaitEmailCode, Ok, LoggingOut, DestroyingKeys, @@ -114,11 +116,15 @@ class AuthManager final : public NetActor { string api_hash_; Timestamp state_timestamp_; - // WaitEmailAddress + // WaitEmailAddress and WaitEmailCode bool allow_apple_id_ = false; bool allow_google_id_ = false; - // WaitEmailAddress and WaitCode + // WaitEmailCode + string email_address_; + SentEmailCode email_code_; + + // WaitEmailAddress, WaitEmailCode, WaitCode and WaitRegistration SendCodeHelper send_code_helper_; // WaitQrCodeConfirmation @@ -143,6 +149,17 @@ class AuthManager final : public NetActor { return state; } + static DbState wait_email_code(int32 api_id, string api_hash, bool allow_apple_id, bool allow_google_id, + string email_address, SentEmailCode email_code, SendCodeHelper send_code_helper) { + DbState state(State::WaitEmailCode, api_id, std::move(api_hash)); + state.send_code_helper_ = std::move(send_code_helper); + state.allow_apple_id_ = allow_apple_id; + state.allow_google_id_ = allow_google_id; + state.email_address_ = std::move(email_address); + state.email_code_ = std::move(email_code); + return state; + } + static DbState wait_code(int32 api_id, string api_hash, SendCodeHelper send_code_helper) { DbState state(State::WaitCode, api_id, std::move(api_hash)); state.send_code_helper_ = std::move(send_code_helper); @@ -196,7 +213,10 @@ class AuthManager final : public NetActor { // State::WaitEmailAddress bool allow_apple_id_ = false; bool allow_google_id_ = false; + + // State::WaitEmailCode string email_address_; + SentEmailCode email_code_; // State::WaitCode SendCodeHelper send_code_helper_; diff --git a/td/telegram/AuthManager.hpp b/td/telegram/AuthManager.hpp index 2548e9cfa..1ec3c79d7 100644 --- a/td/telegram/AuthManager.hpp +++ b/td/telegram/AuthManager.hpp @@ -76,6 +76,10 @@ void AuthManager::DbState::store(StorerT &storer) const { if (state_ == State::WaitEmailAddress) { store(send_code_helper_, storer); + } else if (state_ == State::WaitEmailCode) { + store(send_code_helper_, storer); + store(email_address_, storer); + store(email_code_, storer); } else if (state_ == State::WaitCode) { store(send_code_helper_, storer); } else if (state_ == State::WaitQrCodeConfirmation) { @@ -131,6 +135,10 @@ void AuthManager::DbState::parse(ParserT &parser) { if (state_ == State::WaitEmailAddress) { parse(send_code_helper_, parser); + } else if (state_ == State::WaitEmailCode) { + parse(send_code_helper_, parser); + parse(email_address_, parser); + parse(email_code_, parser); } else if (state_ == State::WaitCode) { parse(send_code_helper_, parser); } else if (state_ == State::WaitQrCodeConfirmation) {