diff --git a/Telegram/SourceFiles/api/api_cloud_password.cpp b/Telegram/SourceFiles/api/api_cloud_password.cpp index e0d7248a77..c5ab29daaf 100644 --- a/Telegram/SourceFiles/api/api_cloud_password.cpp +++ b/Telegram/SourceFiles/api/api_cloud_password.cpp @@ -442,4 +442,103 @@ rpl::producer CloudPassword::setEmail( }; } +rpl::producer CloudPassword::recoverPassword( + const QString &code, + const QString &newPassword, + const QString &newHint) { + + const auto finish = [=](auto consumer) { + _api.request(MTPaccount_GetPassword( + )).done([=](const MTPaccount_Password &result) { + apply(ProcessMtpState(result)); + consumer.put_done(); + }).fail([=](const MTP::Error &error) { + consumer.put_error_copy(error.type()); + }).handleFloodErrors().send(); + }; + + const auto sendMTPaccountUpdatePasswordSettings = [=]( + const Core::CloudPasswordState &latestState, + auto consumer) { + const auto newPasswordBytes = newPassword.toUtf8(); + const auto newPasswordHash = Core::ComputeCloudPasswordDigest( + latestState.mtp.newPassword, + bytes::make_span(newPasswordBytes)); + if (!newPassword.isEmpty() && newPasswordHash.modpow.empty()) { + consumer.put_error("INTERNAL_SERVER_ERROR"); + return; + } + using Flag = MTPDaccount_passwordInputSettings::Flag; + const auto flags = Flag::f_new_algo + | Flag::f_new_password_hash + | Flag::f_hint; + + const auto settings = MTP_account_passwordInputSettings( + MTP_flags(flags), + Core::PrepareCloudPasswordAlgo(newPassword.isEmpty() + ? v::null + : latestState.mtp.newPassword), + newPassword.isEmpty() + ? MTP_bytes() + : MTP_bytes(newPasswordHash.modpow), + MTP_string(newHint), + MTP_string(), + MTPSecureSecretSettings()); + + _api.request(MTPauth_RecoverPassword( + MTP_flags(newPassword.isEmpty() + ? MTPauth_RecoverPassword::Flags(0) + : MTPauth_RecoverPassword::Flag::f_new_settings), + MTP_string(code), + settings + )).done([=](const MTPauth_Authorization &result) { + finish(consumer); + }).fail([=](const MTP::Error &error) { + const auto &type = error.type(); + consumer.put_error_copy(type); + }).handleFloodErrors().send(); + }; + + return [=](auto consumer) { + _api.request(MTPaccount_GetPassword( + )).done([=](const MTPaccount_Password &result) { + const auto latestState = ProcessMtpState(result); + sendMTPaccountUpdatePasswordSettings(latestState, consumer); + }).fail([=](const MTP::Error &error) { + consumer.put_error_copy(error.type()); + }).send(); + return rpl::lifetime(); + }; +} + +rpl::producer CloudPassword::requestPasswordRecovery() { + return [=](auto consumer) { + _api.request(MTPauth_RequestPasswordRecovery( + )).done([=](const MTPauth_PasswordRecovery &result) { + result.match([&](const MTPDauth_passwordRecovery &data) { + consumer.put_next(qs(data.vemail_pattern().v)); + }); + consumer.put_done(); + }).fail([=](const MTP::Error &error) { + consumer.put_error_copy(error.type()); + }).send(); + return rpl::lifetime(); + }; +} + +auto CloudPassword::checkRecoveryEmailAddressCode(const QString &code) +-> rpl::producer { + return [=](auto consumer) { + _api.request(MTPauth_CheckRecoveryPassword( + MTP_string(code) + )).done([=] { + consumer.put_done(); + }).fail([=](const MTP::Error &error) { + consumer.put_error_copy(error.type()); + }).handleFloodErrors().send(); + + return rpl::lifetime(); + }; +} + } // namespace Api diff --git a/Telegram/SourceFiles/api/api_cloud_password.h b/Telegram/SourceFiles/api/api_cloud_password.h index d741669c97..30bc379382 100644 --- a/Telegram/SourceFiles/api/api_cloud_password.h +++ b/Telegram/SourceFiles/api/api_cloud_password.h @@ -52,6 +52,14 @@ public: const QString &oldPassword, const QString &recoveryEmail); + rpl::producer recoverPassword( + const QString &code, + const QString &newPassword, + const QString &newHint); + rpl::producer requestPasswordRecovery(); + rpl::producer checkRecoveryEmailAddressCode( + const QString &code); + private: void apply(Core::CloudPasswordState state);