mirror of
https://github.com/telegramdesktop/tdesktop
synced 2025-04-01 23:00:58 +00:00
Move MTP::Instance to Main::Account.
This commit is contained in:
parent
db2018c765
commit
9cf4cf6dca
@ -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<MTP::Instance*> AuthSession::mtp() {
|
||||
return _account->mtp();
|
||||
}
|
||||
|
||||
void AuthSession::localPasscodeChanged() {
|
||||
_shouldLockAt = 0;
|
||||
_autoLockTimer.cancel();
|
||||
|
@ -333,6 +333,7 @@ public:
|
||||
void moveSettingsFrom(AuthSessionSettings &&other);
|
||||
void saveSettingsDelayed(crl::time delay = kDefaultSaveDelay);
|
||||
|
||||
not_null<MTP::Instance*> mtp();
|
||||
ApiWrap &api() {
|
||||
return *_api;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -1155,13 +1155,13 @@ not_null<Ui::MultiSelect*> 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<base::binary_guard>(
|
||||
result.make_guard());
|
||||
auto alive = std::make_shared<std::unique_ptr<base::Subscription>>(
|
||||
std::make_unique<base::Subscription>());
|
||||
**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<LanguageBox>());
|
||||
}
|
||||
manager->requestLanguageList();
|
||||
manager.requestLanguageList();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -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<MTP::DedicatedLoader> loader) {
|
||||
if (loader) {
|
||||
setImplementation(std::move(loader));
|
||||
|
@ -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<AuthSessionSettings> storedAuthSession;
|
||||
MTP::Instance::Config mtpConfig;
|
||||
MTP::AuthKeysList mtpKeysToDestroy;
|
||||
base::Timer quitTimer;
|
||||
};
|
||||
|
||||
@ -87,6 +81,7 @@ Application::Application(not_null<Launcher*> launcher)
|
||||
, _private(std::make_unique<Private>())
|
||||
, _databases(std::make_unique<Storage::Databases>())
|
||||
, _animationsManager(std::make_unique<Ui::Animations::Manager>())
|
||||
, _dcOptions(std::make_unique<MTP::DcOptions>())
|
||||
, _account(std::make_unique<Main::Account>(cDataFile()))
|
||||
, _langpack(std::make_unique<Lang::Instance>())
|
||||
, _emojiKeywords(std::make_unique<ChatHelpers::EmojiKeywords>())
|
||||
@ -95,9 +90,26 @@ Application::Application(not_null<Launcher*> 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::Instance*> mtp) {
|
||||
_langCloudManager = std::make_unique<Lang::CloudManager>(
|
||||
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<ProxyChange> {
|
||||
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>(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<AuthSessionSettings> 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<qint32>(stream);
|
||||
auto mainDcId = Serialize::read<qint32>(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<qint32>(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<qint32>(stream);
|
||||
auto keyData = Serialize::read<MTP::AuthKey::Data>(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>(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<MTP::Instance>(
|
||||
_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<Lang::CloudManager>(
|
||||
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<MTP::Instance>(
|
||||
_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<MTP::DcOptions>();
|
||||
_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();
|
||||
|
@ -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<ProxyChange> 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<AuthSessionSettings> 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<Application*> instance) {
|
||||
Expects(Instance == nullptr);
|
||||
|
||||
Instance = instance;
|
||||
}
|
||||
};
|
||||
InstanceSetter _setter = { this };
|
||||
|
||||
not_null<Launcher*> _launcher;
|
||||
rpl::event_stream<ProxyChange> _proxyChanges;
|
||||
|
||||
// Some fields are just moved from the declaration.
|
||||
struct Private;
|
||||
@ -273,6 +256,7 @@ private:
|
||||
|
||||
const std::unique_ptr<Storage::Databases> _databases;
|
||||
const std::unique_ptr<Ui::Animations::Manager> _animationsManager;
|
||||
const std::unique_ptr<MTP::DcOptions> _dcOptions;
|
||||
const std::unique_ptr<Main::Account> _account;
|
||||
std::unique_ptr<Window::Controller> _window;
|
||||
std::unique_ptr<Media::View::OverlayWidget> _mediaView;
|
||||
@ -280,10 +264,6 @@ private:
|
||||
std::unique_ptr<Lang::CloudManager> _langCloudManager;
|
||||
const std::unique_ptr<ChatHelpers::EmojiKeywords> _emojiKeywords;
|
||||
std::unique_ptr<Lang::Translator> _translator;
|
||||
std::unique_ptr<MTP::DcOptions> _dcOptions;
|
||||
std::unique_ptr<MTP::Instance> _mtproto;
|
||||
std::unique_ptr<MTP::Instance> _mtprotoForKeysDestroy;
|
||||
rpl::event_stream<> _configUpdates;
|
||||
base::Observable<void> _passcodedChanged;
|
||||
QPointer<BoxContent> _badProxyDisableBox;
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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<int> PinnedDialogsInFolderMaxValue() {
|
||||
rpl::producer<int> PinnedDialogsInFolderMaxValue(
|
||||
not_null<AuthSession*> 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<int> PinnedDialogsInFolderMaxValue() {
|
||||
Folder::Folder(not_null<Data::Session*> owner, FolderId id)
|
||||
: Entry(owner, this)
|
||||
, _id(id)
|
||||
, _chatsList(PinnedDialogsInFolderMaxValue())
|
||||
, _chatsList(PinnedDialogsInFolderMaxValue(&owner->session()))
|
||||
, _name(tr::lng_archived_name(tr::now)) {
|
||||
indexNameParts();
|
||||
|
||||
|
@ -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<Loader>
|
||||
#include "media/streaming/media_streaming_reader.h" // make_shared<Reader>
|
||||
@ -155,11 +156,12 @@ MTPPhotoSize FindDocumentThumbnail(const MTPDdocument &data) {
|
||||
: MTPPhotoSize(MTP_photoSizeEmpty(MTP_string()));
|
||||
}
|
||||
|
||||
rpl::producer<int> PinnedDialogsCountMaxValue() {
|
||||
rpl::producer<int> PinnedDialogsCountMaxValue(
|
||||
not_null<AuthSession*> 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<AuthSession*> 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(); })
|
||||
|
@ -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<Main::Account*> account,
|
||||
not_null<Widget::Data*> 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<SignupWidget>();
|
||||
});
|
||||
}
|
||||
|
||||
@ -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<PwdCheckWidget>();
|
||||
}
|
||||
|
||||
void CodeWidget::submit() {
|
||||
|
@ -39,7 +39,10 @@ class CodeWidget : public Widget::Step {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
CodeWidget(QWidget *parent, Widget::Data *data);
|
||||
CodeWidget(
|
||||
QWidget *parent,
|
||||
not_null<Main::Account*> account,
|
||||
not_null<Widget::Data*> data);
|
||||
|
||||
bool hasBack() const override {
|
||||
return true;
|
||||
|
@ -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<Main::Account*> account,
|
||||
not_null<Widget::Data*> 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<CodeWidget>();
|
||||
}
|
||||
|
||||
bool PhoneWidget::phoneSubmitFail(const RPCError &error) {
|
||||
|
@ -23,7 +23,10 @@ class PhoneWidget : public Widget::Step {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
PhoneWidget(QWidget *parent, Widget::Data *data);
|
||||
PhoneWidget(
|
||||
QWidget *parent,
|
||||
not_null<Main::Account*> account,
|
||||
not_null<Widget::Data*> data);
|
||||
|
||||
void selectCountry(const QString &country);
|
||||
|
||||
|
@ -23,8 +23,9 @@ namespace Intro {
|
||||
|
||||
PwdCheckWidget::PwdCheckWidget(
|
||||
QWidget *parent,
|
||||
Widget::Data *data)
|
||||
: Step(parent, data)
|
||||
not_null<Main::Account*> account,
|
||||
not_null<Widget::Data*> data)
|
||||
: Step(parent, account, data)
|
||||
, _request(getData()->pwdRequest)
|
||||
, _hasRecovery(getData()->hasRecovery)
|
||||
, _notEmptyPassport(getData()->pwdNotEmptyPassport)
|
||||
|
@ -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<Main::Account*> account,
|
||||
not_null<Widget::Data*> data);
|
||||
|
||||
void setInnerFocus() override;
|
||||
void activate() override;
|
||||
|
@ -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<Main::Account*> account,
|
||||
not_null<Widget::Data*> data)
|
||||
: Step(parent, account, data)
|
||||
, _photo(
|
||||
this,
|
||||
tr::lng_settings_crop_profile(tr::now),
|
||||
|
@ -21,7 +21,10 @@ class SignupWidget : public Widget::Step {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
SignupWidget(QWidget *parent, Widget::Data *data);
|
||||
SignupWidget(
|
||||
QWidget *parent,
|
||||
not_null<Main::Account*> account,
|
||||
not_null<Widget::Data*> data);
|
||||
|
||||
void finishInit() override;
|
||||
void setInnerFocus() override;
|
||||
|
@ -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<Main::Account*> account,
|
||||
not_null<Widget::Data*> 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<PhoneWidget>();
|
||||
}
|
||||
|
||||
rpl::producer<QString> StartWidget::nextButtonText() const {
|
||||
|
@ -19,7 +19,10 @@ namespace Intro {
|
||||
|
||||
class StartWidget : public Widget::Step {
|
||||
public:
|
||||
StartWidget(QWidget *parent, Widget::Data *data);
|
||||
StartWidget(
|
||||
QWidget *parent,
|
||||
not_null<Main::Account*> account,
|
||||
not_null<Widget::Data*> data);
|
||||
|
||||
void submit() override;
|
||||
rpl::producer<QString> nextButtonText() const override;
|
||||
|
@ -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<Main::Account*> account)
|
||||
: RpWidget(parent)
|
||||
, _account(account)
|
||||
, _back(this, object_ptr<Ui::IconButton>(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<Main::Account*> account,
|
||||
not_null<Data*> data,
|
||||
bool hasCover)
|
||||
: RpWidget(parent)
|
||||
, _account(account)
|
||||
, _data(data)
|
||||
, _hasCover(hasCover)
|
||||
, _title(this, _hasCover ? st::introCoverTitle : st::introTitle)
|
||||
|
@ -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<Main::Account*> 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<Main::Account*> account,
|
||||
not_null<Data*> 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<Data*> 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 <typename StepType>
|
||||
void goNext() {
|
||||
if (_goCallback) {
|
||||
_goCallback(
|
||||
new StepType(parentWidget(), _account, _data),
|
||||
Direction::Forward);
|
||||
}
|
||||
}
|
||||
void goReplace(Step *step) {
|
||||
if (_goCallback) _goCallback(step, Direction::Replace);
|
||||
|
||||
template <typename StepType>
|
||||
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<Main::Account*> _account;
|
||||
const not_null<Data*> _data;
|
||||
|
||||
bool _hasCover = false;
|
||||
Fn<void(Step *step, Direction direction)> _goCallback;
|
||||
Fn<void()> _showResetCallback;
|
||||
@ -233,7 +258,7 @@ private:
|
||||
void createLanguageLink();
|
||||
|
||||
void updateControlsGeometry();
|
||||
Data *getData() {
|
||||
not_null<Data*> getData() {
|
||||
return &_data;
|
||||
}
|
||||
|
||||
@ -260,6 +285,8 @@ private:
|
||||
void getNearestDC();
|
||||
void showTerms(Fn<void()> callback);
|
||||
|
||||
not_null<Main::Account*> _account;
|
||||
|
||||
Ui::Animations::Simple _a_show;
|
||||
bool _showBack = false;
|
||||
QPixmap _cacheUnder, _cacheOver;
|
||||
|
@ -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<AuthSession>(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<AuthSession*> Account::sessionValue() const {
|
||||
return _sessionValue.value();
|
||||
}
|
||||
@ -49,8 +140,343 @@ rpl::producer<AuthSession*> Account::sessionChanges() const {
|
||||
return _sessionValue.changes();
|
||||
}
|
||||
|
||||
MTP::Instance *Account::mtp() {
|
||||
return MTP::MainInstance();
|
||||
rpl::producer<MTP::Instance*> Account::mtpValue() const {
|
||||
return _mtpValue.value();
|
||||
}
|
||||
|
||||
rpl::producer<MTP::Instance*> 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>(
|
||||
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<AuthSessionSettings> 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<qint32>(stream);
|
||||
auto mainDcId = Serialize::read<qint32>(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<qint32>(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<qint32>(stream);
|
||||
const auto keyData = Serialize::read<MTP::AuthKey::Data>(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>(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<MTP::Instance>(
|
||||
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<MTP::Instance>(
|
||||
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
|
||||
|
@ -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<AuthSession*> sessionValue() const;
|
||||
[[nodiscard]] rpl::producer<AuthSession*> sessionChanges() const;
|
||||
|
||||
[[nodiscard]] MTP::Instance *mtp();
|
||||
[[nodiscard]] MTP::Instance *mtp() {
|
||||
return _mtp.get();
|
||||
}
|
||||
[[nodiscard]] rpl::producer<MTP::Instance*> mtpValue() const;
|
||||
[[nodiscard]] rpl::producer<MTP::Instance*> 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<AuthSessionSettings> 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::Instance> _mtp;
|
||||
rpl::variable<MTP::Instance*> _mtpValue;
|
||||
std::unique_ptr<MTP::Instance> _mtpForKeysDestroy;
|
||||
rpl::event_stream<> _configUpdates;
|
||||
|
||||
std::unique_ptr<AuthSession> _session;
|
||||
rpl::variable<AuthSession*> _sessionValue;
|
||||
|
||||
UserId _authSessionUserId = 0;
|
||||
QByteArray _authSessionUserSerialized;
|
||||
int32 _authSessionUserStreamVersion = 0;
|
||||
std::unique_ptr<AuthSessionSettings> _storedAuthSession;
|
||||
MTP::Instance::Config _mtpConfig;
|
||||
MTP::AuthKeysList _mtpKeysToDestroy;
|
||||
|
||||
rpl::lifetime _lifetime;
|
||||
|
||||
};
|
||||
|
||||
} // namespace Main
|
||||
|
@ -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: {
|
||||
|
@ -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<ConfirmBox>(
|
||||
|
@ -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))
|
||||
|
@ -48,6 +48,8 @@ public:
|
||||
|
||||
};
|
||||
|
||||
DcOptions();
|
||||
|
||||
[[nodiscard]] static bool ValidateSecret(bytes::const_span secret);
|
||||
|
||||
// construct methods don't notify "changed" subscribers.
|
||||
|
@ -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
|
||||
|
@ -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*> _instance;
|
||||
not_null<DcOptions*> _dcOptions;
|
||||
Instance::Mode _mode = Instance::Mode::Normal;
|
||||
const not_null<Instance*> _instance;
|
||||
const not_null<DcOptions*> _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));
|
||||
|
@ -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<InformBox>("Could not load endpoints :( Errors in 'log.txt'."));
|
||||
}
|
||||
}
|
||||
|
@ -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<MTP::AuthKey::Data>(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);
|
||||
|
Loading…
Reference in New Issue
Block a user