Don't allow two same accounts being logged in.

This commit is contained in:
John Preston 2020-06-24 13:32:07 +04:00
parent d8a2b391a3
commit 0bc2bfe630
6 changed files with 61 additions and 16 deletions

View file

@ -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);

View file

@ -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);

View file

@ -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) {

View file

@ -48,7 +48,7 @@ public:
std::shared_ptr<MTP::AuthKey> localKey);
void start(std::unique_ptr<MTP::Config> config);
[[nodiscard]] UserId willHaveUserId() const;
[[nodiscard]] uint64 willHaveSessionUniqueId(MTP::Config *config) const;
void createSession(const MTPUser &user);
void createSession(
UserId id,

View file

@ -166,11 +166,9 @@ base::Observable<void> &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 {

View file

@ -169,7 +169,7 @@ Domain::StartModernResult Domain::startModern(
_oldVersion = keyData.version;
auto tried = base::flat_set<int>();
auto users = base::flat_set<UserId>();
auto sessions = base::flat_set<uint64>();
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;
}