diff --git a/Telegram/SourceFiles/boxes/passcode_box.cpp b/Telegram/SourceFiles/boxes/passcode_box.cpp index 2c0bbf9b1..a63733293 100644 --- a/Telegram/SourceFiles/boxes/passcode_box.cpp +++ b/Telegram/SourceFiles/boxes/passcode_box.cpp @@ -154,9 +154,9 @@ void StartPendingReset( PasscodeBox::CloudFields PasscodeBox::CloudFields::From( const Core::CloudPasswordState ¤t) { auto result = CloudFields(); - result.curRequest = current.request; - result.newAlgo = current.newPassword; - result.newSecureSecretAlgo = current.newSecureSecret; + result.curRequest = current.mtp.request; + result.newAlgo = current.mtp.newPassword; + result.newSecureSecretAlgo = current.mtp.newSecureSecret; result.hasRecovery = current.hasRecovery; result.notEmptyPassport = current.notEmptyPassport; result.hint = current.hint; diff --git a/Telegram/SourceFiles/core/core_cloud_password.cpp b/Telegram/SourceFiles/core/core_cloud_password.cpp index f01b48087..99b5d589e 100644 --- a/Telegram/SourceFiles/core/core_cloud_password.cpp +++ b/Telegram/SourceFiles/core/core_cloud_password.cpp @@ -303,18 +303,53 @@ bytes::vector ComputeSecureSecretHash( CloudPasswordState ParseCloudPasswordState( const MTPDaccount_password &data) { auto result = CloudPasswordState(); - result.request = ParseCloudPasswordCheckRequest(data); - result.unknownAlgorithm = data.vcurrent_algo() && !result.request; + result.mtp.request = ParseCloudPasswordCheckRequest(data); + result.hasPassword = (!!result.mtp.request); + result.mtp.unknownAlgorithm = data.vcurrent_algo() && !result.hasPassword; result.hasRecovery = data.is_has_recovery(); result.notEmptyPassport = data.is_has_secure_values(); result.hint = qs(data.vhint().value_or_empty()); - result.newPassword = ValidateNewCloudPasswordAlgo( + result.mtp.newPassword = ValidateNewCloudPasswordAlgo( ParseCloudPasswordAlgo(data.vnew_algo())); - result.newSecureSecret = ValidateNewSecureSecretAlgo( + result.mtp.newSecureSecret = ValidateNewSecureSecretAlgo( ParseSecureSecretAlgo(data.vnew_secure_algo())); result.unconfirmedPattern = qs(data.vemail_unconfirmed_pattern().value_or_empty()); result.pendingResetDate = data.vpending_reset_date().value_or_empty(); + + result.outdatedClient = [&] { + const auto badSecureAlgo = data.vnew_secure_algo().match([]( + const MTPDsecurePasswordKdfAlgoUnknown &) { + return true; + }, [](const auto &) { + return false; + }); + if (badSecureAlgo) { + return true; + } + if (data.vcurrent_algo()) { + const auto badCurrentAlgo = data.vcurrent_algo()->match([]( + const MTPDpasswordKdfAlgoUnknown &) { + return true; + }, [](const auto &) { + return false; + }); + if (badCurrentAlgo) { + return true; + } + } + const auto badNewAlgo = data.vnew_algo().match([]( + const MTPDpasswordKdfAlgoUnknown &) { + return true; + }, [](const auto &) { + return false; + }); + if (badNewAlgo) { + return true; + } + return false; + }(); + return result; } diff --git a/Telegram/SourceFiles/core/core_cloud_password.h b/Telegram/SourceFiles/core/core_cloud_password.h index 78e319e7b..2c4d06bc8 100644 --- a/Telegram/SourceFiles/core/core_cloud_password.h +++ b/Telegram/SourceFiles/core/core_cloud_password.h @@ -122,13 +122,18 @@ bytes::vector ComputeSecureSecretHash( bytes::const_span password); struct CloudPasswordState { - CloudPasswordCheckRequest request; - bool unknownAlgorithm = false; + struct Mtp { + CloudPasswordCheckRequest request; + bool unknownAlgorithm = false; + CloudPasswordAlgo newPassword; + SecureSecretAlgo newSecureSecret; + }; + Mtp mtp; + bool hasPassword = false; bool hasRecovery = false; bool notEmptyPassport = false; + bool outdatedClient = false; QString hint; - CloudPasswordAlgo newPassword; - SecureSecretAlgo newSecureSecret; QString unconfirmedPattern; TimeId pendingResetDate = 0; }; diff --git a/Telegram/SourceFiles/intro/intro_code.cpp b/Telegram/SourceFiles/intro/intro_code.cpp index f7c91adcc..47baa5c49 100644 --- a/Telegram/SourceFiles/intro/intro_code.cpp +++ b/Telegram/SourceFiles/intro/intro_code.cpp @@ -346,7 +346,7 @@ void CodeWidget::gotPassword(const MTPaccount_Password &result) { LOG(("API Error: No current password received on login.")); _code->setFocus(); return; - } else if (!getData()->pwdState.request) { + } else if (!getData()->pwdState.hasPassword) { const auto callback = [=](Fn &&close) { Core::UpdateApplication(); close(); diff --git a/Telegram/SourceFiles/intro/intro_password_check.cpp b/Telegram/SourceFiles/intro/intro_password_check.cpp index 256facf57..a4cbfb87d 100644 --- a/Telegram/SourceFiles/intro/intro_password_check.cpp +++ b/Telegram/SourceFiles/intro/intro_password_check.cpp @@ -36,7 +36,7 @@ PasswordCheckWidget::PasswordCheckWidget( , _codeField(this, st::introPassword, tr::lng_signin_code()) , _toRecover(this, tr::lng_signin_recover(tr::now)) , _toPassword(this, tr::lng_signin_try_password(tr::now)) { - Expects(!!_passwordState.request); + Expects(_passwordState.hasPassword); Lang::Updated( ) | rpl::start_with_next([=] { @@ -169,7 +169,7 @@ void PasswordCheckWidget::handleSrpIdInvalid() { const auto now = crl::now(); if (_lastSrpIdInvalidTime > 0 && now - _lastSrpIdInvalidTime < Core::kHandleSrpIdInvalidTimeout) { - _passwordState.request.id = 0; + _passwordState.mtp.request.id = 0; showError(rpl::single(Lang::Hard::ServerError())); } else { _lastSrpIdInvalidTime = now; @@ -178,7 +178,7 @@ void PasswordCheckWidget::handleSrpIdInvalid() { } void PasswordCheckWidget::checkPasswordHash() { - if (_passwordState.request.id) { + if (_passwordState.mtp.request.id) { passwordChecked(); } else { requestPasswordData(); @@ -201,12 +201,12 @@ void PasswordCheckWidget::requestPasswordData() { void PasswordCheckWidget::passwordChecked() { const auto check = Core::ComputeCloudPasswordCheck( - _passwordState.request, + _passwordState.mtp.request, _passwordHash); if (!check) { return serverError(); } - _passwordState.request.id = 0; + _passwordState.mtp.request.id = 0; _sentRequest = api().request( MTPauth_CheckPassword(check.result) ).done([=](const MTPauth_Authorization &result) { @@ -391,7 +391,7 @@ void PasswordCheckWidget::submit() { const auto password = _pwdField->getLastText().toUtf8(); _passwordHash = Core::ComputeCloudPasswordHash( - _passwordState.request.algo, + _passwordState.mtp.request.algo, bytes::make_span(password)); checkPasswordHash(); } diff --git a/Telegram/SourceFiles/intro/intro_qr.cpp b/Telegram/SourceFiles/intro/intro_qr.cpp index bd4db429c..5cba6020c 100644 --- a/Telegram/SourceFiles/intro/intro_qr.cpp +++ b/Telegram/SourceFiles/intro/intro_qr.cpp @@ -394,7 +394,7 @@ void QrWidget::sendCheckPasswordRequest() { LOG(("API Error: No current password received on login.")); goReplace(Animate::Forward); return; - } else if (!getData()->pwdState.request) { + } else if (!getData()->pwdState.hasPassword) { const auto callback = [=](Fn &&close) { Core::UpdateApplication(); close(); diff --git a/Telegram/SourceFiles/payments/payments_checkout_process.cpp b/Telegram/SourceFiles/payments/payments_checkout_process.cpp index 67e389366..690988cf9 100644 --- a/Telegram/SourceFiles/payments/payments_checkout_process.cpp +++ b/Telegram/SourceFiles/payments/payments_checkout_process.cpp @@ -177,7 +177,7 @@ CheckoutProcess::CheckoutProcess( if (mode == Mode::Payment) { _session->api().cloudPassword().state( ) | rpl::start_with_next([=](const Core::CloudPasswordState &state) { - _form->setHasPassword(!!state.request); + _form->setHasPassword(state.hasPassword); }, _lifetime); } } @@ -624,7 +624,7 @@ void CheckoutProcess::requestPassword() { void CheckoutProcess::panelSetPassword() { getPasswordState([=](const Core::CloudPasswordState &state) { - if (state.request) { + if (state.hasPassword) { return; } auto owned = Box( diff --git a/Telegram/SourceFiles/settings/settings_privacy_security.cpp b/Telegram/SourceFiles/settings/settings_privacy_security.cpp index c1a8c2aaa..3b3e520f4 100644 --- a/Telegram/SourceFiles/settings/settings_privacy_security.cpp +++ b/Telegram/SourceFiles/settings/settings_privacy_security.cpp @@ -273,8 +273,8 @@ void SetupCloudPassword( false ) | rpl::then(controller->session().api().cloudPassword().state( ) | rpl::map([](const State &state) { - return state.request - || state.unknownAlgorithm + return state.mtp.request + || state.mtp.unknownAlgorithm || !state.unconfirmedPattern.isEmpty(); })) | rpl::distinct_until_changed(); auto pattern = session->api().cloudPassword().state( @@ -802,12 +802,7 @@ bool CheckEditCloudPassword(not_null<::Main::Session*> session) { const auto current = session->api().cloudPassword().stateCurrent(); Assert(current.has_value()); - if (!current->unknownAlgorithm - && !v::is_null(current->newPassword) - && !v::is_null(current->newSecureSecret)) { - return true; - } - return false; + return !current->outdatedClient; } object_ptr EditCloudPasswordBox(not_null session) { @@ -839,7 +834,7 @@ void RemoveCloudPassword(not_null controller) { const auto current = session->api().cloudPassword().stateCurrent(); Assert(current.has_value()); - if (!current->request) { + if (!current->hasPassword) { session->api().cloudPassword().clearUnconfirmedPassword(); return; }