diff --git a/td/telegram/PasswordManager.cpp b/td/telegram/PasswordManager.cpp index b3a083366..234b477be 100644 --- a/td/telegram/PasswordManager.cpp +++ b/td/telegram/PasswordManager.cpp @@ -156,10 +156,7 @@ void PasswordManager::do_create_temp_password(string password, int32 timeout, Pa send_with_promise(G()->net_query_creator().create(create_storer(telegram_api::account_getTmpPassword( calc_password_hash(password, password_state.current_salt), timeout))), PromiseCreator::lambda([promise = std::move(promise)](Result r_query) mutable { - if (r_query.is_error()) { - return promise.set_error(r_query.move_as_error()); - } - auto r_result = fetch_result(r_query.move_as_ok()); + auto r_result = fetch_result(std::move(r_query)); if (r_result.is_error()) { return promise.set_error(r_result.move_as_error()); } @@ -202,15 +199,14 @@ void PasswordManager::do_get_full_state(string password, PasswordState state, Pr PromiseCreator::lambda([promise = std::move(promise), state = std::move(state), password](Result r_query) mutable { promise.set_result([&]() -> Result { - TRY_RESULT(query, std::move(r_query)); - TRY_RESULT(result, fetch_result(std::move(query))); + TRY_RESULT(result, fetch_result(std::move(r_query))); PasswordPrivateState private_state; private_state.email = result->email_; auto r_secret = [&]() -> Result { TRY_RESULT(encrypted_secret, secure_storage::EncryptedSecret::create(result->secure_secret_.as_slice())); auto r_secret = encrypted_secret.decrypt(PSLICE() << result->secure_salt_.as_slice() << password - << result->secure_salt_.as_slice()); + << result->secure_salt_.as_slice()); if (r_secret.is_ok() && result->secure_secret_id_ != r_secret.ok().get_hash()) { return Status::Error("Secret hash mismatch"); } @@ -236,15 +232,54 @@ void PasswordManager::get_recovery_email_address(string password, })); } +void PasswordManager::send_email_address_verification_code( + string email, Promise> promise) { + last_verified_email_address_ = email; + auto query = + G()->net_query_creator().create(create_storer(telegram_api::account_sendVerifyEmailCode(std::move(email)))); + send_with_promise( + std::move(query), PromiseCreator::lambda([actor_id = actor_id(this), + promise = std::move(promise)](Result r_query) mutable { + auto r_result = fetch_result(std::move(r_query)); + if (r_result.is_error()) { + return promise.set_error(r_result.move_as_error()); + } + auto result = r_result.move_as_ok(); + return promise.set_value(make_tl_object(result->email_pattern_)); + })); +} + +void PasswordManager::resend_email_address_verification_code( + Promise> promise) { + if (last_verified_email_address_.empty()) { + return promise.set_error(Status::Error(400, "No verification phone was sent")); + } + send_email_address_verification_code(last_verified_email_address_, std::move(promise)); +} + +void PasswordManager::check_email_address_verification_code(string code, + Promise> promise) { + if (last_verified_email_address_.empty()) { + return promise.set_error(Status::Error(400, "No verification phone was sent")); + } + auto query = G()->net_query_creator().create( + create_storer(telegram_api::account_verifyEmail(last_verified_email_address_, std::move(code)))); + send_with_promise(std::move(query), PromiseCreator::lambda([actor_id = actor_id(this), promise = std::move(promise)]( + Result r_query) mutable { + auto r_result = fetch_result(std::move(r_query)); + if (r_result.is_error()) { + return promise.set_error(r_result.move_as_error()); + } + return promise.set_value(td_api::make_object()); + })); +} + void PasswordManager::request_password_recovery( Promise> promise) { send_with_promise( G()->net_query_creator().create(create_storer(telegram_api::auth_requestPasswordRecovery())), PromiseCreator::lambda([promise = std::move(promise)](Result r_query) mutable { - if (r_query.is_error()) { - return promise.set_error(r_query.move_as_error()); - } - auto r_result = fetch_result(r_query.move_as_ok()); + auto r_result = fetch_result(std::move(r_query)); if (r_result.is_error()) { return promise.set_error(r_result.move_as_error()); } @@ -257,10 +292,7 @@ void PasswordManager::recover_password(string code, Promise promise) { send_with_promise(G()->net_query_creator().create(create_storer(telegram_api::auth_recoverPassword(std::move(code)))), PromiseCreator::lambda( [actor_id = actor_id(this), promise = std::move(promise)](Result r_query) mutable { - if (r_query.is_error()) { - return promise.set_error(r_query.move_as_error()); - } - auto r_result = fetch_result(r_query.move_as_ok()); + auto r_result = fetch_result(std::move(r_query)); if (r_result.is_error()) { return promise.set_error(r_result.move_as_error()); } @@ -364,10 +396,7 @@ void PasswordManager::do_update_password_settings(UpdateSettings update_settings send_with_promise(std::move(query), PromiseCreator::lambda([actor_id = actor_id(this), promise = std::move(promise)]( Result r_query) mutable { - if (r_query.is_error()) { - return promise.set_error(r_query.move_as_error()); - } - auto r_result = fetch_result(r_query.move_as_ok()); + auto r_result = fetch_result(std::move(r_query)); if (r_result.is_error()) { if (r_result.error().code() == 400 && r_result.error().message() == "EMAIL_UNCONFIRMED") { return promise.set_value(true); @@ -392,10 +421,7 @@ void PasswordManager::do_get_state(Promise promise) { auto query = G()->net_query_creator().create(create_storer(telegram_api::account_getPassword())); send_with_promise(std::move(query), PromiseCreator::lambda([actor_id = actor_id(this), promise = std::move(promise)]( Result r_query) mutable { - if (r_query.is_error()) { - return promise.set_error(r_query.move_as_error()); - } - auto r_result = fetch_result(r_query.move_as_ok()); + auto r_result = fetch_result(std::move(r_query)); if (r_result.is_error()) { return promise.set_error(r_result.move_as_error()); } diff --git a/td/telegram/PasswordManager.h b/td/telegram/PasswordManager.h index 9389bf4d6..4299ffed2 100644 --- a/td/telegram/PasswordManager.h +++ b/td/telegram/PasswordManager.h @@ -56,6 +56,13 @@ class PasswordManager : public NetQueryCallback { void set_recovery_email_address(string password, string new_recovery_email_address, Promise promise); void get_recovery_email_address(string password, Promise> promise); + string last_verified_email_address_; + void send_email_address_verification_code( + string email, Promise> promise); + void resend_email_address_verification_code( + Promise> promise); + void check_email_address_verification_code(string code, Promise> promise); + void request_password_recovery(Promise> promise); void recover_password(string code, Promise promise); diff --git a/td/telegram/SecureManager.cpp b/td/telegram/SecureManager.cpp index 87c4ea980..27c648c7c 100644 --- a/td/telegram/SecureManager.cpp +++ b/td/telegram/SecureManager.cpp @@ -552,10 +552,7 @@ void SecureManager::do_send_passport_authorization_form(int32 authorization_form auto query = G()->net_query_creator().create(create_storer(td_query)); auto new_promise = PromiseCreator::lambda([promise = std::move(promise)](Result r_net_query_ptr) mutable { - if (r_net_query_ptr.is_error()) { - return promise.set_error(r_net_query_ptr.move_as_error()); - } - auto r_result = fetch_result(r_net_query_ptr.move_as_ok()); + auto r_result = fetch_result(std::move(r_net_query_ptr)); if (r_result.is_error()) { return promise.set_error(r_result.move_as_error()); } diff --git a/td/telegram/Td.cpp b/td/telegram/Td.cpp index 6c3535891..521d14c2e 100644 --- a/td/telegram/Td.cpp +++ b/td/telegram/Td.cpp @@ -6891,20 +6891,25 @@ void Td::on_request(uint64 id, td_api::sendEmailAddressVerificationCode &request CHECK_AUTH(); CHECK_IS_USER(); CLEAN_INPUT_STRING(request.email_address_); - LOG(FATAL) << "TODO"; + CREATE_REQUEST_PROMISE(promise); + send_closure(password_manager_, &PasswordManager::send_email_address_verification_code, request.email_address_, + std::move(promise)); } void Td::on_request(uint64 id, const td_api::resendEmailAddressVerificationCode &request) { CHECK_AUTH(); CHECK_IS_USER(); - LOG(FATAL) << "TODO"; + CREATE_REQUEST_PROMISE(promise); + send_closure(password_manager_, &PasswordManager::resend_email_address_verification_code, std::move(promise)); } void Td::on_request(uint64 id, td_api::checkEmailAddressVerificationCode &request) { CHECK_AUTH(); CHECK_IS_USER(); CLEAN_INPUT_STRING(request.code_); - LOG(FATAL) << "TODO"; + CREATE_REQUEST_PROMISE(promise); + send_closure(password_manager_, &PasswordManager::check_email_address_verification_code, request.code_, + std::move(promise)); } void Td::on_request(uint64 id, td_api::getPassportAuthorizationForm &request) { diff --git a/td/telegram/cli.cpp b/td/telegram/cli.cpp index c88512218..48e5c03e8 100644 --- a/td/telegram/cli.cpp +++ b/td/telegram/cli.cpp @@ -1114,8 +1114,14 @@ class CliClient final : public Actor { send_request(make_tl_object(args, false, false)); } else if (op == "cpnvc" || op == "CheckPhoneNumberVerificationCode") { send_request(make_tl_object(args)); - } else if (op == "rpnvc" || op == "ResendPhoneNumverVerificationCode") { + } else if (op == "rpnvc" || op == "ResendPhoneNumberVerificationCode") { send_request(make_tl_object()); + } else if (op == "seavc" || op == "SendEmailAddressVerificationCode") { + send_request(make_tl_object(args)); + } else if (op == "ceavc" || op == "CheckEmailAddressVerificationCode") { + send_request(make_tl_object(args)); + } else if (op == "reavc" || op == "ResendEmailAddressVerificationCode") { + send_request(make_tl_object()); } else if (op == "srea" || op == "SetRecoveryEmailAddress") { string password; string recovery_email_address; diff --git a/td/telegram/net/NetQuery.h b/td/telegram/net/NetQuery.h index ccf1034a6..da1bdaed4 100644 --- a/td/telegram/net/NetQuery.h +++ b/td/telegram/net/NetQuery.h @@ -392,6 +392,12 @@ Result fetch_result(NetQueryPtr query) { return fetch_result(buffer); } +template +Result fetch_result(Result r_query) { + TRY_RESULT(query, std::move(r_query)); + return fetch_result(std::move(query)); +} + inline void NetQueryCallback::on_result(NetQueryPtr query) { on_result_resendable(std::move(query), Auto()); }