1 /*
2 This file is part of Telegram Desktop,
3 the official desktop application for the Telegram messaging service.
4 
5 For license and copyright information please follow this link:
6 https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
7 */
8 #pragma once
9 
10 #include "base/timer.h"
11 #include "base/flags.h"
12 #include "storage/cache/storage_cache_database.h"
13 #include "data/stickers/data_stickers_set.h"
14 #include "data/data_drafts.h"
15 
16 class History;
17 
18 namespace Core {
19 class FileLocation;
20 } // namespace Core
21 
22 namespace Export {
23 struct Settings;
24 } // namespace Export
25 
26 namespace Main {
27 class Account;
28 class SessionSettings;
29 } // namespace Main
30 
31 namespace Data {
32 class WallPaper;
33 } // namespace Data
34 
35 namespace MTP {
36 class Config;
37 class AuthKey;
38 using AuthKeyPtr = std::shared_ptr<AuthKey>;
39 } // namespace MTP
40 
41 namespace Storage {
42 namespace details {
43 struct ReadSettingsContext;
44 struct FileReadDescriptor;
45 } // namespace details
46 
47 class EncryptionKey;
48 
49 using FileKey = quint64;
50 
51 enum class StartResult : uchar;
52 
53 struct MessageDraft {
54 	MsgId msgId = 0;
55 	TextWithTags textWithTags;
56 	Data::PreviewState previewState = Data::PreviewState::Allowed;
57 };
58 
59 struct MessageDraftSource {
60 	Fn<MessageDraft()> draft;
61 	Fn<MessageCursor()> cursor;
62 };
63 
64 class Account final {
65 public:
66 	Account(not_null<Main::Account*> owner, const QString &dataName);
67 	~Account();
68 
69 	[[nodiscard]] StartResult legacyStart(const QByteArray &passcode);
70 	[[nodiscard]] std::unique_ptr<MTP::Config> start(
71 		MTP::AuthKeyPtr localKey);
72 	void startAdded(MTP::AuthKeyPtr localKey);
oldMapVersion()73 	[[nodiscard]] int oldMapVersion() const {
74 		return _oldMapVersion;
75 	}
76 
77 	[[nodiscard]] QString tempDirectory() const;
78 
peekLegacyLocalKey()79 	[[nodiscard]] MTP::AuthKeyPtr peekLegacyLocalKey() const {
80 		return _localKey;
81 	}
82 
83 	void writeSessionSettings();
84 	void writeMtpData();
85 	void writeMtpConfig();
86 
87 	void registerDraftSource(
88 		not_null<History*> history,
89 		Data::DraftKey key,
90 		MessageDraftSource source);
91 	void unregisterDraftSource(
92 		not_null<History*> history,
93 		Data::DraftKey key);
94 	void writeDrafts(not_null<History*> history);
95 	void readDraftsWithCursors(not_null<History*> history);
96 	void writeDraftCursors(not_null<History*> history);
97 	[[nodiscard]] bool hasDraftCursors(PeerId peerId);
98 	[[nodiscard]] bool hasDraft(PeerId peerId);
99 
100 	void writeFileLocation(MediaKey location, const Core::FileLocation &local);
101 	[[nodiscard]] Core::FileLocation readFileLocation(MediaKey location);
102 	void removeFileLocation(MediaKey location);
103 
104 	[[nodiscard]] EncryptionKey cacheKey() const;
105 	[[nodiscard]] QString cachePath() const;
106 	[[nodiscard]] Cache::Database::Settings cacheSettings() const;
107 	void updateCacheSettings(
108 		Cache::Database::SettingsUpdate &update,
109 		Cache::Database::SettingsUpdate &updateBig);
110 
111 	[[nodiscard]] EncryptionKey cacheBigFileKey() const;
112 	[[nodiscard]] QString cacheBigFilePath() const;
113 	[[nodiscard]] Cache::Database::Settings cacheBigFileSettings() const;
114 
115 	void writeInstalledStickers();
116 	void writeFeaturedStickers();
117 	void writeRecentStickers();
118 	void writeFavedStickers();
119 	void writeArchivedStickers();
120 	void writeArchivedMasks();
121 	void readInstalledStickers();
122 	void readFeaturedStickers();
123 	void readRecentStickers();
124 	void readFavedStickers();
125 	void readArchivedStickers();
126 	void readArchivedMasks();
127 	void writeSavedGifs();
128 	void readSavedGifs();
129 	void writeInstalledMasks();
130 	void writeRecentMasks();
131 	void readInstalledMasks();
132 	void readRecentMasks();
133 
134 	void writeRecentHashtagsAndBots();
135 	void readRecentHashtagsAndBots();
136 	void saveRecentSentHashtags(const QString &text);
137 	void saveRecentSearchHashtags(const QString &text);
138 
139 	void writeExportSettings(const Export::Settings &settings);
140 	[[nodiscard]] Export::Settings readExportSettings();
141 
142 	void writeSelf();
143 
144 	// Read self is special, it can't get session from account, because
145 	// it is not really there yet - it is still being constructed.
146 	void readSelf(
147 		not_null<Main::Session*> session,
148 		const QByteArray& serialized,
149 		int32 streamVersion);
150 
151 	void markBotTrustedOpenGame(PeerId botId);
152 	[[nodiscard]] bool isBotTrustedOpenGame(PeerId botId);
153 	void markBotTrustedPayment(PeerId botId);
154 	[[nodiscard]] bool isBotTrustedPayment(PeerId botId);
155 
156 	[[nodiscard]] bool encrypt(
157 		const void *src,
158 		void *dst,
159 		uint32 len,
160 		const void *key128) const;
161 	[[nodiscard]] bool decrypt(
162 		const void *src,
163 		void *dst,
164 		uint32 len,
165 		const void *key128) const;
166 
167 	void reset();
168 
169 private:
170 	enum class ReadMapResult {
171 		Success,
172 		IncorrectPasscode,
173 		Failed,
174 	};
175 	enum class BotTrustFlag : uchar {
176 		NoOpenGame = (1 << 0),
177 		Payment    = (1 << 1),
178 	};
is_flag_type(BotTrustFlag)179 	friend inline constexpr bool is_flag_type(BotTrustFlag) { return true; };
180 
181 	[[nodiscard]] base::flat_set<QString> collectGoodNames() const;
182 	[[nodiscard]] auto prepareReadSettingsContext() const
183 		-> details::ReadSettingsContext;
184 
185 	ReadMapResult readMapWith(
186 		MTP::AuthKeyPtr localKey,
187 		const QByteArray &legacyPasscode = QByteArray());
188 	void clearLegacyFiles();
189 	void writeMapDelayed();
190 	void writeMapQueued();
191 	void writeMap();
192 
193 	void readLocations();
194 	void writeLocations();
195 	void writeLocationsQueued();
196 	void writeLocationsDelayed();
197 
198 	std::unique_ptr<Main::SessionSettings> readSessionSettings();
199 	void writeSessionSettings(Main::SessionSettings *stored);
200 
201 	std::unique_ptr<MTP::Config> readMtpConfig();
202 	void readMtpData();
203 	std::unique_ptr<Main::SessionSettings> applyReadContext(
204 		details::ReadSettingsContext &&context);
205 
206 	void readDraftCursors(PeerId peerId, Data::HistoryDrafts &map);
207 	void readDraftCursorsLegacy(
208 		PeerId peerId,
209 		details::FileReadDescriptor &draft,
210 		quint64 draftPeerSerialized,
211 		Data::HistoryDrafts &map);
212 	void clearDraftCursors(PeerId peerId);
213 	void readDraftsWithCursorsLegacy(
214 		not_null<History*> history,
215 		details::FileReadDescriptor &draft,
216 		quint64 draftPeerSerialized);
217 
218 	void writeStickerSet(
219 		QDataStream &stream,
220 		const Data::StickersSet &set);
221 	template <typename CheckSet>
222 	void writeStickerSets(
223 		FileKey &stickersKey,
224 		CheckSet checkSet,
225 		const Data::StickersSetsOrder &order);
226 	void readStickerSets(
227 		FileKey &stickersKey,
228 		Data::StickersSetsOrder *outOrder = nullptr,
229 		Data::StickersSetFlags readingFlags = 0);
230 	void importOldRecentStickers();
231 
232 	void readTrustedBots();
233 	void writeTrustedBots();
234 
235 	std::optional<RecentHashtagPack> saveRecentHashtags(
236 		Fn<RecentHashtagPack()> getPack,
237 		const QString &text);
238 
239 	const not_null<Main::Account*> _owner;
240 	const QString _dataName;
241 	const FileKey _dataNameKey = 0;
242 	const QString _basePath;
243 	const QString _tempPath;
244 	const QString _databasePath;
245 
246 	MTP::AuthKeyPtr _localKey;
247 
248 	base::flat_map<PeerId, FileKey> _draftsMap;
249 	base::flat_map<PeerId, FileKey> _draftCursorsMap;
250 	base::flat_map<PeerId, bool> _draftsNotReadMap;
251 	base::flat_map<
252 		not_null<History*>,
253 		base::flat_map<Data::DraftKey, MessageDraftSource>> _draftSources;
254 
255 	QMultiMap<MediaKey, Core::FileLocation> _fileLocations;
256 	QMap<QString, QPair<MediaKey, Core::FileLocation>> _fileLocationPairs;
257 	QMap<MediaKey, MediaKey> _fileLocationAliases;
258 
259 	FileKey _locationsKey = 0;
260 	FileKey _trustedBotsKey = 0;
261 	FileKey _installedStickersKey = 0;
262 	FileKey _featuredStickersKey = 0;
263 	FileKey _recentStickersKey = 0;
264 	FileKey _favedStickersKey = 0;
265 	FileKey _archivedStickersKey = 0;
266 	FileKey _archivedMasksKey = 0;
267 	FileKey _savedGifsKey = 0;
268 	FileKey _recentStickersKeyOld = 0;
269 	FileKey _legacyBackgroundKeyDay = 0;
270 	FileKey _legacyBackgroundKeyNight = 0;
271 	FileKey _settingsKey = 0;
272 	FileKey _recentHashtagsAndBotsKey = 0;
273 	FileKey _exportSettingsKey = 0;
274 	FileKey _installedMasksKey = 0;
275 	FileKey _recentMasksKey = 0;
276 
277 	qint64 _cacheTotalSizeLimit = 0;
278 	qint64 _cacheBigFileTotalSizeLimit = 0;
279 	qint32 _cacheTotalTimeLimit = 0;
280 	qint32 _cacheBigFileTotalTimeLimit = 0;
281 
282 	base::flat_map<PeerId, base::flags<BotTrustFlag>> _trustedBots;
283 	bool _trustedBotsRead = false;
284 	bool _readingUserSettings = false;
285 	bool _recentHashtagsAndBotsWereRead = false;
286 
287 	int _oldMapVersion = 0;
288 
289 	base::Timer _writeMapTimer;
290 	base::Timer _writeLocationsTimer;
291 	bool _mapChanged = false;
292 	bool _locationsChanged = false;
293 
294 };
295 
296 } // namespace Storage
297