diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings index 8dedebdf5..cad1098f8 100644 --- a/Telegram/Resources/langs/lang.strings +++ b/Telegram/Resources/langs/lang.strings @@ -730,6 +730,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_cloud_password_reset_cancel_title" = "Cancel reset"; "lng_cloud_password_reset_cancel_sure" = "Cancel the password reset process? If you request a new reset later, it will take another 7 days."; "lng_cloud_password_reset_later" = "You recently requested a password reset that was cancelled. Please wait {duration} before making a new request."; +"lng_cloud_password_expired" = "Please re-enter your password."; "lng_connection_auto_connecting" = "Default (connecting...)"; "lng_connection_auto" = "Default ({transport} used)"; diff --git a/Telegram/SourceFiles/settings/cloud_password/settings_cloud_password_common.cpp b/Telegram/SourceFiles/settings/cloud_password/settings_cloud_password_common.cpp index f6b572e84..af46a5feb 100644 --- a/Telegram/SourceFiles/settings/cloud_password/settings_cloud_password_common.cpp +++ b/Telegram/SourceFiles/settings/cloud_password/settings_cloud_password_common.cpp @@ -11,7 +11,15 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "lang/lang_keys.h" #include "lottie/lottie_icon.h" #include "main/main_session.h" +#include "settings/cloud_password/settings_cloud_password_common.h" +#include "settings/cloud_password/settings_cloud_password_email.h" +#include "settings/cloud_password/settings_cloud_password_email_confirm.h" +#include "settings/cloud_password/settings_cloud_password_hint.h" +#include "settings/cloud_password/settings_cloud_password_input.h" +#include "settings/cloud_password/settings_cloud_password_manage.h" +#include "settings/cloud_password/settings_cloud_password_start.h" #include "settings/settings_common.h" +#include "ui/boxes/confirm_box.h" #include "ui/widgets/buttons.h" #include "ui/widgets/input_fields.h" #include "ui/widgets/labels.h" @@ -250,6 +258,10 @@ Api::CloudPassword &AbstractStep::cloudPassword() { return _controller->session().api().cloudPassword(); } +rpl::producer AbstractStep::removeTypes() { + return rpl::never(); +} + void AbstractStep::showBack() { _showBack.fire({}); } @@ -276,6 +288,30 @@ void AbstractStep::setInnerFocus() { } } +bool AbstractStep::isPasswordInvalidError(const QString &type) { + if (type == u"PASSWORD_HASH_INVALID"_q + || type == u"SRP_PASSWORD_CHANGED"_q) { + + // Most likely the cloud password has been changed on another device. + // Quit. + _quits.fire(AbstractStep::Types{ + CloudPasswordStartId(), + CloudPasswordInputId(), + CloudPasswordHintId(), + CloudPasswordEmailId(), + CloudPasswordEmailConfirmId(), + CloudPasswordManageId(), + }); + controller()->show( + Ui::MakeInformBox(tr::lng_cloud_password_expired()), + Ui::LayerOption::CloseOther); + setStepData(StepData()); + showBack(); + return true; + } + return false; +} + rpl::producer AbstractStep::sectionShowOther() { return _showOther.events(); } @@ -284,6 +320,10 @@ rpl::producer<> AbstractStep::sectionShowBack() { return _showBack.events(); } +rpl::producer> AbstractStep::removeFromStack() { + return rpl::merge(removeTypes(), _quits.events()); +} + void AbstractStep::setStepDataReference(std::any &data) { _stepData = &data; } diff --git a/Telegram/SourceFiles/settings/cloud_password/settings_cloud_password_common.h b/Telegram/SourceFiles/settings/cloud_password/settings_cloud_password_common.h index 8a32b7a83..ed1d94c7c 100644 --- a/Telegram/SourceFiles/settings/cloud_password/settings_cloud_password_common.h +++ b/Telegram/SourceFiles/settings/cloud_password/settings_cloud_password_common.h @@ -43,6 +43,8 @@ struct StepData { ProcessRecover processRecover; }; +void SetupAutoCloseTimer(rpl::lifetime &lifetime, Fn callback); + void SetupHeader( not_null content, const QString &lottie, @@ -102,15 +104,18 @@ private: class AbstractStep : public AbstractSection { public: + using Types = std::vector; AbstractStep( QWidget *parent, not_null controller); ~AbstractStep(); - void showFinished() override; - void setInnerFocus() override; - [[nodiscard]] rpl::producer sectionShowOther() override; - [[nodiscard]] rpl::producer<> sectionShowBack() override; + void showFinished() override final; + void setInnerFocus() override final; + [[nodiscard]] rpl::producer sectionShowOther() override final; + [[nodiscard]] rpl::producer<> sectionShowBack() override final; + + [[nodiscard]] rpl::producer removeFromStack() override final; void setStepDataReference(std::any &data) override; @@ -118,6 +123,10 @@ protected: [[nodiscard]] not_null controller() const; [[nodiscard]] Api::CloudPassword &cloudPassword(); + [[nodiscard]] virtual rpl::producer removeTypes(); + + bool isPasswordInvalidError(const QString &type); + void showBack(); void showOther(Type type); @@ -136,6 +145,7 @@ private: rpl::event_stream<> _showFinished; rpl::event_stream _showOther; rpl::event_stream<> _showBack; + rpl::event_stream _quits; std::any *_stepData; diff --git a/Telegram/SourceFiles/settings/cloud_password/settings_cloud_password_email.cpp b/Telegram/SourceFiles/settings/cloud_password/settings_cloud_password_email.cpp index ca5230a38..1e13fae55 100644 --- a/Telegram/SourceFiles/settings/cloud_password/settings_cloud_password_email.cpp +++ b/Telegram/SourceFiles/settings/cloud_password/settings_cloud_password_email.cpp @@ -121,6 +121,7 @@ void Email::setupContent() { if (MTP::IsFloodError(type)) { error->show(); error->setText(tr::lng_flood_error(tr::now)); + } else if (AbstractStep::isPasswordInvalidError(type)) { } else if (type == u"EMAIL_INVALID"_q) { error->show(); error->setText(tr::lng_cloud_password_bad_email(tr::now)); diff --git a/Telegram/SourceFiles/settings/cloud_password/settings_cloud_password_email_confirm.cpp b/Telegram/SourceFiles/settings/cloud_password/settings_cloud_password_email_confirm.cpp index 926dd1740..09fc68aa0 100644 --- a/Telegram/SourceFiles/settings/cloud_password/settings_cloud_password_email_confirm.cpp +++ b/Telegram/SourceFiles/settings/cloud_password/settings_cloud_password_email_confirm.cpp @@ -56,7 +56,8 @@ public: [[nodiscard]] rpl::producer title() override; void setupContent(); - [[nodiscard]] rpl::producer> removeFromStack() override; +protected: + [[nodiscard]] rpl::producer> removeTypes() override; private: rpl::lifetime _requestLifetime; @@ -67,7 +68,7 @@ rpl::producer EmailConfirm::title() { return tr::lng_settings_cloud_password_email_title(); } -rpl::producer> EmailConfirm::removeFromStack() { +rpl::producer> EmailConfirm::removeTypes() { return rpl::single(std::vector{ CloudPasswordStartId(), CloudPasswordInputId(), diff --git a/Telegram/SourceFiles/settings/cloud_password/settings_cloud_password_input.cpp b/Telegram/SourceFiles/settings/cloud_password/settings_cloud_password_input.cpp index 8b27cfb8b..298ca23da 100644 --- a/Telegram/SourceFiles/settings/cloud_password/settings_cloud_password_input.cpp +++ b/Telegram/SourceFiles/settings/cloud_password/settings_cloud_password_input.cpp @@ -118,7 +118,8 @@ public: [[nodiscard]] rpl::producer title() override; void setupContent(); - [[nodiscard]] rpl::producer> removeFromStack() override; +protected: + [[nodiscard]] rpl::producer> removeTypes() override; private: void setupRecoverButton( @@ -132,7 +133,7 @@ private: }; -rpl::producer> Input::removeFromStack() { +rpl::producer> Input::removeTypes() { return _removesFromStack.value(); } diff --git a/Telegram/SourceFiles/settings/cloud_password/settings_cloud_password_manage.cpp b/Telegram/SourceFiles/settings/cloud_password/settings_cloud_password_manage.cpp index b84da8474..246b0d6a2 100644 --- a/Telegram/SourceFiles/settings/cloud_password/settings_cloud_password_manage.cpp +++ b/Telegram/SourceFiles/settings/cloud_password/settings_cloud_password_manage.cpp @@ -94,11 +94,12 @@ public: [[nodiscard]] rpl::producer title() override; void setupContent(); - [[nodiscard]] rpl::producer> removeFromStack() override; - [[nodiscard]] QPointer createPinnedToBottom( not_null parent) override; +protected: + [[nodiscard]] rpl::producer> removeTypes() override; + private: rpl::variable _isBottomFillerShown; @@ -112,7 +113,7 @@ rpl::producer Manage::title() { return tr::lng_settings_cloud_password_start_title(); } -rpl::producer> Manage::removeFromStack() { +rpl::producer> Manage::removeTypes() { return rpl::single(std::vector{ CloudPasswordStartId(), CloudPasswordInputId(), @@ -221,7 +222,9 @@ QPointer Manage::createPinnedToBottom( QString(), false, QString() - ) | rpl::start_with_done([=] { + ) | rpl::start_with_error_done([=](const QString &type) { + AbstractStep::isPasswordInvalidError(type); + }, [=] { setStepData(StepData()); close(); showBack();