/* This file is part of Telegram Desktop, the official desktop application for the Telegram messaging service. For license and copyright information please follow this link: https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #pragma once #include "mtproto/mtproto_auth_key.h" #include "mtproto/mtp_instance.h" #include "base/weak_ptr.h" namespace Storage { class Account; class Domain; enum class StartResult : uchar; } // namespace Storage namespace MTP { class AuthKey; class Config; } // namespace MTP namespace Main { class Domain; class Session; class SessionSettings; class AppConfig; class Account final : public base::has_weak_ptr { public: Account(not_null domain, const QString &dataName, int index); ~Account(); [[nodiscard]] Domain &domain() const { return *_domain; } [[nodiscard]] Storage::Domain &domainLocal() const; [[nodiscard]] Storage::StartResult legacyStart( const QByteArray &passcode); [[nodiscard]] std::unique_ptr prepareToStart( std::shared_ptr localKey); void prepareToStartAdded( std::shared_ptr localKey); void start(std::unique_ptr config); [[nodiscard]] uint64 willHaveSessionUniqueId(MTP::Config *config) const; void createSession(const MTPUser &user); void createSession( UserId id, QByteArray serialized, int streamVersion, std::unique_ptr settings); void destroySession(); void logOut(); void forcedLogOut(); [[nodiscard]] bool loggingOut() const; [[nodiscard]] AppConfig &appConfig() const { Expects(_appConfig != nullptr); return *_appConfig; } [[nodiscard]] Storage::Account &local() const { return *_local; } [[nodiscard]] bool sessionExists() const; [[nodiscard]] Session &session() const; [[nodiscard]] Session *maybeSession() const; [[nodiscard]] rpl::producer sessionValue() const; [[nodiscard]] rpl::producer sessionChanges() const; [[nodiscard]] MTP::Instance &mtp() const { return *_mtp; } [[nodiscard]] rpl::producer> mtpValue() const; // Set from legacy storage. void setLegacyMtpMainDcId(MTP::DcId mainDcId); void setLegacyMtpKey(std::shared_ptr key); void setSessionUserId(UserId userId); void setSessionFromStorage( std::unique_ptr data, QByteArray &&selfSerialized, int32 selfStreamVersion); [[nodiscard]] SessionSettings *getSessionSettings(); [[nodiscard]] rpl::producer<> mtpNewSessionCreated() const; [[nodiscard]] rpl::producer mtpUpdates() const; // Serialization. [[nodiscard]] QByteArray serializeMtpAuthorization() const; void setMtpAuthorization(const QByteArray &serialized); void suggestMainDcId(MTP::DcId mainDcId); void destroyStaleAuthorizationKeys(); [[nodiscard]] rpl::lifetime &lifetime() { return _lifetime; } private: static constexpr auto kDefaultSaveDelay = crl::time(1000); void startMtp(std::unique_ptr config); void createSession( const MTPUser &user, QByteArray serialized, int streamVersion, std::unique_ptr settings); void watchProxyChanges(); void watchSessionChanges(); bool checkForUpdates(const mtpPrime *from, const mtpPrime *end); bool checkForNewSession(const mtpPrime *from, const mtpPrime *end); void destroyMtpKeys(MTP::AuthKeysList &&keys); void resetAuthorizationKeys(); void loggedOut(); const not_null _domain; const std::unique_ptr _local; std::unique_ptr _mtp; rpl::variable _mtpValue; std::unique_ptr _mtpForKeysDestroy; rpl::event_stream _mtpUpdates; rpl::event_stream<> _mtpNewSessionCreated; std::unique_ptr _appConfig; std::unique_ptr _session; rpl::variable _sessionValue; UserId _sessionUserId = 0; QByteArray _sessionUserSerialized; int32 _sessionUserStreamVersion = 0; std::unique_ptr _storedSessionSettings; MTP::Instance::Fields _mtpFields; MTP::AuthKeysList _mtpKeysToDestroy; bool _loggingOut = false; rpl::lifetime _lifetime; }; } // namespace Main