diff --git a/Telegram/SourceFiles/intro/intro_phone.cpp b/Telegram/SourceFiles/intro/intro_phone.cpp index 2254bae255..2b66c53165 100644 --- a/Telegram/SourceFiles/intro/intro_phone.cpp +++ b/Telegram/SourceFiles/intro/intro_phone.cpp @@ -16,7 +16,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "ui/wrap/fade_wrap.h" #include "ui/special_fields.h" #include "main/main_account.h" +#include "main/main_domain.h" #include "main/main_app_config.h" +#include "main/main_session.h" +#include "data/data_user.h" #include "boxes/confirm_phone_box.h" #include "boxes/confirm_box.h" #include "core/application.h" @@ -138,6 +141,24 @@ void PhoneWidget::submit() { return; } + // Check if such account is authorized already. + const auto digitsOnly = [](QString value) { + return value.replace(QRegularExpression("[^0-9]"), QString()); + }; + const auto phoneDigits = digitsOnly(phone); + for (const auto &[index, existing] : Core::App().domain().accounts()) { + const auto raw = existing.get(); + if (const auto session = raw->maybeSession()) { + if (raw->mtp().environment() == account().mtp().environment() + && digitsOnly(session->user()->phone()) == phoneDigits) { + crl::on_main(raw, [=] { + Core::App().domain().activate(raw); + }); + return; + } + } + } + hidePhoneError(); _checkRequestTimer.callEach(1000); diff --git a/Telegram/SourceFiles/intro/intro_step.cpp b/Telegram/SourceFiles/intro/intro_step.cpp index 6d1b36547f..cfe376aea2 100644 --- a/Telegram/SourceFiles/intro/intro_step.cpp +++ b/Telegram/SourceFiles/intro/intro_step.cpp @@ -13,6 +13,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "lang/lang_keys.h" #include "lang/lang_cloud_manager.h" #include "main/main_account.h" +#include "main/main_domain.h" #include "main/main_session.h" #include "main/main_session_settings.h" #include "core/application.h" @@ -144,6 +145,21 @@ void Step::finish(const MTPUser &user, QImage &&photo) { return; } + // Check if such account is authorized already. + for (const auto &[index, existing] : Core::App().domain().accounts()) { + const auto raw = existing.get(); + if (const auto session = raw->maybeSession()) { + if (raw->mtp().environment() == _account->mtp().environment() + && user.c_user().vid().v == session->userId()) { + _account->logOut(); + crl::on_main(raw, [=] { + Core::App().domain().activate(raw); + }); + return; + } + } + } + // Save the default language if we've suggested some other and user ignored it. const auto currentId = Lang::Current().id(); const auto defaultId = Lang::DefaultLanguageId(); @@ -152,7 +168,6 @@ void Step::finish(const MTPUser &user, QImage &&photo) { Lang::Current().switchToId(Lang::DefaultLanguage()); Local::writeLangPack(); } - const auto account = _account; account->createSession(user); diff --git a/Telegram/SourceFiles/main/main_account.cpp b/Telegram/SourceFiles/main/main_account.cpp index 988fa8cfa9..a4c51694e5 100644 --- a/Telegram/SourceFiles/main/main_account.cpp +++ b/Telegram/SourceFiles/main/main_account.cpp @@ -126,8 +126,13 @@ void Account::watchSessionChanges() { }, _lifetime); } -UserId Account::willHaveUserId() const { - return _sessionUserId; +uint64 Account::willHaveSessionUniqueId(MTP::Config *config) const { + // See also Session::uniqueId. + if (!_sessionUserId) { + return 0; + } + return uint64(uint32(_sessionUserId)) + | (config && config->isTestMode() ? 0x0100'0000'0000'0000ULL : 0ULL); } void Account::createSession(const MTPUser &user) { diff --git a/Telegram/SourceFiles/main/main_account.h b/Telegram/SourceFiles/main/main_account.h index 99318ae25d..b26699fb57 100644 --- a/Telegram/SourceFiles/main/main_account.h +++ b/Telegram/SourceFiles/main/main_account.h @@ -48,7 +48,7 @@ public: std::shared_ptr localKey); void start(std::unique_ptr config); - [[nodiscard]] UserId willHaveUserId() const; + [[nodiscard]] uint64 willHaveSessionUniqueId(MTP::Config *config) const; void createSession(const MTPUser &user); void createSession( UserId id, diff --git a/Telegram/SourceFiles/main/main_session.cpp b/Telegram/SourceFiles/main/main_session.cpp index 2aebd8bc4c..cbbab57f84 100644 --- a/Telegram/SourceFiles/main/main_session.cpp +++ b/Telegram/SourceFiles/main/main_session.cpp @@ -166,11 +166,9 @@ base::Observable &Session::downloaderTaskFinished() { } uint64 Session::uniqueId() const { - auto result = uint64(uint32(userId())); - if (mtp().isTestMode()) { - result |= 0x0100'0000'0000'0000ULL; - } - return result; + // See also Account::willHaveSessionUniqueId. + return uint64(uint32(userId())) + | (mtp().isTestMode() ? 0x0100'0000'0000'0000ULL : 0ULL); } UserId Session::userId() const { diff --git a/Telegram/SourceFiles/storage/storage_domain.cpp b/Telegram/SourceFiles/storage/storage_domain.cpp index bdfb8d33b1..9a74ea8eb8 100644 --- a/Telegram/SourceFiles/storage/storage_domain.cpp +++ b/Telegram/SourceFiles/storage/storage_domain.cpp @@ -169,7 +169,7 @@ Domain::StartModernResult Domain::startModern( _oldVersion = keyData.version; auto tried = base::flat_set(); - auto users = base::flat_set(); + auto sessions = base::flat_set(); auto active = 0; for (auto i = 0; i != count; ++i) { auto index = qint32(); @@ -182,10 +182,11 @@ Domain::StartModernResult Domain::startModern( _dataName, index); auto config = account->prepareToStart(_localKey); - const auto userId = account->willHaveUserId(); - if (!users.contains(userId) - && (userId != 0 || (users.empty() && i + 1 == count))) { - if (users.empty()) { + const auto sessionId = account->willHaveSessionUniqueId( + config.get()); + if (!sessions.contains(sessionId) + && (sessionId != 0 || (sessions.empty() && i + 1 == count))) { + if (sessions.empty()) { active = index; } account->start(std::move(config)); @@ -193,16 +194,21 @@ Domain::StartModernResult Domain::startModern( .index = index, .account = std::move(account) }); - users.emplace(userId); + sessions.emplace(sessionId); } } } + if (sessions.empty()) { + LOG(("App Error: no accounts read.")); + return StartModernResult::Failed; + } + if (!info.stream.atEnd()) { info.stream >> active; } _owner->activateFromStorage(active); - Ensures(!users.empty()); + Ensures(!sessions.empty()); return StartModernResult::Success; }