diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index 56d927ebc..e76e691a5 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -3870,8 +3870,9 @@ checkAuthenticationPassword password:string = Ok; //@description Requests to send a password recovery code to an email address that was previously set up. Works only when the current authorization state is authorizationStateWaitPassword requestAuthenticationPasswordRecovery = Ok; -//@description Recovers the password with a password recovery code sent to an email address that was previously set up. Works only when the current authorization state is authorizationStateWaitPassword @recovery_code Recovery code to check -recoverAuthenticationPassword recovery_code:string = Ok; +//@description Recovers the password with a password recovery code sent to an email address that was previously set up. Works only when the current authorization state is authorizationStateWaitPassword +//@recovery_code Recovery code to check @new_password New password of the user; may be empty to remove the password @new_hint New password hint; may be empty +recoverAuthenticationPassword recovery_code:string new_password:string new_hint:string = Ok; //@description Checks the authentication token of a bot; to log in as a bot. Works only when the current authorization state is authorizationStateWaitPhoneNumber. Can be used instead of setAuthenticationPhoneNumber and checkAuthenticationCode to log in @token The bot token checkAuthenticationBotToken token:string = Ok; @@ -3921,8 +3922,9 @@ resendRecoveryEmailAddressCode = PasswordState; //@description Requests to send a password recovery code to an email address that was previously set up requestPasswordRecovery = EmailAddressAuthenticationCodeInfo; -//@description Recovers the password using a recovery code sent to an email address that was previously set up @recovery_code Recovery code to check -recoverPassword recovery_code:string = PasswordState; +//@description Recovers the password using a recovery code sent to an email address that was previously set up +//@recovery_code Recovery code to check @new_password New password of the user; may be empty to remove the password @new_hint New password hint; may be empty +recoverPassword recovery_code:string new_password:string new_hint:string = PasswordState; //@description Creates a new temporary password for processing payments @password Persistent user password @valid_for Time during which the temporary password will be valid, in seconds; should be between 60 and 86400 createTemporaryPassword password:string valid_for:int32 = TemporaryPasswordState; diff --git a/td/telegram/AuthManager.cpp b/td/telegram/AuthManager.cpp index c8a51c311..c28b1f88c 100644 --- a/td/telegram/AuthManager.cpp +++ b/td/telegram/AuthManager.cpp @@ -325,7 +325,7 @@ void AuthManager::request_password_recovery(uint64 query_id) { G()->net_query_creator().create_unauth(telegram_api::auth_requestPasswordRecovery())); } -void AuthManager::recover_password(uint64 query_id, string code) { +void AuthManager::recover_password(uint64 query_id, string code, string new_password, string new_hint) { if (state_ != State::WaitPassword) { return on_query_error(query_id, Status::Error(8, "Call to recoverAuthenticationPassword unexpected")); } diff --git a/td/telegram/AuthManager.h b/td/telegram/AuthManager.h index 5336a1c03..5277d0eac 100644 --- a/td/telegram/AuthManager.h +++ b/td/telegram/AuthManager.h @@ -42,7 +42,7 @@ class AuthManager : public NetActor { void check_bot_token(uint64 query_id, string bot_token); void check_password(uint64 query_id, string password); void request_password_recovery(uint64 query_id); - void recover_password(uint64 query_id, string code); + void recover_password(uint64 query_id, string code, string new_password, string new_hint); void log_out(uint64 query_id); void delete_account(uint64 query_id, const string &reason); diff --git a/td/telegram/PasswordManager.cpp b/td/telegram/PasswordManager.cpp index 691b5d9a4..bba20c868 100644 --- a/td/telegram/PasswordManager.cpp +++ b/td/telegram/PasswordManager.cpp @@ -478,9 +478,38 @@ void PasswordManager::request_password_recovery( })); } -void PasswordManager::recover_password(string code, Promise promise) { +void PasswordManager::recover_password(string code, string new_password, string new_hint, Promise promise) { // is called only after authorization - send_with_promise(G()->net_query_creator().create(telegram_api::auth_recoverPassword(0, std::move(code), nullptr)), + if (new_password.empty()) { + return do_recover_password(std::move(code), nullptr, std::move(promise)); + } + + UpdateSettings update_settings; + update_settings.update_password = true; + update_settings.new_password = std::move(new_password); + update_settings.new_hint = std::move(new_hint); + + do_get_state(PromiseCreator::lambda([actor_id = actor_id(this), code = std::move(code), + update_settings = std::move(update_settings), + promise = std::move(promise)](Result r_state) mutable { + if (r_state.is_error()) { + return promise.set_error(r_state.move_as_error()); + } + + TRY_RESULT_PROMISE(promise, new_settings, get_password_input_settings(update_settings, r_state.ok(), nullptr)); + + send_closure(actor_id, &PasswordManager::do_recover_password, std::move(code), std::move(new_settings), + std::move(promise)); + })); +} + +void PasswordManager::do_recover_password(string code, PasswordInputSettings &&new_settings, Promise &&promise) { + int32 flags = 0; + if (new_settings != nullptr) { + flags |= telegram_api::auth_recoverPassword::NEW_SETTINGS_MASK; + } + send_with_promise(G()->net_query_creator().create( + telegram_api::auth_recoverPassword(flags, std::move(code), std::move(new_settings))), PromiseCreator::lambda( [actor_id = actor_id(this), promise = std::move(promise)](Result r_query) mutable { auto r_result = fetch_result(std::move(r_query)); @@ -538,7 +567,7 @@ void PasswordManager::do_update_password_settings(UpdateSettings update_settings })); } -Result> PasswordManager::get_password_input_settings( +Result PasswordManager::get_password_input_settings( const UpdateSettings &update_settings, const PasswordState &state, const PasswordPrivateState *private_state) { auto settings = make_tl_object(); bool have_secret = private_state != nullptr && private_state->secret; diff --git a/td/telegram/PasswordManager.h b/td/telegram/PasswordManager.h index 43758b4f9..40bfe10c9 100644 --- a/td/telegram/PasswordManager.h +++ b/td/telegram/PasswordManager.h @@ -52,6 +52,7 @@ class PasswordManager : public NetQueryCallback { public: using State = tl_object_ptr; using TempState = tl_object_ptr; + using PasswordInputSettings = tl_object_ptr; explicit PasswordManager(ActorShared<> parent) : parent_(std::move(parent)) { } @@ -75,7 +76,7 @@ class PasswordManager : public NetQueryCallback { void check_email_address_verification_code(string code, Promise promise); void request_password_recovery(Promise> promise); - void recover_password(string code, Promise promise); + void recover_password(string code, string new_password, string new_hint, Promise promise); void get_secure_secret(string password, Promise promise); void get_input_check_password_srp(string password, @@ -170,8 +171,11 @@ class PasswordManager : public NetQueryCallback { static tl_object_ptr get_input_check_password(Slice password, const PasswordState &state); - static Result> get_password_input_settings( - const UpdateSettings &update_settings, const PasswordState &state, const PasswordPrivateState *private_state); + static Result get_password_input_settings(const UpdateSettings &update_settings, + const PasswordState &state, + const PasswordPrivateState *private_state); + + void do_recover_password(string code, PasswordInputSettings &&new_settings, Promise &&promise); void update_password_settings(UpdateSettings update_settings, Promise promise); void do_update_password_settings(UpdateSettings update_settings, PasswordFullState full_state, Promise promise); diff --git a/td/telegram/Td.cpp b/td/telegram/Td.cpp index 216301ae4..840fd2777 100644 --- a/td/telegram/Td.cpp +++ b/td/telegram/Td.cpp @@ -4783,7 +4783,8 @@ void Td::on_request(uint64 id, const td_api::requestAuthenticationPasswordRecove void Td::on_request(uint64 id, td_api::recoverAuthenticationPassword &request) { CLEAN_INPUT_STRING(request.recovery_code_); - send_closure(auth_manager_actor_, &AuthManager::recover_password, id, std::move(request.recovery_code_)); + send_closure(auth_manager_actor_, &AuthManager::recover_password, id, std::move(request.recovery_code_), + std::move(request.new_password_), std::move(request.new_hint_)); } void Td::on_request(uint64 id, const td_api::logOut &request) { @@ -4926,7 +4927,7 @@ void Td::on_request(uint64 id, td_api::recoverPassword &request) { CLEAN_INPUT_STRING(request.recovery_code_); CREATE_REQUEST_PROMISE(); send_closure(password_manager_, &PasswordManager::recover_password, std::move(request.recovery_code_), - std::move(promise)); + std::move(request.new_password_), std::move(request.new_hint_), std::move(promise)); } void Td::on_request(uint64 id, td_api::getTemporaryPasswordState &request) { diff --git a/td/telegram/cli.cpp b/td/telegram/cli.cpp index d9b1fd3d5..379f3a236 100644 --- a/td/telegram/cli.cpp +++ b/td/telegram/cli.cpp @@ -1655,7 +1655,11 @@ class CliClient final : public Actor { } else if (op == "rapr") { send_request(td_api::make_object()); } else if (op == "rap") { - send_request(td_api::make_object(args)); + string code; + string new_password; + string new_hint; + get_args(args, code, new_password, new_hint); + send_request(td_api::make_object(code, new_password, new_hint)); } else if (op == "lo" || op == "LogOut" || op == "logout") { send_request(td_api::make_object()); } else if (op == "destroy") { @@ -1777,7 +1781,11 @@ class CliClient final : public Actor { } else if (op == "rpr" || op == "RequestPasswordRecovery") { send_request(td_api::make_object()); } else if (op == "rp" || op == "RecoverPassword") { - send_request(td_api::make_object(args)); + string code; + string new_password; + string new_hint; + get_args(args, code, new_password, new_hint); + send_request(td_api::make_object(code, new_password, new_hint)); } else if (op == "gtp" || op == "GetTemporaryPassword") { send_request(td_api::make_object()); } else if (op == "ctp" || op == "CreateTemporaryPassword") {