diff --git a/Telegram/SourceFiles/app.cpp b/Telegram/SourceFiles/app.cpp index ffebdf65b..d8c11cf4b 100644 --- a/Telegram/SourceFiles/app.cpp +++ b/Telegram/SourceFiles/app.cpp @@ -147,43 +147,6 @@ namespace App { return false; } -namespace { - bool loggedOut() { - if (Global::LocalPasscode()) { - Global::SetLocalPasscode(false); - Global::RefLocalPasscodeChanged().notify(); - } - Media::Player::mixer()->stopAndClear(); - if (auto w = wnd()) { - w->tempDirDelete(Local::ClearManagerAll); - w->setupIntro(); - } - histories().clear(); - Messenger::Instance().authSessionDestroy(); - Local::reset(); - Window::Theme::Background()->reset(); - - cSetOtherOnline(0); - clearStorageImages(); - return true; - } -} // namespace - - void logOut() { - if (auto mtproto = Messenger::Instance().mtp()) { - mtproto->logout(rpcDone([] { - return loggedOut(); - }), rpcFail([] { - return loggedOut(); - })); - } else { - // We log out because we've forgotten passcode. - // So we just start mtproto from scratch. - Messenger::Instance().startMtp(); - loggedOut(); - } - } - namespace { // we should get a full restriction in "{fulltype}: {reason}" format and we // need to find a "-all" tag in {fulltype}, otherwise ignore this restriction diff --git a/Telegram/SourceFiles/app.h b/Telegram/SourceFiles/app.h index 3680a2f4d..021a3e582 100644 --- a/Telegram/SourceFiles/app.h +++ b/Telegram/SourceFiles/app.h @@ -68,8 +68,6 @@ namespace App { MainWidget *main(); bool passcoded(); - void logOut(); - QString formatPhone(QString phone); UserData *feedUser(const MTPUser &user); diff --git a/Telegram/SourceFiles/auth_session.cpp b/Telegram/SourceFiles/auth_session.cpp index 6c580cb5b..8ce8b33c1 100644 --- a/Telegram/SourceFiles/auth_session.cpp +++ b/Telegram/SourceFiles/auth_session.cpp @@ -314,7 +314,7 @@ bool AuthSession::validateSelf(const MTPUser &user) { return false; } else if (user.c_user().vid.v != userId()) { LOG(("Auth Error: wrong self user received.")); - App::logOutDelayed(); + crl::on_main(this, [] { Messenger::Instance().logOut(); }); return false; } return true; diff --git a/Telegram/SourceFiles/boxes/confirm_box.cpp b/Telegram/SourceFiles/boxes/confirm_box.cpp index 93175cdfc..1b89807b1 100644 --- a/Telegram/SourceFiles/boxes/confirm_box.cpp +++ b/Telegram/SourceFiles/boxes/confirm_box.cpp @@ -250,6 +250,9 @@ InformBox::InformBox(QWidget*, const QString &text, const QString &doneText, Fn< InformBox::InformBox(QWidget*, const TextWithEntities &text, Fn closedCallback) : ConfirmBox(ConfirmBox::InformBoxTag(), text, lang(lng_box_ok), std::move(closedCallback)) { } +InformBox::InformBox(QWidget*, const TextWithEntities &text, const QString &doneText, Fn closedCallback) : ConfirmBox(ConfirmBox::InformBoxTag(), text, doneText, std::move(closedCallback)) { +} + MaxInviteBox::MaxInviteBox(QWidget*, not_null channel) : BoxContent() , _channel(channel) , _text(st::boxLabelStyle, lng_participant_invite_sorry(lt_count, Global::ChatSizeMax()), _confirmBoxTextOptions, st::boxWidth - st::boxPadding.left() - st::boxButtonPadding.right()) { diff --git a/Telegram/SourceFiles/boxes/confirm_box.h b/Telegram/SourceFiles/boxes/confirm_box.h index 9c2ee6caa..c0c0d0009 100644 --- a/Telegram/SourceFiles/boxes/confirm_box.h +++ b/Telegram/SourceFiles/boxes/confirm_box.h @@ -87,6 +87,7 @@ public: InformBox(QWidget*, const QString &text, Fn closedCallback = nullptr); InformBox(QWidget*, const QString &text, const QString &doneText, Fn closedCallback = nullptr); InformBox(QWidget*, const TextWithEntities &text, Fn closedCallback = nullptr); + InformBox(QWidget*, const TextWithEntities &text, const QString &doneText, Fn closedCallback = nullptr); }; diff --git a/Telegram/SourceFiles/facades.cpp b/Telegram/SourceFiles/facades.cpp index 7deb2a4d4..a851c9657 100644 --- a/Telegram/SourceFiles/facades.cpp +++ b/Telegram/SourceFiles/facades.cpp @@ -183,12 +183,6 @@ void activateClickHandler(ClickHandlerPtr handler, Qt::MouseButton button) { }); } -void logOutDelayed() { - InvokeQueued(QCoreApplication::instance(), [] { - App::logOut(); - }); -} - } // namespace App namespace Ui { diff --git a/Telegram/SourceFiles/facades.h b/Telegram/SourceFiles/facades.h index 8e90cffa1..5b4a75db7 100644 --- a/Telegram/SourceFiles/facades.h +++ b/Telegram/SourceFiles/facades.h @@ -76,8 +76,6 @@ void showSettings(); void activateClickHandler(ClickHandlerPtr handler, Qt::MouseButton button); -void logOutDelayed(); - } // namespace App diff --git a/Telegram/SourceFiles/mainwidget.cpp b/Telegram/SourceFiles/mainwidget.cpp index a9940bdd5..1db6ae7fe 100644 --- a/Telegram/SourceFiles/mainwidget.cpp +++ b/Telegram/SourceFiles/mainwidget.cpp @@ -87,6 +87,41 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "styles/style_history.h" #include "styles/style_boxes.h" +namespace { + +bool IsForceLogoutNotification(const MTPDupdateServiceNotification &data) { + return qs(data.vtype).startsWith(qstr("AUTH_KEY_DROP_")); +} + +bool HasForceLogoutNotification(const MTPUpdates &updates) { + const auto checkUpdate = [](const MTPUpdate &update) { + if (update.type() != mtpc_updateServiceNotification) { + return false; + } + return IsForceLogoutNotification( + update.c_updateServiceNotification()); + }; + const auto checkVector = [&](const MTPVector &list) { + for (const auto &update : list.v) { + if (checkUpdate(update)) { + return true; + } + } + return false; + }; + switch (updates.type()) { + case mtpc_updates: + return checkVector(updates.c_updates().vupdates); + case mtpc_updatesCombined: + return checkVector(updates.c_updatesCombined().vupdates); + case mtpc_updateShort: + return checkUpdate(updates.c_updateShort().vupdate); + } + return false; +} + +} // namespace + enum StackItemType { HistoryStackItem, SectionStackItem, @@ -3293,7 +3328,7 @@ void MainWidget::feedMessageIds(const MTPVector &updates) { } bool MainWidget::updateFail(const RPCError &e) { - App::logOutDelayed(); + crl::on_main(this, [] { Messenger::Instance().logOut(); }); return true; } @@ -4231,7 +4266,8 @@ void MainWidget::updateReceived(const mtpPrime *from, const mtpPrime *end) { _lastUpdateTime = getms(true); noUpdatesTimer.start(NoUpdatesTimeout); - if (!requestingDifference()) { + if (!requestingDifference() + || HasForceLogoutNotification(updates)) { feedUpdates(updates); } } catch (mtpErrorUnexpected &) { // just some other type @@ -4899,11 +4935,17 @@ void MainWidget::feedUpdate(const MTPUpdate &update) { } break; case mtpc_updateServiceNotification: { - auto &d = update.c_updateServiceNotification(); - if (d.is_popup()) { - Ui::show(Box(qs(d.vmessage))); + const auto &d = update.c_updateServiceNotification(); + const auto text = TextWithEntities { + qs(d.vmessage), + TextUtilities::EntitiesFromMTP(d.ventities.v) + }; + if (IsForceLogoutNotification(d)) { + Messenger::Instance().forceLogOut(text); + } else if (d.is_popup()) { + Ui::show(Box(text)); } else { - App::wnd()->serviceNotification({ qs(d.vmessage), TextUtilities::EntitiesFromMTP(d.ventities.v) }, d.vmedia); + App::wnd()->serviceNotification(text, d.vmedia); emit App::wnd()->checkNewAuthorization(); } } break; diff --git a/Telegram/SourceFiles/mainwindow.cpp b/Telegram/SourceFiles/mainwindow.cpp index 3b8fde933..da4c98341 100644 --- a/Telegram/SourceFiles/mainwindow.cpp +++ b/Telegram/SourceFiles/mainwindow.cpp @@ -606,11 +606,15 @@ void MainWindow::onShowNewChannel() { } void MainWindow::onLogout() { - if (isHidden()) showFromTray(); + if (isHidden()) { + showFromTray(); + } - Ui::show(Box(lang(lng_sure_logout), lang(lng_settings_logout), st::attentionBoxButton, [] { - App::logOut(); - })); + Ui::show(Box( + lang(lng_sure_logout), + lang(lng_settings_logout), + st::attentionBoxButton, + [] { Messenger::Instance().logOut(); })); } void MainWindow::quitFromTray() { diff --git a/Telegram/SourceFiles/messenger.cpp b/Telegram/SourceFiles/messenger.cpp index 686514b70..6a2eb3367 100644 --- a/Telegram/SourceFiles/messenger.cpp +++ b/Telegram/SourceFiles/messenger.cpp @@ -35,6 +35,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "mtproto/dc_options.h" #include "mtproto/mtp_instance.h" #include "media/player/media_player_instance.h" +#include "media/media_audio.h" #include "media/media_audio_track.h" #include "window/notifications_manager.h" #include "window/themes/window_theme.h" @@ -508,20 +509,24 @@ void Messenger::suggestMainDcId(MTP::DcId mainDcId) { void Messenger::destroyStaleAuthorizationKeys() { Assert(_mtproto != nullptr); - auto keys = _mtproto->getKeysForWrite(); - for (auto &key : keys) { + for (const auto &key : _mtproto->getKeysForWrite()) { // Disable this for now. if (key->type() == MTP::AuthKey::Type::ReadFromFile) { _private->mtpKeysToDestroy = _mtproto->getKeysForWrite(); - _mtproto.reset(); - LOG(("MTP Info: destroying stale keys, count: %1").arg(_private->mtpKeysToDestroy.size())); - startMtp(); - Local::writeMtpData(); + LOG(("MTP Info: destroying stale keys, count: %1" + ).arg(_private->mtpKeysToDestroy.size())); + resetAuthorizationKeys(); return; } } } +void Messenger::resetAuthorizationKeys() { + _mtproto.reset(); + startMtp(); + Local::writeMtpData(); +} + void Messenger::startLocalStorage() { _dcOptions = std::make_unique(); _dcOptions->constructFromBuiltIn(); @@ -650,6 +655,18 @@ void Messenger::killDownloadSessionsStop(MTP::DcId dcId) { } } +void Messenger::forceLogOut(const TextWithEntities &explanation) { + const auto box = Ui::show(Box( + explanation, + lang(lng_passcode_logout))); + connect(box, &QObject::destroyed, [=] { + InvokeQueued(this, [=] { + resetAuthorizationKeys(); + loggedOut(); + }); + }); +} + void Messenger::checkLocalTime() { if (App::main()) App::main()->checkLastUpdate(checkms()); } @@ -777,8 +794,6 @@ void Messenger::authSessionDestroy() { _private->storedAuthSession.reset(); _private->authSessionUserId = 0; authSessionChanged().notify(true); - - loggedOut(); } void Messenger::setInternalLinkDomain(const QString &domain) const { @@ -1097,11 +1112,43 @@ void Messenger::checkMediaViewActivation() { } } +void Messenger::logOut() { + if (_mtproto) { + _mtproto->logout(::rpcDone([=] { + loggedOut(); + }), ::rpcFail([=] { + loggedOut(); + return true; + })); + } else { + // We log out because we've forgotten passcode. + // So we just start mtproto from scratch. + startMtp(); + loggedOut(); + } +} + void Messenger::loggedOut() { + if (Global::LocalPasscode()) { + Global::SetLocalPasscode(false); + Global::RefLocalPasscodeChanged().notify(); + } + Media::Player::mixer()->stopAndClear(); + if (const auto w = getActiveWindow()) { + w->tempDirDelete(Local::ClearManagerAll); + w->setupIntro(); + } + App::histories().clear(); + authSessionDestroy(); if (_mediaView) { hideMediaView(); _mediaView->clearData(); } + Local::reset(); + Window::Theme::Background()->reset(); + + cSetOtherOnline(0); + clearStorageImages(); } QPoint Messenger::getPointForCallPanelCenter() const { diff --git a/Telegram/SourceFiles/messenger.h b/Telegram/SourceFiles/messenger.h index 895ae8a81..101569f68 100644 --- a/Telegram/SourceFiles/messenger.h +++ b/Telegram/SourceFiles/messenger.h @@ -132,10 +132,10 @@ public: return _langCloudManager.get(); } void authSessionCreate(UserId userId); - void authSessionDestroy(); base::Observable &authSessionChanged() { return _authSessionChanged; } + void logOut(); // Media component. Media::Audio::Instance &audio() { @@ -166,6 +166,7 @@ public: void killDownloadSessionsStart(MTP::DcId dcId); void killDownloadSessionsStop(MTP::DcId dcId); + void forceLogOut(const TextWithEntities &explanation); void checkLocalTime(); void setupPasscode(); void clearPasscode(); @@ -215,6 +216,8 @@ private: void quitDelayed(); void photoUpdated(const FullMsgId &msgId, const MTPInputFile &file); + void resetAuthorizationKeys(); + void authSessionDestroy(); void loggedOut(); not_null _launcher;