From 01eacadca58e3a86520fde94d06dc4aebfae7912 Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Sun, 8 May 2022 23:03:11 +0300 Subject: [PATCH] Added ability to set recovery email from Api::CloudPassword. --- .../SourceFiles/api/api_cloud_password.cpp | 76 ++++++++++++++++++- Telegram/SourceFiles/api/api_cloud_password.h | 3 + 2 files changed, 77 insertions(+), 2 deletions(-) diff --git a/Telegram/SourceFiles/api/api_cloud_password.cpp b/Telegram/SourceFiles/api/api_cloud_password.cpp index 15ef2527e..e0d7248a7 100644 --- a/Telegram/SourceFiles/api/api_cloud_password.cpp +++ b/Telegram/SourceFiles/api/api_cloud_password.cpp @@ -25,8 +25,6 @@ namespace { } // namespace -// #TODO Add ability to set recovery email separately. - CloudPassword::CloudPassword(not_null api) : _api(&api->instance()) { } @@ -370,4 +368,78 @@ rpl::producer CloudPassword::resendEmailCode() { }; } +rpl::producer CloudPassword::setEmail( + const QString &oldPassword, + const QString &recoveryEmail) { + const auto generatePasswordCheck = [=]( + const Core::CloudPasswordState &latestState) { + if (oldPassword.isEmpty() || !latestState.hasPassword) { + return Core::CloudPasswordResult{ + MTP_inputCheckPasswordEmpty() + }; + } + const auto hash = Core::ComputeCloudPasswordHash( + latestState.mtp.request.algo, + bytes::make_span(oldPassword.toUtf8())); + return Core::ComputeCloudPasswordCheck( + latestState.mtp.request, + hash); + }; + + const auto finish = [=](auto consumer, int unconfirmedEmailLengthCode) { + _api.request(MTPaccount_GetPassword( + )).done([=](const MTPaccount_Password &result) { + apply(ProcessMtpState(result)); + if (unconfirmedEmailLengthCode) { + consumer.put_next(SetOk{ unconfirmedEmailLengthCode }); + } else { + 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 settings = MTP_account_passwordInputSettings( + MTP_flags(MTPDaccount_passwordInputSettings::Flag::f_email), + MTP_passwordKdfAlgoUnknown(), + MTP_bytes(), + MTP_string(), + MTP_string(recoveryEmail), + MTPSecureSecretSettings()); + _api.request(MTPaccount_UpdatePasswordSettings( + generatePasswordCheck(latestState).result, + settings + )).done([=] { + finish(consumer, 0); + }).fail([=](const MTP::Error &error) { + const auto &type = error.type(); + const auto prefix = u"EMAIL_UNCONFIRMED_"_q; + if (type.startsWith(prefix)) { + const auto codeLength = base::StringViewMid( + type, + prefix.size()).toInt(); + + finish(consumer, codeLength); + } else { + 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(); + }; +} + } // namespace Api diff --git a/Telegram/SourceFiles/api/api_cloud_password.h b/Telegram/SourceFiles/api/api_cloud_password.h index b26f343b8..d741669c9 100644 --- a/Telegram/SourceFiles/api/api_cloud_password.h +++ b/Telegram/SourceFiles/api/api_cloud_password.h @@ -48,6 +48,9 @@ public: rpl::producer confirmEmail(const QString &code); rpl::producer resendEmailCode(); + rpl::producer setEmail( + const QString &oldPassword, + const QString &recoveryEmail); private: void apply(Core::CloudPasswordState state);