From 9cf4cf6dcaf6f7b4bff34d0245e2d25707aaf27c Mon Sep 17 00:00:00 2001 From: John Preston Date: Wed, 24 Jul 2019 10:46:23 +0200 Subject: [PATCH] Move MTP::Instance to Main::Account. --- Telegram/SourceFiles/auth_session.cpp | 6 +- Telegram/SourceFiles/auth_session.h | 1 + Telegram/SourceFiles/boxes/connection_box.cpp | 3 +- Telegram/SourceFiles/boxes/language_box.cpp | 8 +- .../chat_helpers/emoji_sets_manager.cpp | 3 +- Telegram/SourceFiles/core/application.cpp | 450 ++---------------- Telegram/SourceFiles/core/application.h | 50 +- Telegram/SourceFiles/core/update_checker.cpp | 5 +- Telegram/SourceFiles/data/data_folder.cpp | 8 +- Telegram/SourceFiles/data/data_session.cpp | 8 +- Telegram/SourceFiles/intro/introcode.cpp | 10 +- Telegram/SourceFiles/intro/introcode.h | 5 +- Telegram/SourceFiles/intro/introphone.cpp | 13 +- Telegram/SourceFiles/intro/introphone.h | 5 +- Telegram/SourceFiles/intro/intropwdcheck.cpp | 5 +- Telegram/SourceFiles/intro/intropwdcheck.h | 5 +- Telegram/SourceFiles/intro/introsignup.cpp | 6 +- Telegram/SourceFiles/intro/introsignup.h | 5 +- Telegram/SourceFiles/intro/introstart.cpp | 8 +- Telegram/SourceFiles/intro/introstart.h | 5 +- Telegram/SourceFiles/intro/introwidget.cpp | 33 +- Telegram/SourceFiles/intro/introwidget.h | 53 ++- Telegram/SourceFiles/main/main_account.cpp | 434 ++++++++++++++++- Telegram/SourceFiles/main/main_account.h | 60 ++- Telegram/SourceFiles/mainwidget.cpp | 2 +- Telegram/SourceFiles/mainwindow.cpp | 13 +- Telegram/SourceFiles/mtproto/dc_options.cpp | 4 + Telegram/SourceFiles/mtproto/dc_options.h | 2 + Telegram/SourceFiles/mtproto/facade.cpp | 5 +- Telegram/SourceFiles/mtproto/mtp_instance.cpp | 9 +- .../SourceFiles/settings/settings_codes.cpp | 2 +- Telegram/SourceFiles/storage/localstorage.cpp | 15 +- 32 files changed, 715 insertions(+), 526 deletions(-) diff --git a/Telegram/SourceFiles/auth_session.cpp b/Telegram/SourceFiles/auth_session.cpp index 3054dbbe6f..2b47176c9d 100644 --- a/Telegram/SourceFiles/auth_session.cpp +++ b/Telegram/SourceFiles/auth_session.cpp @@ -534,7 +534,7 @@ bool AuthSession::validateSelf(const MTPUser &user) { return false; } else if (user.c_user().vid().v != userId()) { LOG(("Auth Error: wrong self user received.")); - crl::on_main(this, [] { Core::App().logOut(); }); + crl::on_main(this, [=] { _account->logOut(); }); return false; } return true; @@ -558,6 +558,10 @@ void AuthSession::saveSettingsDelayed(crl::time delay) { _saveDataTimer.callOnce(delay); } +not_null AuthSession::mtp() { + return _account->mtp(); +} + void AuthSession::localPasscodeChanged() { _shouldLockAt = 0; _autoLockTimer.cancel(); diff --git a/Telegram/SourceFiles/auth_session.h b/Telegram/SourceFiles/auth_session.h index 76557acc89..201882fc24 100644 --- a/Telegram/SourceFiles/auth_session.h +++ b/Telegram/SourceFiles/auth_session.h @@ -333,6 +333,7 @@ public: void moveSettingsFrom(AuthSessionSettings &&other); void saveSettingsDelayed(crl::time delay = kDefaultSaveDelay); + not_null mtp(); ApiWrap &api() { return *_api; } diff --git a/Telegram/SourceFiles/boxes/connection_box.cpp b/Telegram/SourceFiles/boxes/connection_box.cpp index 8ea0c82a93..5622cf2d7c 100644 --- a/Telegram/SourceFiles/boxes/connection_box.cpp +++ b/Telegram/SourceFiles/boxes/connection_box.cpp @@ -12,6 +12,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "storage/localstorage.h" #include "base/qthelp_url.h" #include "core/application.h" +#include "main/main_account.h" #include "ui/widgets/checkbox.h" #include "ui/widgets/buttons.h" #include "ui/widgets/input_fields.h" @@ -1045,7 +1046,7 @@ void ProxiesBoxController::refreshChecker(Item &item) { const auto type = (item.data.type == Type::Http) ? Variants::Http : Variants::Tcp; - const auto mtproto = Core::App().mtp(); + const auto mtproto = Core::App().activeAccount().mtp(); const auto dcId = mtproto->mainDcId(); item.state = ItemState::Checking; diff --git a/Telegram/SourceFiles/boxes/language_box.cpp b/Telegram/SourceFiles/boxes/language_box.cpp index a45cd07efe..46e73d1695 100644 --- a/Telegram/SourceFiles/boxes/language_box.cpp +++ b/Telegram/SourceFiles/boxes/language_box.cpp @@ -1155,13 +1155,13 @@ not_null LanguageBox::createMultiSelect() { base::binary_guard LanguageBox::Show() { auto result = base::binary_guard(); - const auto manager = Core::App().langCloudManager(); - if (manager->languageList().empty()) { + auto &manager = Lang::CurrentCloudManager(); + if (manager.languageList().empty()) { auto guard = std::make_shared( result.make_guard()); auto alive = std::make_shared>( std::make_unique()); - **alive = manager->languageListChanged().add_subscription([=] { + **alive = manager.languageListChanged().add_subscription([=] { const auto show = guard->alive(); *alive = nullptr; if (show) { @@ -1171,7 +1171,7 @@ base::binary_guard LanguageBox::Show() { } else { Ui::show(Box()); } - manager->requestLanguageList(); + manager.requestLanguageList(); return result; } diff --git a/Telegram/SourceFiles/chat_helpers/emoji_sets_manager.cpp b/Telegram/SourceFiles/chat_helpers/emoji_sets_manager.cpp index 40e1ffb92d..47493a65d3 100644 --- a/Telegram/SourceFiles/chat_helpers/emoji_sets_manager.cpp +++ b/Telegram/SourceFiles/chat_helpers/emoji_sets_manager.cpp @@ -19,6 +19,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "base/zlib_help.h" #include "layout.h" #include "core/application.h" +#include "main/main_account.h" #include "mainwidget.h" #include "styles/style_boxes.h" #include "styles/style_chat_helpers.h" @@ -245,7 +246,7 @@ Loader::Loader(QObject *parent, int id) , _id(id) , _size(GetDownloadSize(_id)) , _state(Loading{ 0, _size }) -, _mtproto(Core::App().mtp()) { +, _mtproto(Core::App().activeAccount().mtp()) { const auto ready = [=](std::unique_ptr loader) { if (loader) { setImplementation(std::move(loader)); diff --git a/Telegram/SourceFiles/core/application.cpp b/Telegram/SourceFiles/core/application.cpp index 702531ae69..bc1addfb87 100644 --- a/Telegram/SourceFiles/core/application.cpp +++ b/Telegram/SourceFiles/core/application.cpp @@ -72,12 +72,6 @@ constexpr auto kQuitPreventTimeoutMs = 1500; Application *Application::Instance = nullptr; struct Application::Private { - UserId authSessionUserId = 0; - QByteArray authSessionUserSerialized; - int32 authSessionUserStreamVersion = 0; - std::unique_ptr storedAuthSession; - MTP::Instance::Config mtpConfig; - MTP::AuthKeysList mtpKeysToDestroy; base::Timer quitTimer; }; @@ -87,6 +81,7 @@ Application::Application(not_null launcher) , _private(std::make_unique()) , _databases(std::make_unique()) , _animationsManager(std::make_unique()) +, _dcOptions(std::make_unique()) , _account(std::make_unique(cDataFile())) , _langpack(std::make_unique()) , _emojiKeywords(std::make_unique()) @@ -95,9 +90,26 @@ Application::Application(not_null launcher) , _logoNoMargin(Window::LoadLogoNoMargin()) { Expects(!_logo.isNull()); Expects(!_logoNoMargin.isNull()); - Expects(Instance == nullptr); - Instance = this; + activeAccount().sessionChanges( + ) | rpl::start_with_next([=] { + if (_mediaView) { + hideMediaView(); + _mediaView->clearData(); + } + }, _lifetime); + + activeAccount().mtpChanges( + ) | rpl::filter([=](MTP::Instance *instance) { + return instance != nullptr; + }) | rpl::start_with_next([=](not_null mtp) { + _langCloudManager = std::make_unique( + langpack(), + mtp); + if (!UpdaterDisabled()) { + UpdateChecker().setMtproto(mtp.get()); + } + }, _lifetime); } Application::~Application() { @@ -109,14 +121,14 @@ Application::~Application() { Local::finish(); // Some MTP requests can be cancelled from data clearing. - authSessionDestroy(); + unlockTerms(); + activeAccount().destroySession(); // The langpack manager should be destroyed before MTProto instance, // because it is MTP::Sender and it may have pending requests. _langCloudManager.reset(); - _mtproto.reset(); - _mtprotoForKeysDestroy.reset(); + activeAccount().clearMtp(); Shortcuts::Finish(); @@ -199,7 +211,7 @@ void Application::run() { DEBUG_LOG(("Application Info: passcode needed...")); } else { DEBUG_LOG(("Application Info: local map read...")); - startMtp(); + activeAccount().startMtp(); DEBUG_LOG(("Application Info: MTP started...")); if (activeAccount().sessionExists()) { _window->setupMain(); @@ -327,31 +339,24 @@ bool Application::eventFilter(QObject *object, QEvent *e) { void Application::setCurrentProxy( const ProxyData &proxy, ProxyData::Settings settings) { - const auto key = [&](const ProxyData &proxy) { - if (proxy.type == ProxyData::Type::Mtproto) { - return std::make_pair(proxy.host, proxy.port); - } - return std::make_pair(QString(), uint32(0)); - }; - const auto previousKey = key( - (Global::ProxySettings() == ProxyData::Settings::Enabled + const auto current = [&] { + return (Global::ProxySettings() == ProxyData::Settings::Enabled) ? Global::SelectedProxy() - : ProxyData())); + : ProxyData(); + }; + const auto was = current(); Global::SetSelectedProxy(proxy); Global::SetProxySettings(settings); + const auto now = current(); refreshGlobalProxy(); - if (_mtproto) { - _mtproto->restart(); - if (previousKey != key(proxy)) { - _mtproto->reInitConnection(_mtproto->mainDcId()); - } - } - if (_mtprotoForKeysDestroy) { - _mtprotoForKeysDestroy->restart(); - } + _proxyChanges.fire({ was, now }); Global::RefConnectionTypeChanged().notify(); } +auto Application::proxyChanges() const -> rpl::producer { + return _proxyChanges.events(); +} + void Application::badMtprotoConfigurationError() { if (Global::ProxySettings() == ProxyData::Settings::Enabled && !_badProxyDisableBox) { @@ -366,311 +371,16 @@ void Application::badMtprotoConfigurationError() { } } -void Application::setMtpMainDcId(MTP::DcId mainDcId) { - Expects(!_mtproto); - - _private->mtpConfig.mainDcId = mainDcId; -} - -void Application::setMtpKey(MTP::DcId dcId, const MTP::AuthKey::Data &keyData) { - Expects(!_mtproto); - - _private->mtpConfig.keys.push_back(std::make_shared(MTP::AuthKey::Type::ReadFromFile, dcId, keyData)); -} - -QByteArray Application::serializeMtpAuthorization() const { - auto serialize = [this](auto mainDcId, auto &keys, auto &keysToDestroy) { - auto keysSize = [](auto &list) { - return sizeof(qint32) + list.size() * (sizeof(qint32) + MTP::AuthKey::Data().size()); - }; - auto writeKeys = [](QDataStream &stream, auto &keys) { - stream << qint32(keys.size()); - for (auto &key : keys) { - stream << qint32(key->dcId()); - key->write(stream); - } - }; - - auto result = QByteArray(); - auto size = sizeof(qint32) + sizeof(qint32); // userId + mainDcId - size += keysSize(keys) + keysSize(keysToDestroy); - result.reserve(size); - { - QDataStream stream(&result, QIODevice::WriteOnly); - stream.setVersion(QDataStream::Qt_5_1); - - auto currentUserId = activeAccount().sessionExists() - ? activeAccount().session().userId() - : 0; - stream << qint32(currentUserId) << qint32(mainDcId); - writeKeys(stream, keys); - writeKeys(stream, keysToDestroy); - - DEBUG_LOG(("MTP Info: Keys written, userId: %1, dcId: %2").arg(currentUserId).arg(mainDcId)); - } - return result; - }; - if (_mtproto) { - auto keys = _mtproto->getKeysForWrite(); - auto keysToDestroy = _mtprotoForKeysDestroy ? _mtprotoForKeysDestroy->getKeysForWrite() : MTP::AuthKeysList(); - return serialize(_mtproto->mainDcId(), keys, keysToDestroy); - } - auto &keys = _private->mtpConfig.keys; - auto &keysToDestroy = _private->mtpKeysToDestroy; - return serialize(_private->mtpConfig.mainDcId, keys, keysToDestroy); -} - -void Application::setAuthSessionUserId(UserId userId) { - Expects(!activeAccount().sessionExists()); - - _private->authSessionUserId = userId; -} - -void Application::setAuthSessionFromStorage( - std::unique_ptr data, - QByteArray &&selfSerialized, - int32 selfStreamVersion) { - Expects(!activeAccount().sessionExists()); - - DEBUG_LOG(("authSessionUserSerialized set: %1" - ).arg(selfSerialized.size())); - - _private->storedAuthSession = std::move(data); - _private->authSessionUserSerialized = std::move(selfSerialized); - _private->authSessionUserStreamVersion = selfStreamVersion; -} - -AuthSessionSettings *Application::getAuthSessionSettings() { - if (_private->authSessionUserId) { - return _private->storedAuthSession - ? _private->storedAuthSession.get() - : nullptr; - } else if (activeAccount().sessionExists()) { - return &activeAccount().session().settings(); - } - return nullptr; -} - -void Application::setMtpAuthorization(const QByteArray &serialized) { - Expects(!_mtproto); - - QDataStream stream(serialized); - stream.setVersion(QDataStream::Qt_5_1); - - auto userId = Serialize::read(stream); - auto mainDcId = Serialize::read(stream); - if (stream.status() != QDataStream::Ok) { - LOG(("MTP Error: could not read main fields from serialized mtp authorization.")); - return; - } - - setAuthSessionUserId(userId); - _private->mtpConfig.mainDcId = mainDcId; - - auto readKeys = [&stream](auto &keys) { - auto count = Serialize::read(stream); - if (stream.status() != QDataStream::Ok) { - LOG(("MTP Error: could not read keys count from serialized mtp authorization.")); - return; - } - keys.reserve(count); - for (auto i = 0; i != count; ++i) { - auto dcId = Serialize::read(stream); - auto keyData = Serialize::read(stream); - if (stream.status() != QDataStream::Ok) { - LOG(("MTP Error: could not read key from serialized mtp authorization.")); - return; - } - keys.push_back(std::make_shared(MTP::AuthKey::Type::ReadFromFile, dcId, keyData)); - } - }; - readKeys(_private->mtpConfig.keys); - readKeys(_private->mtpKeysToDestroy); - LOG(("MTP Info: read keys, current: %1, to destroy: %2").arg(_private->mtpConfig.keys.size()).arg(_private->mtpKeysToDestroy.size())); -} - -void Application::startMtp() { - Expects(!_mtproto); - - auto config = base::take(_private->mtpConfig); - config.deviceModel = _launcher->deviceModel(); - config.systemVersion = _launcher->systemVersion(); - _mtproto = std::make_unique( - _dcOptions.get(), - MTP::Instance::Mode::Normal, - std::move(config)); - _mtproto->setUserPhone(cLoggedPhoneNumber()); - _private->mtpConfig.mainDcId = _mtproto->mainDcId(); - - _mtproto->setStateChangedHandler([](MTP::ShiftedDcId dc, int32 state) { - if (dc == MTP::maindc()) { - Global::RefConnectionTypeChanged().notify(); - } - }); - _mtproto->setSessionResetHandler([](MTP::ShiftedDcId shiftedDcId) { - if (App::main() && shiftedDcId == MTP::maindc()) { - App::main()->getDifference(); - } - }); - - if (!_private->mtpKeysToDestroy.empty()) { - destroyMtpKeys(base::take(_private->mtpKeysToDestroy)); - } - - if (_private->authSessionUserId) { - DEBUG_LOG(("authSessionUserSerialized.size: %1" - ).arg(_private->authSessionUserSerialized.size())); - QDataStream peekStream(_private->authSessionUserSerialized); - const auto phone = Serialize::peekUserPhone( - _private->authSessionUserStreamVersion, - peekStream); - const auto flags = MTPDuser::Flag::f_self | (phone.isEmpty() - ? MTPDuser::Flag() - : MTPDuser::Flag::f_phone); - authSessionCreate(MTP_user( - MTP_flags(flags), - MTP_int(base::take(_private->authSessionUserId)), - MTPlong(), // access_hash - MTPstring(), // first_name - MTPstring(), // last_name - MTPstring(), // username - MTP_string(phone), - MTPUserProfilePhoto(), - MTPUserStatus(), - MTPint(), // bot_info_version - MTPstring(), // restriction_reason - MTPstring(), // bot_inline_placeholder - MTPstring())); // lang_code - Local::readSelf( - base::take(_private->authSessionUserSerialized), - base::take(_private->authSessionUserStreamVersion)); - } - if (_private->storedAuthSession) { - if (activeAccount().sessionExists()) { - activeAccount().session().moveSettingsFrom( - std::move(*_private->storedAuthSession)); - } - _private->storedAuthSession.reset(); - } - - _langCloudManager = std::make_unique( - langpack(), - mtp()); - if (!UpdaterDisabled()) { - UpdateChecker().setMtproto(mtp()); - } - - if (activeAccount().sessionExists()) { - // Skip all pending self updates so that we won't Local::writeSelf. - Notify::peerUpdatedSendDelayed(); - } -} - -void Application::destroyMtpKeys(MTP::AuthKeysList &&keys) { - if (keys.empty()) { - return; - } - if (_mtprotoForKeysDestroy) { - _mtprotoForKeysDestroy->addKeysForDestroy(std::move(keys)); - Local::writeMtpData(); - return; - } - auto destroyConfig = MTP::Instance::Config(); - destroyConfig.mainDcId = MTP::Instance::Config::kNoneMainDc; - destroyConfig.keys = std::move(keys); - destroyConfig.deviceModel = _launcher->deviceModel(); - destroyConfig.systemVersion = _launcher->systemVersion(); - _mtprotoForKeysDestroy = std::make_unique( - _dcOptions.get(), - MTP::Instance::Mode::KeysDestroyer, - std::move(destroyConfig)); - connect( - _mtprotoForKeysDestroy.get(), - &MTP::Instance::allKeysDestroyed, - [=] { allKeysDestroyed(); }); -} - -void Application::allKeysDestroyed() { - LOG(("MTP Info: all keys scheduled for destroy are destroyed.")); - crl::on_main(this, [=] { - _mtprotoForKeysDestroy = nullptr; - Local::writeMtpData(); - }); -} - -void Application::suggestMainDcId(MTP::DcId mainDcId) { - Expects(_mtproto != nullptr); - - _mtproto->suggestMainDcId(mainDcId); - if (_private->mtpConfig.mainDcId != MTP::Instance::Config::kNotSetMainDc) { - _private->mtpConfig.mainDcId = mainDcId; - } -} - -void Application::destroyStaleAuthorizationKeys() { - Expects(_mtproto != nullptr); - - for (const auto &key : _mtproto->getKeysForWrite()) { - // Disable this for now. - if (key->type() == MTP::AuthKey::Type::ReadFromFile) { - _private->mtpKeysToDestroy = _mtproto->getKeysForWrite(); - LOG(("MTP Info: destroying stale keys, count: %1" - ).arg(_private->mtpKeysToDestroy.size())); - resetAuthorizationKeys(); - return; - } - } -} - -void Application::configUpdated() { - _configUpdates.fire({}); -} - -rpl::producer<> Application::configUpdates() const { - return _configUpdates.events(); -} - -void Application::resetAuthorizationKeys() { - _mtproto = nullptr; - startMtp(); - Local::writeMtpData(); -} - void Application::startLocalStorage() { - _dcOptions = std::make_unique(); - _dcOptions->constructFromBuiltIn(); Local::start(); subscribe(_dcOptions->changed(), [this](const MTP::DcOptions::Ids &ids) { Local::writeSettings(); - if (auto instance = mtp()) { - for (auto id : ids) { + if (const auto instance = activeAccount().mtp()) { + for (const auto id : ids) { instance->restart(id); } } }); - activeAccount().sessionChanges( - ) | rpl::start_with_next([=] { - crl::on_main(this, [=] { - const auto phone = activeAccount().sessionExists() - ? activeAccount().session().user()->phone() - : QString(); - const auto support = activeAccount().sessionExists() - && activeAccount().session().supportMode(); - if (cLoggedPhoneNumber() != phone) { - cSetLoggedPhoneNumber(phone); - if (_mtproto) { - _mtproto->setUserPhone(phone); - } - Local::writeSettings(); - } - if (_mtproto) { - _mtproto->requestConfig(); - } - Platform::SetApplicationIcon( - Window::CreateIcon(&activeAccount())); - Shortcuts::ToggleSupportShortcuts(support); - }); - }, _lifetime); } void Application::forceLogOut(const TextWithEntities &explanation) { @@ -681,10 +391,7 @@ void Application::forceLogOut(const TextWithEntities &explanation) { box->setCloseByOutsideClick(false); connect(box, &QObject::destroyed, [=] { crl::on_main(this, [=] { - if (AuthSession::Exists()) { - resetAuthorizationKeys(); - loggedOut(); - } + activeAccount().forcedLogOut(); }); }); } @@ -773,41 +480,6 @@ void Application::writeInstallBetaVersionsSetting() { _launcher->writeInstallBetaVersionsSetting(); } -void Application::authSessionCreate(const MTPUser &user) { - Expects(_mtproto != nullptr); - - _mtproto->setUpdatesHandler(::rpcDone([]( - const mtpPrime *from, - const mtpPrime *end) { - if (const auto main = App::main()) { - return main->updateReceived(from, end); - } - return true; - })); - _mtproto->setGlobalFailHandler(::rpcFail([=](const RPCError &error) { - if (activeAccount().sessionExists()) { - crl::on_main(&activeAccount().session(), [=] { logOut(); }); - } - return true; - })); - - activeAccount().createSession(user); -} - -void Application::authSessionDestroy() { - _private->storedAuthSession.reset(); - _private->authSessionUserId = 0; - _private->authSessionUserSerialized = {}; - if (activeAccount().sessionExists()) { - unlockTerms(); - _mtproto->clearGlobalHandlers(); - - activeAccount().destroySession(); - - Notify::unreadCounterUpdated(); - } -} - int Application::unreadBadge() const { return activeAccount().sessionExists() ? activeAccount().session().data().unreadBadge() @@ -897,7 +569,9 @@ void Application::lockByPasscode() { void Application::unlockPasscode() { clearPasscodeLock(); - _window->clearPasscodeLock(); + if (_window) { + _window->clearPasscodeLock(); + } } void Application::clearPasscodeLock() { @@ -1011,48 +685,6 @@ void Application::checkMediaViewActivation() { } } -void Application::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 Application::loggedOut() { - if (Global::LocalPasscode()) { - Global::SetLocalPasscode(false); - Global::RefLocalPasscodeChanged().notify(); - } - clearPasscodeLock(); - Media::Player::mixer()->stopAndClear(); - Global::SetVoiceMsgPlaybackDoubled(false); - if (const auto window = activeWindow()) { - window->tempDirDelete(Local::ClearManagerAll); - window->setupIntro(); - } - if (activeAccount().sessionExists()) { - activeAccount().session().data().clearLocalStorage(); - authSessionDestroy(); - } - if (_mediaView) { - hideMediaView(); - _mediaView->clearData(); - } - Local::reset(); - - cSetOtherOnline(0); - Images::ClearRemote(); -} - QPoint Application::getPointForCallPanelCenter() const { if (const auto window = activeWindow()) { return window->getPointForCallPanelCenter(); diff --git a/Telegram/SourceFiles/core/application.h b/Telegram/SourceFiles/core/application.h index dfa66803aa..a86b2b849e 100644 --- a/Telegram/SourceFiles/core/application.h +++ b/Telegram/SourceFiles/core/application.h @@ -120,34 +120,16 @@ public: MTP::DcOptions *dcOptions() { return _dcOptions.get(); } + struct ProxyChange { + ProxyData was; + ProxyData now; + }; void setCurrentProxy( const ProxyData &proxy, ProxyData::Settings settings); + [[nodiscard]] rpl::producer proxyChanges() const; void badMtprotoConfigurationError(); - // Set from legacy storage. - void setMtpMainDcId(MTP::DcId mainDcId); - void setMtpKey(MTP::DcId dcId, const MTP::AuthKey::Data &keyData); - void setAuthSessionUserId(UserId userId); - void setAuthSessionFromStorage( - std::unique_ptr data, - QByteArray &&selfSerialized, - int32 selfStreamVersion); - AuthSessionSettings *getAuthSessionSettings(); - - // Serialization. - QByteArray serializeMtpAuthorization() const; - void setMtpAuthorization(const QByteArray &serialized); - - void startMtp(); - MTP::Instance *mtp() { - return _mtproto.get(); - } - void suggestMainDcId(MTP::DcId mainDcId); - void destroyStaleAuthorizationKeys(); - void configUpdated(); - [[nodiscard]] rpl::producer<> configUpdates() const; - // Databases. Storage::Databases &databases() { return *_databases; @@ -159,10 +141,8 @@ public: } // AuthSession component. - void authSessionCreate(const MTPUser &user); int unreadBadge() const; bool unreadBadgeMuted() const; - void logOut(); // Media component. Media::Audio::Instance &audio() { @@ -244,9 +224,6 @@ private: friend bool IsAppLaunched(); friend Application &App(); - void destroyMtpKeys(MTP::AuthKeysList &&keys); - void allKeysDestroyed(); - void startLocalStorage(); void startShortcuts(); @@ -256,14 +233,20 @@ private: static void QuitAttempt(); void quitDelayed(); - void resetAuthorizationKeys(); - void authSessionDestroy(); void clearPasscodeLock(); - void loggedOut(); static Application *Instance; + struct InstanceSetter { + InstanceSetter(not_null instance) { + Expects(Instance == nullptr); + + Instance = instance; + } + }; + InstanceSetter _setter = { this }; not_null _launcher; + rpl::event_stream _proxyChanges; // Some fields are just moved from the declaration. struct Private; @@ -273,6 +256,7 @@ private: const std::unique_ptr _databases; const std::unique_ptr _animationsManager; + const std::unique_ptr _dcOptions; const std::unique_ptr _account; std::unique_ptr _window; std::unique_ptr _mediaView; @@ -280,10 +264,6 @@ private: std::unique_ptr _langCloudManager; const std::unique_ptr _emojiKeywords; std::unique_ptr _translator; - std::unique_ptr _dcOptions; - std::unique_ptr _mtproto; - std::unique_ptr _mtprotoForKeysDestroy; - rpl::event_stream<> _configUpdates; base::Observable _passcodedChanged; QPointer _badProxyDisableBox; diff --git a/Telegram/SourceFiles/core/update_checker.cpp b/Telegram/SourceFiles/core/update_checker.cpp index 800f7824cf..bff6dcd77d 100644 --- a/Telegram/SourceFiles/core/update_checker.cpp +++ b/Telegram/SourceFiles/core/update_checker.cpp @@ -13,8 +13,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "base/unixtime.h" #include "storage/localstorage.h" #include "core/application.h" -#include "mainwindow.h" #include "core/click_handler_types.h" +#include "mainwindow.h" +#include "main/main_account.h" #include "info/info_memento.h" #include "info/settings/info_settings_widget.h" #include "window/window_session_controller.h" @@ -1390,7 +1391,7 @@ Updater::~Updater() { UpdateChecker::UpdateChecker() : _updater(GetUpdaterInstance()) { if (IsAppLaunched()) { - if (const auto mtproto = Core::App().mtp()) { + if (const auto mtproto = Core::App().activeAccount().mtp()) { _updater->setMtproto(mtproto); } } diff --git a/Telegram/SourceFiles/data/data_folder.cpp b/Telegram/SourceFiles/data/data_folder.cpp index 5916cb2c65..7fb776e8d4 100644 --- a/Telegram/SourceFiles/data/data_folder.cpp +++ b/Telegram/SourceFiles/data/data_folder.cpp @@ -15,6 +15,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "lang/lang_keys.h" #include "storage/storage_facade.h" #include "core/application.h" +#include "main/main_account.h" //#include "storage/storage_feed_messages.h" // #feed #include "auth_session.h" #include "observer_peer.h" @@ -28,11 +29,12 @@ namespace { constexpr auto kLoadedChatsMinCount = 20; constexpr auto kShowChatNamesCount = 8; -rpl::producer PinnedDialogsInFolderMaxValue() { +rpl::producer PinnedDialogsInFolderMaxValue( + not_null session) { return rpl::single( rpl::empty_value() ) | rpl::then( - Core::App().configUpdates() + session->account().configUpdates() ) | rpl::map([=] { return Global::PinnedDialogsInFolderMax(); }); @@ -53,7 +55,7 @@ rpl::producer PinnedDialogsInFolderMaxValue() { Folder::Folder(not_null owner, FolderId id) : Entry(owner, this) , _id(id) -, _chatsList(PinnedDialogsInFolderMaxValue()) +, _chatsList(PinnedDialogsInFolderMaxValue(&owner->session())) , _name(tr::lng_archived_name(tr::now)) { indexNameParts(); diff --git a/Telegram/SourceFiles/data/data_session.cpp b/Telegram/SourceFiles/data/data_session.cpp index 61c7caf5dd..fec417e576 100644 --- a/Telegram/SourceFiles/data/data_session.cpp +++ b/Telegram/SourceFiles/data/data_session.cpp @@ -25,6 +25,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "inline_bots/inline_bot_layout_item.h" #include "storage/localstorage.h" #include "storage/storage_encrypted_file.h" +#include "main/main_account.h" #include "media/player/media_player_instance.h" // instance()->play() #include "media/streaming/media_streaming_loader.h" // unique_ptr #include "media/streaming/media_streaming_reader.h" // make_shared @@ -155,11 +156,12 @@ MTPPhotoSize FindDocumentThumbnail(const MTPDdocument &data) { : MTPPhotoSize(MTP_photoSizeEmpty(MTP_string())); } -rpl::producer PinnedDialogsCountMaxValue() { +rpl::producer PinnedDialogsCountMaxValue( + not_null session) { return rpl::single( rpl::empty_value() ) | rpl::then( - Core::App().configUpdates() + session->account().configUpdates() ) | rpl::map([=] { return Global::PinnedDialogsCountMax(); }); @@ -195,7 +197,7 @@ Session::Session(not_null session) , _bigFileCache(Core::App().databases().get( Local::cacheBigFilePath(), Local::cacheBigFileSettings())) -, _chatsList(PinnedDialogsCountMaxValue()) +, _chatsList(PinnedDialogsCountMaxValue(session)) , _contactsList(Dialogs::SortMode::Name) , _contactsNoChatsList(Dialogs::SortMode::Name) , _selfDestructTimer([=] { checkSelfDestructItems(); }) diff --git a/Telegram/SourceFiles/intro/introcode.cpp b/Telegram/SourceFiles/intro/introcode.cpp index 14731086d0..356f8ce7b9 100644 --- a/Telegram/SourceFiles/intro/introcode.cpp +++ b/Telegram/SourceFiles/intro/introcode.cpp @@ -73,7 +73,11 @@ void CodeInput::correctValue(const QString &was, int wasCursor, QString &now, in } } -CodeWidget::CodeWidget(QWidget *parent, Widget::Data *data) : Step(parent, data) +CodeWidget::CodeWidget( + QWidget *parent, + not_null account, + not_null data) +: Step(parent, account, data) , _noTelegramCode(this, tr::lng_code_no_telegram(tr::now), st::introLink) , _code(this, st::introCode, tr::lng_code_ph()) , _callTimer(this) @@ -244,7 +248,7 @@ void CodeWidget::codeSubmitDone(const MTPauth_Authorization &result) { } else { getData()->termsLock = Window::TermsLock(); } - goReplace(new Intro::SignupWidget(parentWidget(), getData())); + goReplace(); }); } @@ -342,7 +346,7 @@ void CodeWidget::gotPassword(const MTPaccount_Password &result) { getData()->hasRecovery = d.is_has_recovery(); getData()->pwdHint = qs(d.vhint().value_or_empty()); getData()->pwdNotEmptyPassport = d.is_has_secure_values(); - goReplace(new Intro::PwdCheckWidget(parentWidget(), getData())); + goReplace(); } void CodeWidget::submit() { diff --git a/Telegram/SourceFiles/intro/introcode.h b/Telegram/SourceFiles/intro/introcode.h index 2b8d99d74a..527715035d 100644 --- a/Telegram/SourceFiles/intro/introcode.h +++ b/Telegram/SourceFiles/intro/introcode.h @@ -39,7 +39,10 @@ class CodeWidget : public Widget::Step { Q_OBJECT public: - CodeWidget(QWidget *parent, Widget::Data *data); + CodeWidget( + QWidget *parent, + not_null account, + not_null data); bool hasBack() const override { return true; diff --git a/Telegram/SourceFiles/intro/introphone.cpp b/Telegram/SourceFiles/intro/introphone.cpp index 135681e9e1..8bd1716b7d 100644 --- a/Telegram/SourceFiles/intro/introphone.cpp +++ b/Telegram/SourceFiles/intro/introphone.cpp @@ -13,6 +13,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "ui/widgets/buttons.h" #include "ui/widgets/labels.h" #include "ui/wrap/fade_wrap.h" +#include "main/main_account.h" #include "boxes/confirm_phone_box.h" #include "boxes/confirm_box.h" #include "core/application.h" @@ -29,7 +30,11 @@ bool AllowPhoneAttempt(const QString &phone) { } // namespace -PhoneWidget::PhoneWidget(QWidget *parent, Widget::Data *data) : Step(parent, data) +PhoneWidget::PhoneWidget( + QWidget *parent, + not_null account, + not_null data) +: Step(parent, account, data) , _country(this, st::introCountry) , _code(this, st::introCountryCode) , _phone(this, st::introPhone) @@ -54,7 +59,7 @@ PhoneWidget::PhoneWidget(QWidget *parent, Widget::Data *data) : Step(parent, dat } _changed = false; - Core::App().destroyStaleAuthorizationKeys(); + account->destroyStaleAuthorizationKeys(); } void PhoneWidget::resizeEvent(QResizeEvent *e) { @@ -111,7 +116,7 @@ void PhoneWidget::submit() { _checkRequest->start(1000); _sentPhone = phone; - Core::App().mtp()->setUserPhone(_sentPhone); + account().mtp()->setUserPhone(_sentPhone); _sentRequest = MTP::send( MTPauth_SendCode( MTP_string(_sentPhone), @@ -162,7 +167,7 @@ void PhoneWidget::phoneSubmitDone(const MTPauth_SentCode &result) { getData()->callStatus = Widget::Data::CallStatus::Disabled; getData()->callTimeout = 0; } - goNext(new Intro::CodeWidget(parentWidget(), getData())); + goNext(); } bool PhoneWidget::phoneSubmitFail(const RPCError &error) { diff --git a/Telegram/SourceFiles/intro/introphone.h b/Telegram/SourceFiles/intro/introphone.h index 6dd6598b1e..60e706345e 100644 --- a/Telegram/SourceFiles/intro/introphone.h +++ b/Telegram/SourceFiles/intro/introphone.h @@ -23,7 +23,10 @@ class PhoneWidget : public Widget::Step { Q_OBJECT public: - PhoneWidget(QWidget *parent, Widget::Data *data); + PhoneWidget( + QWidget *parent, + not_null account, + not_null data); void selectCountry(const QString &country); diff --git a/Telegram/SourceFiles/intro/intropwdcheck.cpp b/Telegram/SourceFiles/intro/intropwdcheck.cpp index 94ee2c3aee..f6d1728a63 100644 --- a/Telegram/SourceFiles/intro/intropwdcheck.cpp +++ b/Telegram/SourceFiles/intro/intropwdcheck.cpp @@ -23,8 +23,9 @@ namespace Intro { PwdCheckWidget::PwdCheckWidget( QWidget *parent, - Widget::Data *data) -: Step(parent, data) + not_null account, + not_null data) +: Step(parent, account, data) , _request(getData()->pwdRequest) , _hasRecovery(getData()->hasRecovery) , _notEmptyPassport(getData()->pwdNotEmptyPassport) diff --git a/Telegram/SourceFiles/intro/intropwdcheck.h b/Telegram/SourceFiles/intro/intropwdcheck.h index 0036d6f9a2..a0fc7b5558 100644 --- a/Telegram/SourceFiles/intro/intropwdcheck.h +++ b/Telegram/SourceFiles/intro/intropwdcheck.h @@ -23,7 +23,10 @@ class PwdCheckWidget : public Widget::Step, private MTP::Sender { Q_OBJECT public: - PwdCheckWidget(QWidget *parent, Widget::Data *data); + PwdCheckWidget( + QWidget *parent, + not_null account, + not_null data); void setInnerFocus() override; void activate() override; diff --git a/Telegram/SourceFiles/intro/introsignup.cpp b/Telegram/SourceFiles/intro/introsignup.cpp index c09e15e8d3..01d71d369d 100644 --- a/Telegram/SourceFiles/intro/introsignup.cpp +++ b/Telegram/SourceFiles/intro/introsignup.cpp @@ -20,7 +20,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL namespace Intro { -SignupWidget::SignupWidget(QWidget *parent, Widget::Data *data) : Step(parent, data) +SignupWidget::SignupWidget( + QWidget *parent, + not_null account, + not_null data) +: Step(parent, account, data) , _photo( this, tr::lng_settings_crop_profile(tr::now), diff --git a/Telegram/SourceFiles/intro/introsignup.h b/Telegram/SourceFiles/intro/introsignup.h index ee5b9a1418..7eadd5ae85 100644 --- a/Telegram/SourceFiles/intro/introsignup.h +++ b/Telegram/SourceFiles/intro/introsignup.h @@ -21,7 +21,10 @@ class SignupWidget : public Widget::Step { Q_OBJECT public: - SignupWidget(QWidget *parent, Widget::Data *data); + SignupWidget( + QWidget *parent, + not_null account, + not_null data); void finishInit() override; void setInnerFocus() override; diff --git a/Telegram/SourceFiles/intro/introstart.cpp b/Telegram/SourceFiles/intro/introstart.cpp index 9822f3678a..8ee0b1e5ce 100644 --- a/Telegram/SourceFiles/intro/introstart.cpp +++ b/Telegram/SourceFiles/intro/introstart.cpp @@ -14,7 +14,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL namespace Intro { -StartWidget::StartWidget(QWidget *parent, Widget::Data *data) : Step(parent, data, true) { +StartWidget::StartWidget( + QWidget *parent, + not_null account, + not_null data) +: Step(parent, account, data, true) { setMouseTracking(true); setTitleText(rpl::single(qsl("Telegram Desktop"))); setDescriptionText(tr::lng_intro_about()); @@ -22,7 +26,7 @@ StartWidget::StartWidget(QWidget *parent, Widget::Data *data) : Step(parent, dat } void StartWidget::submit() { - goNext(new Intro::PhoneWidget(parentWidget(), getData())); + goNext(); } rpl::producer StartWidget::nextButtonText() const { diff --git a/Telegram/SourceFiles/intro/introstart.h b/Telegram/SourceFiles/intro/introstart.h index 1a0489151e..9f7048f6f6 100644 --- a/Telegram/SourceFiles/intro/introstart.h +++ b/Telegram/SourceFiles/intro/introstart.h @@ -19,7 +19,10 @@ namespace Intro { class StartWidget : public Widget::Step { public: - StartWidget(QWidget *parent, Widget::Data *data); + StartWidget( + QWidget *parent, + not_null account, + not_null data); void submit() override; rpl::producer nextButtonText() const override; diff --git a/Telegram/SourceFiles/intro/introwidget.cpp b/Telegram/SourceFiles/intro/introwidget.cpp index 5136a888e7..1567ee5652 100644 --- a/Telegram/SourceFiles/intro/introwidget.cpp +++ b/Telegram/SourceFiles/intro/introwidget.cpp @@ -15,6 +15,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "intro/introcode.h" #include "intro/introsignup.h" #include "intro/intropwdcheck.h" +#include "main/main_account.h" #include "mainwidget.h" #include "apiwrap.h" #include "mainwindow.h" @@ -59,7 +60,9 @@ void PrepareSupportMode() { } // namespace -Widget::Widget(QWidget *parent) : RpWidget(parent) +Widget::Widget(QWidget *parent, not_null account) +: RpWidget(parent) +, _account(account) , _back(this, object_ptr(this, st::introBackButton)) , _settings( this, @@ -84,7 +87,7 @@ Widget::Widget(QWidget *parent) : RpWidget(parent) getNearestDC(); setupConnectingWidget(); - appendStep(new StartWidget(this, getData())); + appendStep(new StartWidget(this, _account, getData())); fixOrder(); subscribe(Lang::CurrentCloudManager().firstLanguageSuggestion(), [this] { createLanguageLink(); }); @@ -367,11 +370,13 @@ void Widget::resetAccount() { _resetRequest = 0; Ui::hideLayer(); - moveToStep(new SignupWidget(this, getData()), Direction::Replace); + moveToStep( + new SignupWidget(this, _account, getData()), + Direction::Replace); }).fail([this](const RPCError &error) { _resetRequest = 0; - auto type = error.type(); + const auto &type = error.type(); if (type.startsWith(qstr("2FA_CONFIRM_WAIT_"))) { const auto seconds = type.mid(qstr("2FA_CONFIRM_WAIT_").size()).toInt(); const auto days = (seconds + 59) / 86400; @@ -434,7 +439,7 @@ void Widget::getNearestDC() { ).arg(qs(nearest.vcountry()) ).arg(nearest.vnearest_dc().v ).arg(nearest.vthis_dc().v)); - Core::App().suggestMainDcId(nearest.vnearest_dc().v); + _account->suggestMainDcId(nearest.vnearest_dc().v); auto nearestCountry = qs(nearest.vcountry()); if (getData()->country != nearestCountry) { getData()->country = nearestCountry; @@ -664,16 +669,19 @@ void Widget::Step::finish(const MTPUser &user, QImage &&photo) { Local::writeLangPack(); } - Core::App().authSessionCreate(user); + const auto account = _account; + const auto weak = base::make_weak(account.get()); + account->createSession(user); Local::writeMtpData(); App::wnd()->setupMain(); // "this" is already deleted here by creating the main widget. - if (AuthSession::Exists()) { + if (weak && account->sessionExists()) { + auto &session = account->session(); if (!photo.isNull()) { - Auth().api().uploadPeerPhoto(Auth().user(), std::move(photo)); + session.api().uploadPeerPhoto(session.user(), std::move(photo)); } - if (Auth().supportMode()) { + if (session.supportMode()) { PrepareSupportMode(); } } @@ -919,8 +927,13 @@ void Widget::Step::refreshError(const QString &text) { } } -Widget::Step::Step(QWidget *parent, Data *data, bool hasCover) +Widget::Step::Step( + QWidget *parent, + not_null account, + not_null data, + bool hasCover) : RpWidget(parent) +, _account(account) , _data(data) , _hasCover(hasCover) , _title(this, _hasCover ? st::introCoverTitle : st::introTitle) diff --git a/Telegram/SourceFiles/intro/introwidget.h b/Telegram/SourceFiles/intro/introwidget.h index ab051829d1..58d49d524f 100644 --- a/Telegram/SourceFiles/intro/introwidget.h +++ b/Telegram/SourceFiles/intro/introwidget.h @@ -13,6 +13,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "window/window_lock_widgets.h" #include "core/core_cloud_password.h" +namespace Main { +class Account; +} // namespace Main + namespace Ui { class IconButton; class RoundButton; @@ -34,7 +38,7 @@ class Widget : public Ui::RpWidget, private MTP::Sender, private base::Subscribe Q_OBJECT public: - Widget(QWidget *parent); + Widget(QWidget *parent, not_null account); void showAnimated(const QPixmap &bgAnimCache, bool back = false); @@ -90,7 +94,15 @@ public: }; class Step : public Ui::RpWidget, public RPCSender, protected base::Subscriber { public: - Step(QWidget *parent, Data *data, bool hasCover = false); + Step( + QWidget *parent, + not_null account, + not_null data, + bool hasCover = false); + + Main::Account &account() const { + return *_account; + } virtual void finishInit() { } @@ -147,19 +159,33 @@ public: void showDescription(); void hideDescription(); - Data *getData() const { + not_null getData() const { return _data; } void finish(const MTPUser &user, QImage &&photo = QImage()); void goBack() { - if (_goCallback) _goCallback(nullptr, Direction::Back); + if (_goCallback) { + _goCallback(nullptr, Direction::Back); + } } - void goNext(Step *step) { - if (_goCallback) _goCallback(step, Direction::Forward); + + template + void goNext() { + if (_goCallback) { + _goCallback( + new StepType(parentWidget(), _account, _data), + Direction::Forward); + } } - void goReplace(Step *step) { - if (_goCallback) _goCallback(step, Direction::Replace); + + template + void goReplace() { + if (_goCallback) { + _goCallback( + new StepType(parentWidget(), _account, _data), + Direction::Replace); + } } void showResetButton() { if (_showResetCallback) _showResetCallback(); @@ -190,9 +216,6 @@ public: void updateLabelsPosition(); void paintContentSnapshot(Painter &p, const QPixmap &snapshot, float64 alpha, float64 howMuchHidden); void refreshError(const QString &text); - void refreshTitle(); - void refreshDescription(); - void refreshLang(); CoverAnimation prepareCoverAnimation(Step *step); QPixmap prepareContentSnapshot(); @@ -202,7 +225,9 @@ public: void prepareCoverMask(); void paintCover(Painter &p, int top); - Data *_data = nullptr; + const not_null _account; + const not_null _data; + bool _hasCover = false; Fn _goCallback; Fn _showResetCallback; @@ -233,7 +258,7 @@ private: void createLanguageLink(); void updateControlsGeometry(); - Data *getData() { + not_null getData() { return &_data; } @@ -260,6 +285,8 @@ private: void getNearestDC(); void showTerms(Fn callback); + not_null _account; + Ui::Animations::Simple _a_show; bool _showBack = false; QPixmap _cacheUnder, _cacheOver; diff --git a/Telegram/SourceFiles/main/main_account.cpp b/Telegram/SourceFiles/main/main_account.cpp index 6bb88b3e59..79aaa775b3 100644 --- a/Telegram/SourceFiles/main/main_account.cpp +++ b/Telegram/SourceFiles/main/main_account.cpp @@ -7,28 +7,113 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #include "main/main_account.h" -#include "auth_session.h" #include "core/application.h" +#include "core/launcher.h" +#include "core/shortcuts.h" +#include "storage/serialize_common.h" +#include "storage/localstorage.h" +#include "data/data_session.h" +#include "data/data_user.h" +#include "window/window_controller.h" +#include "media/audio/media_audio.h" +#include "mainwidget.h" +#include "observer_peer.h" +#include "auth_session.h" namespace Main { Account::Account(const QString &dataName) { + watchProxyChanges(); + watchSessionChanges(); } -Account::~Account() { +Account::~Account() = default; + +void Account::watchProxyChanges() { + using ProxyChange = Core::Application::ProxyChange; + + Core::App().proxyChanges( + ) | rpl::start_with_next([=](const ProxyChange &change) { + const auto key = [&](const ProxyData &proxy) { + return (proxy.type == ProxyData::Type::Mtproto) + ? std::make_pair(proxy.host, proxy.port) + : std::make_pair(QString(), uint32(0)); + }; + if (_mtp) { + _mtp->restart(); + if (key(change.was) != key(change.now)) { + _mtp->reInitConnection(_mtp->mainDcId()); + } + } + if (_mtpForKeysDestroy) { + _mtpForKeysDestroy->restart(); + } + }, _lifetime); +} + +void Account::watchSessionChanges() { + sessionChanges( + ) | rpl::start_with_next([=] { + crl::on_main(this, [=] { + const auto phone = sessionExists() + ? session().user()->phone() + : QString(); + const auto support = sessionExists() && session().supportMode(); + if (cLoggedPhoneNumber() != phone) { + cSetLoggedPhoneNumber(phone); + if (_mtp) { + _mtp->setUserPhone(phone); + } + Local::writeSettings(); + } + if (_mtp) { + _mtp->requestConfig(); + } + Shortcuts::ToggleSupportShortcuts(support); + Platform::SetApplicationIcon(Window::CreateIcon(this)); + }); + }, _lifetime); } void Account::createSession(const MTPUser &user) { + Expects(_mtp != nullptr); Expects(_session == nullptr); Expects(_sessionValue.current() == nullptr); + _mtp->setUpdatesHandler(::rpcDone([]( + const mtpPrime *from, + const mtpPrime *end) { + if (const auto main = App::main()) { + return main->updateReceived(from, end); + } + return true; + })); + _mtp->setGlobalFailHandler(::rpcFail([=](const RPCError &error) { + if (sessionExists()) { + crl::on_main(&session(), [=] { logOut(); }); + } + return true; + })); + _session = std::make_unique(this, user); _sessionValue = _session.get(); } void Account::destroySession() { + _storedAuthSession.reset(); + _authSessionUserId = 0; + _authSessionUserSerialized = {}; + if (!sessionExists()) { + return; + } + session().data().clearLocalStorage(); + + _mtp->clearGlobalHandlers(); + _sessionValue = nullptr; _session = nullptr; + + Notify::unreadCounterUpdated(); } bool Account::sessionExists() const { @@ -41,6 +126,12 @@ AuthSession &Account::session() { return *_sessionValue.current(); } +const AuthSession &Account::session() const { + Expects(sessionExists()); + + return *_sessionValue.current(); +} + rpl::producer Account::sessionValue() const { return _sessionValue.value(); } @@ -49,8 +140,343 @@ rpl::producer Account::sessionChanges() const { return _sessionValue.changes(); } -MTP::Instance *Account::mtp() { - return MTP::MainInstance(); +rpl::producer Account::mtpValue() const { + return _mtpValue.value(); +} + +rpl::producer Account::mtpChanges() const { + return _mtpValue.changes(); +} + +void Account::setMtpMainDcId(MTP::DcId mainDcId) { + Expects(!_mtp); + + _mtpConfig.mainDcId = mainDcId; +} + +void Account::setMtpKey(MTP::DcId dcId, const MTP::AuthKey::Data &keyData) { + Expects(!_mtp); + + _mtpConfig.keys.push_back(std::make_shared( + MTP::AuthKey::Type::ReadFromFile, + dcId, + keyData)); +} + +QByteArray Account::serializeMtpAuthorization() const { + const auto serialize = [&]( + MTP::DcId mainDcId, + const MTP::AuthKeysList &keys, + const MTP::AuthKeysList &keysToDestroy) { + const auto keysSize = [](auto &list) { + const auto keyDataSize = MTP::AuthKey::Data().size(); + return sizeof(qint32) + + list.size() * (sizeof(qint32) + keyDataSize); + }; + const auto writeKeys = []( + QDataStream &stream, + const MTP::AuthKeysList &keys) { + stream << qint32(keys.size()); + for (const auto &key : keys) { + stream << qint32(key->dcId()); + key->write(stream); + } + }; + + auto result = QByteArray(); + auto size = sizeof(qint32) + sizeof(qint32); // userId + mainDcId + size += keysSize(keys) + keysSize(keysToDestroy); + result.reserve(size); + { + QDataStream stream(&result, QIODevice::WriteOnly); + stream.setVersion(QDataStream::Qt_5_1); + + const auto currentUserId = sessionExists() + ? session().userId() + : 0; + stream << qint32(currentUserId) << qint32(mainDcId); + writeKeys(stream, keys); + writeKeys(stream, keysToDestroy); + + DEBUG_LOG(("MTP Info: Keys written, userId: %1, dcId: %2").arg(currentUserId).arg(mainDcId)); + } + return result; + }; + if (_mtp) { + const auto keys = _mtp->getKeysForWrite(); + const auto keysToDestroy = _mtpForKeysDestroy + ? _mtpForKeysDestroy->getKeysForWrite() + : MTP::AuthKeysList(); + return serialize(_mtp->mainDcId(), keys, keysToDestroy); + } + const auto &keys = _mtpConfig.keys; + const auto &keysToDestroy = _mtpKeysToDestroy; + return serialize(_mtpConfig.mainDcId, keys, keysToDestroy); +} + +void Account::setAuthSessionUserId(UserId userId) { + Expects(!sessionExists()); + + _authSessionUserId = userId; +} + +void Account::setAuthSessionFromStorage( + std::unique_ptr data, + QByteArray &&selfSerialized, + int32 selfStreamVersion) { + Expects(!sessionExists()); + + DEBUG_LOG(("authSessionUserSerialized set: %1" + ).arg(selfSerialized.size())); + + _storedAuthSession = std::move(data); + _authSessionUserSerialized = std::move(selfSerialized); + _authSessionUserStreamVersion = selfStreamVersion; +} + +AuthSessionSettings *Account::getAuthSessionSettings() { + if (_authSessionUserId) { + return _storedAuthSession ? _storedAuthSession.get() : nullptr; + } else if (sessionExists()) { + return &session().settings(); + } + return nullptr; +} + +void Account::setMtpAuthorization(const QByteArray &serialized) { + Expects(!_mtp); + + QDataStream stream(serialized); + stream.setVersion(QDataStream::Qt_5_1); + + auto userId = Serialize::read(stream); + auto mainDcId = Serialize::read(stream); + if (stream.status() != QDataStream::Ok) { + LOG(("MTP Error: " + "Could not read main fields from mtp authorization.")); + return; + } + + setAuthSessionUserId(userId); + _mtpConfig.mainDcId = mainDcId; + + const auto readKeys = [&stream](auto &keys) { + const auto count = Serialize::read(stream); + if (stream.status() != QDataStream::Ok) { + LOG(("MTP Error: " + "Could not read keys count from mtp authorization.")); + return; + } + keys.reserve(count); + for (auto i = 0; i != count; ++i) { + const auto dcId = Serialize::read(stream); + const auto keyData = Serialize::read(stream); + if (stream.status() != QDataStream::Ok) { + LOG(("MTP Error: " + "Could not read key from mtp authorization.")); + return; + } + keys.push_back(std::make_shared(MTP::AuthKey::Type::ReadFromFile, dcId, keyData)); + } + }; + readKeys(_mtpConfig.keys); + readKeys(_mtpKeysToDestroy); + LOG(("MTP Info: " + "read keys, current: %1, to destroy: %2" + ).arg(_mtpConfig.keys.size() + ).arg(_mtpKeysToDestroy.size())); +} + +void Account::startMtp() { + Expects(!_mtp); + + auto config = base::take(_mtpConfig); + config.deviceModel = Core::App().launcher()->deviceModel(); + config.systemVersion = Core::App().launcher()->systemVersion(); + _mtp = std::make_unique( + Core::App().dcOptions(), + MTP::Instance::Mode::Normal, + std::move(config)); + _mtp->setUserPhone(cLoggedPhoneNumber()); + _mtpConfig.mainDcId = _mtp->mainDcId(); + + _mtp->setStateChangedHandler([](MTP::ShiftedDcId dc, int32 state) { + if (dc == MTP::maindc()) { + Global::RefConnectionTypeChanged().notify(); + } + }); + _mtp->setSessionResetHandler([](MTP::ShiftedDcId shiftedDcId) { + if (App::main() && shiftedDcId == MTP::maindc()) { + App::main()->getDifference(); + } + }); + + if (!_mtpKeysToDestroy.empty()) { + destroyMtpKeys(base::take(_mtpKeysToDestroy)); + } + + if (_authSessionUserId) { + DEBUG_LOG(("authSessionUserSerialized.size: %1" + ).arg(_authSessionUserSerialized.size())); + QDataStream peekStream(_authSessionUserSerialized); + const auto phone = Serialize::peekUserPhone( + _authSessionUserStreamVersion, + peekStream); + const auto flags = MTPDuser::Flag::f_self | (phone.isEmpty() + ? MTPDuser::Flag() + : MTPDuser::Flag::f_phone); + createSession(MTP_user( + MTP_flags(flags), + MTP_int(base::take(_authSessionUserId)), + MTPlong(), // access_hash + MTPstring(), // first_name + MTPstring(), // last_name + MTPstring(), // username + MTP_string(phone), + MTPUserProfilePhoto(), + MTPUserStatus(), + MTPint(), // bot_info_version + MTPstring(), // restriction_reason + MTPstring(), // bot_inline_placeholder + MTPstring())); // lang_code + Local::readSelf( + base::take(_authSessionUserSerialized), + base::take(_authSessionUserStreamVersion)); + } + if (_storedAuthSession) { + if (sessionExists()) { + session().moveSettingsFrom(std::move(*_storedAuthSession)); + } + _storedAuthSession.reset(); + } + + if (sessionExists()) { + // Skip all pending self updates so that we won't Local::writeSelf. + Notify::peerUpdatedSendDelayed(); + } + + _mtpValue = _mtp.get(); +} + + +void Account::logOut() { + if (_mtp) { + _mtp->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 Account::forcedLogOut() { + if (sessionExists()) { + resetAuthorizationKeys(); + loggedOut(); + } +} + +void Account::loggedOut() { + if (Global::LocalPasscode()) { + Global::SetLocalPasscode(false); + Global::RefLocalPasscodeChanged().notify(); + } + Core::App().unlockPasscode(); + Core::App().unlockTerms(); + Media::Player::mixer()->stopAndClear(); + Global::SetVoiceMsgPlaybackDoubled(false); + if (const auto window = Core::App().activeWindow()) { + window->tempDirDelete(Local::ClearManagerAll); + window->setupIntro(); + } + destroySession(); + Local::reset(); + + cSetOtherOnline(0); + Images::ClearRemote(); +} + +void Account::destroyMtpKeys(MTP::AuthKeysList &&keys) { + if (keys.empty()) { + return; + } + if (_mtpForKeysDestroy) { + _mtpForKeysDestroy->addKeysForDestroy(std::move(keys)); + Local::writeMtpData(); + return; + } + auto destroyConfig = MTP::Instance::Config(); + destroyConfig.mainDcId = MTP::Instance::Config::kNoneMainDc; + destroyConfig.keys = std::move(keys); + destroyConfig.deviceModel = Core::App().launcher()->deviceModel(); + destroyConfig.systemVersion = Core::App().launcher()->systemVersion(); + _mtpForKeysDestroy = std::make_unique( + Core::App().dcOptions(), + MTP::Instance::Mode::KeysDestroyer, + std::move(destroyConfig)); + QObject::connect( + _mtpForKeysDestroy.get(), + &MTP::Instance::allKeysDestroyed, + [=] { allKeysDestroyed(); }); +} + +void Account::allKeysDestroyed() { + LOG(("MTP Info: all keys scheduled for destroy are destroyed.")); + crl::on_main(this, [=] { + _mtpForKeysDestroy = nullptr; + Local::writeMtpData(); + }); +} + +void Account::suggestMainDcId(MTP::DcId mainDcId) { + Expects(_mtp != nullptr); + + _mtp->suggestMainDcId(mainDcId); + if (_mtpConfig.mainDcId != MTP::Instance::Config::kNotSetMainDc) { + _mtpConfig.mainDcId = mainDcId; + } +} + +void Account::destroyStaleAuthorizationKeys() { + Expects(_mtp != nullptr); + + for (const auto &key : _mtp->getKeysForWrite()) { + // Disable this for now. + if (key->type() == MTP::AuthKey::Type::ReadFromFile) { + _mtpKeysToDestroy = _mtp->getKeysForWrite(); + LOG(("MTP Info: destroying stale keys, count: %1" + ).arg(_mtpKeysToDestroy.size())); + resetAuthorizationKeys(); + return; + } + } +} + +void Account::configUpdated() { + _configUpdates.fire({}); +} + +rpl::producer<> Account::configUpdates() const { + return _configUpdates.events(); +} + +void Account::resetAuthorizationKeys() { + _mtp = nullptr; + _mtpValue = _mtp.get(); + startMtp(); + Local::writeMtpData(); +} + +void Account::clearMtp() { + _mtp = nullptr; + _mtpForKeysDestroy = nullptr; + _mtpValue = _mtp.get(); } } // namespace Main diff --git a/Telegram/SourceFiles/main/main_account.h b/Telegram/SourceFiles/main/main_account.h index 2e02813f15..2c98d07032 100644 --- a/Telegram/SourceFiles/main/main_account.h +++ b/Telegram/SourceFiles/main/main_account.h @@ -7,11 +7,15 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #pragma once +#include "mtproto/auth_key.h" +#include "base/weak_ptr.h" + class AuthSession; +class AuthSessionSettings; namespace Main { -class Account final { +class Account final : public base::has_weak_ptr { public: explicit Account(const QString &dataName); ~Account(); @@ -22,17 +26,69 @@ public: void createSession(const MTPUser &user); void destroySession(); + void logOut(); + void forcedLogOut(); + [[nodiscard]] bool sessionExists() const; [[nodiscard]] AuthSession &session(); + [[nodiscard]] const AuthSession &session() const; [[nodiscard]] rpl::producer sessionValue() const; [[nodiscard]] rpl::producer sessionChanges() const; - [[nodiscard]] MTP::Instance *mtp(); + [[nodiscard]] MTP::Instance *mtp() { + return _mtp.get(); + } + [[nodiscard]] rpl::producer mtpValue() const; + [[nodiscard]] rpl::producer mtpChanges() const; + + // Set from legacy storage. + void setMtpMainDcId(MTP::DcId mainDcId); + void setMtpKey(MTP::DcId dcId, const MTP::AuthKey::Data &keyData); + void setAuthSessionUserId(UserId userId); + void setAuthSessionFromStorage( + std::unique_ptr data, + QByteArray &&selfSerialized, + int32 selfStreamVersion); + [[nodiscard]] AuthSessionSettings *getAuthSessionSettings(); + + // Serialization. + [[nodiscard]] QByteArray serializeMtpAuthorization() const; + void setMtpAuthorization(const QByteArray &serialized); + + void startMtp(); + void suggestMainDcId(MTP::DcId mainDcId); + void destroyStaleAuthorizationKeys(); + void configUpdated(); + [[nodiscard]] rpl::producer<> configUpdates() const; + void clearMtp(); private: + void watchProxyChanges(); + void watchSessionChanges(); + + void destroyMtpKeys(MTP::AuthKeysList &&keys); + void allKeysDestroyed(); + void resetAuthorizationKeys(); + + void loggedOut(); + + std::unique_ptr _mtp; + rpl::variable _mtpValue; + std::unique_ptr _mtpForKeysDestroy; + rpl::event_stream<> _configUpdates; + std::unique_ptr _session; rpl::variable _sessionValue; + UserId _authSessionUserId = 0; + QByteArray _authSessionUserSerialized; + int32 _authSessionUserStreamVersion = 0; + std::unique_ptr _storedAuthSession; + MTP::Instance::Config _mtpConfig; + MTP::AuthKeysList _mtpKeysToDestroy; + + rpl::lifetime _lifetime; + }; } // namespace Main diff --git a/Telegram/SourceFiles/mainwidget.cpp b/Telegram/SourceFiles/mainwidget.cpp index 26f19fd4b4..47f11df2cb 100644 --- a/Telegram/SourceFiles/mainwidget.cpp +++ b/Telegram/SourceFiles/mainwidget.cpp @@ -4244,7 +4244,7 @@ void MainWidget::feedUpdate(const MTPUpdate &update) { } break; case mtpc_updateConfig: { - Core::App().mtp()->requestConfig(); + session().mtp()->requestConfig(); } break; case mtpc_updateUserPhone: { diff --git a/Telegram/SourceFiles/mainwindow.cpp b/Telegram/SourceFiles/mainwindow.cpp index 481a7912f3..6e30495367 100644 --- a/Telegram/SourceFiles/mainwindow.cpp +++ b/Telegram/SourceFiles/mainwindow.cpp @@ -200,7 +200,7 @@ void MainWindow::clearPasscodeLock() { _main->showAnimated(bg, true); Core::App().checkStartUrl(); } else { - Core::App().startMtp(); + account().startMtp(); if (account().sessionExists()) { setupMain(); } else { @@ -216,7 +216,7 @@ void MainWindow::setupIntro() { auto bg = animated ? grabInner() : QPixmap(); clearWidgets(); - _intro.create(bodyWidget()); + _intro.create(bodyWidget(), &account()); updateControlsGeometry(); if (animated) { @@ -619,16 +619,15 @@ void MainWindow::onLogout() { showFromTray(); } - const auto logout = [] { - Core::App().logOut(); - }; const auto callback = [=] { if (account().sessionExists() && account().session().data().exportInProgress()) { Ui::hideLayer(); - account().session().data().stopExportWithConfirmation(logout); + account().session().data().stopExportWithConfirmation([=] { + account().logOut(); + }); } else { - logout(); + account().logOut(); } }; Ui::show(Box( diff --git a/Telegram/SourceFiles/mtproto/dc_options.cpp b/Telegram/SourceFiles/mtproto/dc_options.cpp index 992482f748..4dda904163 100644 --- a/Telegram/SourceFiles/mtproto/dc_options.cpp +++ b/Telegram/SourceFiles/mtproto/dc_options.cpp @@ -88,6 +88,10 @@ private: }; +DcOptions::DcOptions() { + constructFromBuiltIn(); +} + bool DcOptions::ValidateSecret(bytes::const_span secret) { // See also TcpConnection::Protocol::Create. return (secret.size() >= 21 && secret[0] == bytes::type(0xEE)) diff --git a/Telegram/SourceFiles/mtproto/dc_options.h b/Telegram/SourceFiles/mtproto/dc_options.h index 288822d337..cbd20d68ad 100644 --- a/Telegram/SourceFiles/mtproto/dc_options.h +++ b/Telegram/SourceFiles/mtproto/dc_options.h @@ -48,6 +48,8 @@ public: }; + DcOptions(); + [[nodiscard]] static bool ValidateSecret(bytes::const_span secret); // construct methods don't notify "changed" subscribers. diff --git a/Telegram/SourceFiles/mtproto/facade.cpp b/Telegram/SourceFiles/mtproto/facade.cpp index 6f1f0ec48f..920a2c723e 100644 --- a/Telegram/SourceFiles/mtproto/facade.cpp +++ b/Telegram/SourceFiles/mtproto/facade.cpp @@ -9,6 +9,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "storage/localstorage.h" #include "core/application.h" +#include "main/main_account.h" namespace MTP { namespace internal { @@ -38,7 +39,9 @@ void unpause() { } // namespace internal Instance *MainInstance() { - return Core::IsAppLaunched() ? Core::App().mtp() : nullptr; + return Core::IsAppLaunched() + ? Core::App().activeAccount().mtp() + : nullptr; } } // namespace MTP diff --git a/Telegram/SourceFiles/mtproto/mtp_instance.cpp b/Telegram/SourceFiles/mtproto/mtp_instance.cpp index 7a2c7fe15f..496fe72284 100644 --- a/Telegram/SourceFiles/mtproto/mtp_instance.cpp +++ b/Telegram/SourceFiles/mtproto/mtp_instance.cpp @@ -17,6 +17,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "mtproto/rsa_public_key.h" #include "storage/localstorage.h" #include "calls/calls_instance.h" +#include "main/main_account.h" #include "auth_session.h" #include "apiwrap.h" #include "core/application.h" @@ -167,9 +168,9 @@ private: void checkDelayedRequests(); - not_null _instance; - not_null _dcOptions; - Instance::Mode _mode = Instance::Mode::Normal; + const not_null _instance; + const not_null _dcOptions; + const Instance::Mode _mode = Instance::Mode::Normal; DcId _mainDcId = Config::kDefaultMainDc; bool _mainDcIdForced = false; @@ -808,7 +809,7 @@ void Instance::Private::configLoadDone(const MTPConfig &result) { data.vlang_pack_version().value_or_empty(), data.vbase_lang_pack_version().value_or_empty()); - Core::App().configUpdated(); + Core::App().activeAccount().configUpdated(); if (const auto prefix = data.vautoupdate_url_prefix()) { Local::writeAutoupdatePrefix(qs(*prefix)); diff --git a/Telegram/SourceFiles/settings/settings_codes.cpp b/Telegram/SourceFiles/settings/settings_codes.cpp index 49df1059f3..2220cd8878 100644 --- a/Telegram/SourceFiles/settings/settings_codes.cpp +++ b/Telegram/SourceFiles/settings/settings_codes.cpp @@ -108,7 +108,7 @@ auto GenerateCodes() { codes.emplace(qsl("endpoints"), [] { FileDialog::GetOpenPath(Core::App().getFileDialogParent(), "Open DC endpoints", "DC Endpoints (*.tdesktop-endpoints)", [](const FileDialog::OpenResult &result) { if (!result.paths.isEmpty()) { - if (!Core::App().mtp()->dcOptions()->loadFromFile(result.paths.front())) { + if (!Core::App().dcOptions()->loadFromFile(result.paths.front())) { Ui::show(Box("Could not load endpoints :( Errors in 'log.txt'.")); } } diff --git a/Telegram/SourceFiles/storage/localstorage.cpp b/Telegram/SourceFiles/storage/localstorage.cpp index 9d00f3c769..5d6f025615 100644 --- a/Telegram/SourceFiles/storage/localstorage.cpp +++ b/Telegram/SourceFiles/storage/localstorage.cpp @@ -26,6 +26,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "mainwindow.h" #include "lang/lang_keys.h" #include "lang/lang_cloud_manager.h" +#include "main/main_account.h" #include "media/audio/media_audio.h" #include "mtproto/dc_options.h" #include "core/application.h" @@ -972,8 +973,8 @@ bool _readSetting(quint32 blockId, QDataStream &stream, int version, ReadSetting if (!_checkStreamStatus(stream)) return false; DEBUG_LOG(("MTP Info: user found, dc %1, uid %2").arg(dcId).arg(userId)); - Core::App().setMtpMainDcId(dcId); - Core::App().setAuthSessionUserId(userId); + Core::App().activeAccount().setMtpMainDcId(dcId); + Core::App().activeAccount().setAuthSessionUserId(userId); } break; case dbiKey: { @@ -982,7 +983,7 @@ bool _readSetting(quint32 blockId, QDataStream &stream, int version, ReadSetting auto key = Serialize::read(stream); if (!_checkStreamStatus(stream)) return false; - Core::App().setMtpKey(dcId, key); + Core::App().activeAccount().setMtpKey(dcId, key); } break; case dbiMtpAuthorization: { @@ -990,7 +991,7 @@ bool _readSetting(quint32 blockId, QDataStream &stream, int version, ReadSetting stream >> serialized; if (!_checkStreamStatus(stream)) return false; - Core::App().setMtpAuthorization(serialized); + Core::App().activeAccount().setMtpAuthorization(serialized); } break; case dbiAutoStart: { @@ -2034,7 +2035,7 @@ void _writeUserSettings() { } auto userDataInstance = StoredAuthSessionCache ? StoredAuthSessionCache.get() - : Core::App().getAuthSessionSettings(); + : Core::App().activeAccount().getAuthSessionSettings(); auto userData = userDataInstance ? userDataInstance->serialize() : QByteArray(); @@ -2157,7 +2158,7 @@ void _writeMtpData() { return; } - auto mtpAuthorizationSerialized = Core::App().serializeMtpAuthorization(); + auto mtpAuthorizationSerialized = Core::App().activeAccount().serializeMtpAuthorization(); quint32 size = sizeof(quint32) + Serialize::bytearraySize(mtpAuthorizationSerialized); @@ -2388,7 +2389,7 @@ ReadMapState _readMap(const QByteArray &pass) { _readMtpData(); DEBUG_LOG(("selfSerialized set: %1").arg(selfSerialized.size())); - Core::App().setAuthSessionFromStorage( + Core::App().activeAccount().setAuthSessionFromStorage( std::move(StoredAuthSessionCache), std::move(selfSerialized), _oldMapVersion);