diff --git a/Telegram/SourceFiles/inline_bots/bot_attach_web_view.cpp b/Telegram/SourceFiles/inline_bots/bot_attach_web_view.cpp index 682afe3de..95e7630e4 100644 --- a/Telegram/SourceFiles/inline_bots/bot_attach_web_view.cpp +++ b/Telegram/SourceFiles/inline_bots/bot_attach_web_view.cpp @@ -1491,7 +1491,7 @@ void AttachWebView::show( _catchingCancelInShowCall = true; _panel = Ui::BotWebView::Show({ .url = url, - .userDataPath = _session->domain().local().webviewDataPath(), + .storageId = _session->local().resolveStorageIdBots(), .title = std::move(title), .bottom = rpl::single('@' + _bot->username()), .delegate = static_cast(this), diff --git a/Telegram/SourceFiles/intro/intro_step.cpp b/Telegram/SourceFiles/intro/intro_step.cpp index 9c408f412..c3181bd7c 100644 --- a/Telegram/SourceFiles/intro/intro_step.cpp +++ b/Telegram/SourceFiles/intro/intro_step.cpp @@ -224,6 +224,7 @@ void Step::createSession( account->createSession(user, std::move(settings)); // "this" is already deleted here by creating the main widget. + account->local().enforceModernStorageIdBots(); account->local().writeMtpData(); auto &session = account->session(); session.data().chatsFilters().setPreloaded(filters); diff --git a/Telegram/SourceFiles/iv/iv_controller.cpp b/Telegram/SourceFiles/iv/iv_controller.cpp index c62debebf..a2a701d84 100644 --- a/Telegram/SourceFiles/iv/iv_controller.cpp +++ b/Telegram/SourceFiles/iv/iv_controller.cpp @@ -292,12 +292,12 @@ void Controller::initControls() { } void Controller::show( - const QString &dataPath, + const Webview::StorageId &storageId, Prepared page, base::flat_map> inChannelValues) { page.script = fillInChannelValuesScript(std::move(inChannelValues)); InvokeQueued(_container, [=, page = std::move(page)]() mutable { - showInWindow(dataPath, std::move(page)); + showInWindow(storageId, std::move(page)); }); } @@ -389,7 +389,7 @@ void Controller::createWindow() { window->show(); } -void Controller::createWebview(const QString &dataPath) { +void Controller::createWebview(const Webview::StorageId &storageId) { Expects(!_webview); const auto window = _window.get(); @@ -397,7 +397,7 @@ void Controller::createWebview(const QString &dataPath) { _container, Webview::WindowConfig{ .opaqueBg = st::windowBg->c, - .userDataPath = dataPath, + .storageId = storageId, }); const auto raw = _webview.get(); @@ -558,7 +558,9 @@ void Controller::createWebview(const QString &dataPath) { raw->init(R"()"); } -void Controller::showInWindow(const QString &dataPath, Prepared page) { +void Controller::showInWindow( + const Webview::StorageId &storageId, + Prepared page) { Expects(_container != nullptr); const auto url = page.url; @@ -571,7 +573,7 @@ void Controller::showInWindow(const QString &dataPath, Prepared page) { const auto index = i->second; _index = index; if (!_webview) { - createWebview(dataPath); + createWebview(storageId); if (_webview && _webview->widget()) { auto id = u"iv/page%1.html"_q.arg(index); if (!_hash.isEmpty()) { diff --git a/Telegram/SourceFiles/iv/iv_controller.h b/Telegram/SourceFiles/iv/iv_controller.h index 85132b12b..d3363d67e 100644 --- a/Telegram/SourceFiles/iv/iv_controller.h +++ b/Telegram/SourceFiles/iv/iv_controller.h @@ -13,6 +13,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "iv/iv_delegate.h" #include "ui/effects/animations.h" #include "ui/text/text.h" +#include "webview/webview_common.h" class Painter; @@ -69,7 +70,7 @@ public: }; void show( - const QString &dataPath, + const Webview::StorageId &storageId, Prepared page, base::flat_map> inChannelValues); void update(Prepared page); @@ -90,11 +91,11 @@ public: private: void createWindow(); - void createWebview(const QString &dataPath); + void createWebview(const Webview::StorageId &storageId); [[nodiscard]] QByteArray navigateScript(int index, const QString &hash); [[nodiscard]] QByteArray reloadScript(int index); - void showInWindow(const QString &dataPath, Prepared page); + void showInWindow(const Webview::StorageId &storageId, Prepared page); [[nodiscard]] QByteArray fillInChannelValuesScript( base::flat_map> inChannelValues); [[nodiscard]] QByteArray toggleInChannelScript( diff --git a/Telegram/SourceFiles/iv/iv_instance.cpp b/Telegram/SourceFiles/iv/iv_instance.cpp index 9af2cd3d0..49ae8c144 100644 --- a/Telegram/SourceFiles/iv/iv_instance.cpp +++ b/Telegram/SourceFiles/iv/iv_instance.cpp @@ -31,13 +31,12 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "lang/lang_keys.h" #include "lottie/lottie_common.h" // Lottie::ReadContent. #include "main/main_account.h" -#include "main/main_domain.h" #include "main/main_session.h" #include "main/session/session_show.h" #include "media/streaming/media_streaming_loader.h" #include "media/view/media_view_open_common.h" #include "storage/file_download.h" -#include "storage/storage_domain.h" +#include "storage/storage_account.h" #include "ui/boxes/confirm_box.h" #include "ui/layers/layer_widget.h" #include "ui/text/text_utilities.h" @@ -348,9 +347,8 @@ void Shown::showWindowed(Prepared result) { createController(); } - const auto domain = &_session->domain(); _controller->show( - domain->local().webviewDataPath(), + _session->local().resolveStorageIdOther(), std::move(result), base::duplicate(_inChannelValues)); } diff --git a/Telegram/SourceFiles/payments/payments_checkout_process.cpp b/Telegram/SourceFiles/payments/payments_checkout_process.cpp index ad7299664..e9fb12d26 100644 --- a/Telegram/SourceFiles/payments/payments_checkout_process.cpp +++ b/Telegram/SourceFiles/payments/payments_checkout_process.cpp @@ -11,8 +11,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "payments/ui/payments_panel.h" #include "main/main_session.h" #include "main/main_account.h" -#include "main/main_domain.h" -#include "storage/storage_domain.h" +#include "storage/storage_account.h" #include "history/history_item.h" #include "history/history.h" #include "data/data_user.h" // UserData::isBot. @@ -25,7 +24,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "apiwrap.h" #include "api/api_cloud_password.h" #include "window/themes/window_theme.h" -#include "webview/webview_interface.h" #include #include @@ -877,8 +875,8 @@ void CheckoutProcess::performInitialSilentValidation() { _form->validateInformation(saved); } -QString CheckoutProcess::panelWebviewDataPath() { - return _session->domain().local().webviewDataPath(); +Webview::StorageId CheckoutProcess::panelWebviewStorageId() { + return _session->local().resolveStorageIdOther(); } Webview::ThemeParams CheckoutProcess::panelWebviewThemeParams() { diff --git a/Telegram/SourceFiles/payments/payments_checkout_process.h b/Telegram/SourceFiles/payments/payments_checkout_process.h index 84c0624cc..dd995324f 100644 --- a/Telegram/SourceFiles/payments/payments_checkout_process.h +++ b/Telegram/SourceFiles/payments/payments_checkout_process.h @@ -7,8 +7,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #pragma once -#include "payments/ui/payments_panel_delegate.h" #include "base/weak_ptr.h" +#include "payments/ui/payments_panel_delegate.h" +#include "webview/webview_common.h" class HistoryItem; class PasscodeBox; @@ -153,7 +154,7 @@ private: void panelShowBox(object_ptr box) override; QVariant panelClickHandlerContext() override; - QString panelWebviewDataPath() override; + Webview::StorageId panelWebviewStorageId() override; Webview::ThemeParams panelWebviewThemeParams() override; std::optional panelOverrideExpireDateThreshold() override; diff --git a/Telegram/SourceFiles/payments/ui/payments_panel.cpp b/Telegram/SourceFiles/payments/ui/payments_panel.cpp index a672f81fc..f509fdb70 100644 --- a/Telegram/SourceFiles/payments/ui/payments_panel.cpp +++ b/Telegram/SourceFiles/payments/ui/payments_panel.cpp @@ -547,7 +547,7 @@ bool Panel::createWebview(const Webview::ThemeParams ¶ms) { container, Webview::WindowConfig{ .opaqueBg = params.opaqueBg, - .userDataPath = _delegate->panelWebviewDataPath(), + .storageId = _delegate->panelWebviewStorageId(), }); const auto raw = &_webview->window; diff --git a/Telegram/SourceFiles/payments/ui/payments_panel_delegate.h b/Telegram/SourceFiles/payments/ui/payments_panel_delegate.h index b3113d558..fd73fd144 100644 --- a/Telegram/SourceFiles/payments/ui/payments_panel_delegate.h +++ b/Telegram/SourceFiles/payments/ui/payments_panel_delegate.h @@ -18,6 +18,7 @@ class BoxContent; namespace Webview { struct ThemeParams; +struct StorageId; } // namespace Webview namespace Payments::Ui { @@ -59,7 +60,7 @@ public: virtual void panelShowBox(object_ptr box) = 0; virtual QVariant panelClickHandlerContext() = 0; - virtual QString panelWebviewDataPath() = 0; + virtual Webview::StorageId panelWebviewStorageId() = 0; virtual Webview::ThemeParams panelWebviewThemeParams() = 0; virtual std::optional panelOverrideExpireDateThreshold() = 0; diff --git a/Telegram/SourceFiles/storage/storage_account.cpp b/Telegram/SourceFiles/storage/storage_account.cpp index 22484f65b..83d8e52f4 100644 --- a/Telegram/SourceFiles/storage/storage_account.cpp +++ b/Telegram/SourceFiles/storage/storage_account.cpp @@ -18,6 +18,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "storage/serialize_peer.h" #include "storage/serialize_document.h" #include "main/main_account.h" +#include "main/main_domain.h" #include "main/main_session.h" #include "mtproto/mtproto_config.h" #include "mtproto/mtproto_dc_options.h" @@ -35,6 +36,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "data/data_user.h" #include "data/data_drafts.h" #include "export/export_settings.h" +#include "webview/webview_interface.h" #include "window/themes/window_theme.h" namespace Storage { @@ -91,6 +93,7 @@ enum { // Local Storage Keys lskMasksKeys = 0x16, // no data lskCustomEmojiKeys = 0x17, // no data lskSearchSuggestions = 0x18, // no data + lskWebviewTokens = 0x19, // data: QByteArray bots, QByteArray other }; auto EmptyMessageDraftSources() @@ -303,6 +306,7 @@ Account::ReadMapResult Account::readMapWith( quint64 legacyBackgroundKeyDay = 0, legacyBackgroundKeyNight = 0; quint64 userSettingsKey = 0, recentHashtagsAndBotsKey = 0, exportSettingsKey = 0; quint64 searchSuggestionsKey = 0; + QByteArray webviewStorageTokenBots, webviewStorageTokenOther; while (!map.stream.atEnd()) { quint32 keyType; map.stream >> keyType; @@ -411,6 +415,11 @@ Account::ReadMapResult Account::readMapWith( case lskSearchSuggestions: { map.stream >> searchSuggestionsKey; } break; + case lskWebviewTokens: { + map.stream + >> webviewStorageTokenBots + >> webviewStorageTokenOther; + } break; default: LOG(("App Error: unknown key type in encrypted map: %1").arg(keyType)); return ReadMapResult::Failed; @@ -448,6 +457,8 @@ Account::ReadMapResult Account::readMapWith( _exportSettingsKey = exportSettingsKey; _searchSuggestionsKey = searchSuggestionsKey; _oldMapVersion = mapData.version; + _webviewStorageIdBots.token = webviewStorageTokenBots; + _webviewStorageIdOther.token = webviewStorageTokenOther; if (_oldMapVersion < AppVersion) { writeMapDelayed(); @@ -553,6 +564,12 @@ void Account::writeMap() { mapSize += sizeof(quint32) + 3 * sizeof(quint64); } if (_searchSuggestionsKey) mapSize += sizeof(quint32) + sizeof(quint64); + if (!_webviewStorageIdBots.token.isEmpty() + || !_webviewStorageIdOther.token.isEmpty()) { + mapSize += sizeof(quint32) + + Serialize::bytearraySize(_webviewStorageIdBots.token) + + Serialize::bytearraySize(_webviewStorageIdOther.token); + } EncryptedDescriptor mapData(mapSize); if (!self.isEmpty()) { @@ -616,6 +633,13 @@ void Account::writeMap() { mapData.stream << quint32(lskSearchSuggestions); mapData.stream << quint64(_searchSuggestionsKey); } + if (!_webviewStorageIdBots.token.isEmpty() + || !_webviewStorageIdOther.token.isEmpty()) { + mapData.stream << quint32(lskWebviewTokens); + mapData.stream + << _webviewStorageIdBots.token + << _webviewStorageIdOther.token; + } map.writeEncrypted(mapData, _localKey); _mapChanged = false; @@ -655,11 +679,27 @@ void Account::reset() { _cacheTotalTimeLimit = Database::Settings().totalTimeLimit; _cacheBigFileTotalSizeLimit = Database::Settings().totalSizeLimit; _cacheBigFileTotalTimeLimit = Database::Settings().totalTimeLimit; + + const auto wvbots = _webviewStorageIdBots.path; + const auto wvother = _webviewStorageIdOther.path; + const auto wvclear = [](Webview::StorageId &storageId) { + Webview::ClearStorageDataByToken( + base::take(storageId).token.toStdString()); + }; + wvclear(_webviewStorageIdBots); + wvclear(_webviewStorageIdOther); + _mapChanged = true; writeMap(); writeMtpData(); - crl::async([base = _basePath, temp = _tempPath, names = std::move(names)] { + crl::async([ + base = _basePath, + temp = _tempPath, + names = std::move(names), + wvbots, + wvother + ] { for (const auto &name : names) { if (!name.endsWith(u"map0"_q) && !name.endsWith(u"map1"_q) @@ -669,6 +709,12 @@ void Account::reset() { } } QDir(LegacyTempDirectory()).removeRecursively(); + if (!wvbots.isEmpty()) { + QDir(wvbots).removeRecursively(); + } + if (!wvother.isEmpty()) { + QDir(wvother).removeRecursively(); + } QDir(temp).removeRecursively(); }); @@ -3080,6 +3126,54 @@ bool Account::isBotTrustedOpenWebView(PeerId botId) { && ((i->second & BotTrustFlag::OpenWebView) != 0); } +void Account::enforceModernStorageIdBots() { + if (_webviewStorageIdBots.token.isEmpty()) { + _webviewStorageIdBots.token = QByteArray::fromStdString( + Webview::GenerateStorageToken()); + writeMapDelayed(); + } +} + +Webview::StorageId Account::resolveStorageIdBots() { + if (!_webviewStorageIdBots) { + auto &token = _webviewStorageIdBots.token; + const auto legacy = Webview::LegacyStorageIdToken(); + if (token.isEmpty()) { + auto legacyTaken = false; + const auto &list = _owner->domain().accounts(); + for (const auto &[index, account] : list) { + if (account.get() != _owner.get()) { + const auto &id = account->local()._webviewStorageIdBots; + if (id.token == legacy) { + legacyTaken = true; + break; + } + } + } + token = legacyTaken + ? QByteArray::fromStdString(Webview::GenerateStorageToken()) + : legacy; + writeMapDelayed(); + } + _webviewStorageIdBots.path = (token == legacy) + ? (BaseGlobalPath() + u"webview"_q) + : (_databasePath + u"wvbots"_q); + } + return _webviewStorageIdBots; +} + +Webview::StorageId Account::resolveStorageIdOther() { + if (!_webviewStorageIdOther) { + if (_webviewStorageIdOther.token.isEmpty()) { + _webviewStorageIdOther.token = QByteArray::fromStdString( + Webview::GenerateStorageToken()); + writeMapDelayed(); + } + _webviewStorageIdOther.path = _databasePath + u"wvother"_q; + } + return _webviewStorageIdOther; +} + bool Account::encrypt( const void *src, void *dst, diff --git a/Telegram/SourceFiles/storage/storage_account.h b/Telegram/SourceFiles/storage/storage_account.h index b22dd4cbb..d1314cde2 100644 --- a/Telegram/SourceFiles/storage/storage_account.h +++ b/Telegram/SourceFiles/storage/storage_account.h @@ -12,6 +12,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "storage/cache/storage_cache_database.h" #include "data/stickers/data_stickers_set.h" #include "data/data_drafts.h" +#include "webview/webview_common.h" class History; @@ -169,6 +170,10 @@ public: void markBotTrustedOpenWebView(PeerId botId); [[nodiscard]] bool isBotTrustedOpenWebView(PeerId botId); + void enforceModernStorageIdBots(); + [[nodiscard]] Webview::StorageId resolveStorageIdBots(); + [[nodiscard]] Webview::StorageId resolveStorageIdOther(); + [[nodiscard]] bool encrypt( const void *src, void *dst, @@ -309,6 +314,9 @@ private: bool _recentHashtagsAndBotsWereRead = false; bool _searchSuggestionsRead = false; + Webview::StorageId _webviewStorageIdBots; + Webview::StorageId _webviewStorageIdOther; + int _oldMapVersion = 0; base::Timer _writeMapTimer; diff --git a/Telegram/SourceFiles/storage/storage_domain.cpp b/Telegram/SourceFiles/storage/storage_domain.cpp index 1ea0e0f46..c46594f0e 100644 --- a/Telegram/SourceFiles/storage/storage_domain.cpp +++ b/Telegram/SourceFiles/storage/storage_domain.cpp @@ -268,10 +268,6 @@ void Domain::clearOldVersion() { _oldVersion = 0; } -QString Domain::webviewDataPath() const { - return BaseGlobalPath() + "webview"; -} - rpl::producer<> Domain::localPasscodeChanged() const { return _passcodeKeyChanged.events(); } diff --git a/Telegram/SourceFiles/storage/storage_domain.h b/Telegram/SourceFiles/storage/storage_domain.h index 300833091..eff89b6d5 100644 --- a/Telegram/SourceFiles/storage/storage_domain.h +++ b/Telegram/SourceFiles/storage/storage_domain.h @@ -44,8 +44,6 @@ public: [[nodiscard]] int oldVersion() const; void clearOldVersion(); - [[nodiscard]] QString webviewDataPath() const; - [[nodiscard]] rpl::producer<> localPasscodeChanged() const; [[nodiscard]] bool hasLocalPasscode() const; diff --git a/Telegram/SourceFiles/ui/chat/attach/attach_bot_webview.cpp b/Telegram/SourceFiles/ui/chat/attach/attach_bot_webview.cpp index 262c852d5..a18c86bf2 100644 --- a/Telegram/SourceFiles/ui/chat/attach/attach_bot_webview.cpp +++ b/Telegram/SourceFiles/ui/chat/attach/attach_bot_webview.cpp @@ -313,12 +313,12 @@ Panel::Progress::Progress(QWidget *parent, Fn rect) } Panel::Panel( - const QString &userDataPath, + const Webview::StorageId &storageId, rpl::producer title, not_null delegate, MenuButtons menuButtons, bool allowClipboardRead) -: _userDataPath(userDataPath) +: _storageId(storageId) , _delegate(delegate) , _menuButtons(menuButtons) , _widget(std::make_unique()) @@ -597,7 +597,7 @@ bool Panel::createWebview(const Webview::ThemeParams ¶ms) { container, Webview::WindowConfig{ .opaqueBg = params.opaqueBg, - .userDataPath = _userDataPath, + .storageId = _storageId, }); const auto raw = &_webview->window; @@ -1339,7 +1339,7 @@ rpl::lifetime &Panel::lifetime() { std::unique_ptr Show(Args &&args) { auto result = std::make_unique( - args.userDataPath, + args.storageId, std::move(args.title), args.delegate, args.menuButtons, diff --git a/Telegram/SourceFiles/ui/chat/attach/attach_bot_webview.h b/Telegram/SourceFiles/ui/chat/attach/attach_bot_webview.h index bb22a4dfc..ee1dae837 100644 --- a/Telegram/SourceFiles/ui/chat/attach/attach_bot_webview.h +++ b/Telegram/SourceFiles/ui/chat/attach/attach_bot_webview.h @@ -11,6 +11,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "base/object_ptr.h" #include "base/weak_ptr.h" #include "base/flags.h" +#include "webview/webview_common.h" class QJsonObject; class QJsonValue; @@ -23,7 +24,6 @@ class SeparatePanel; namespace Webview { struct Available; -struct ThemeParams; } // namespace Webview namespace Ui::BotWebView { @@ -72,7 +72,7 @@ public: class Panel final : public base::has_weak_ptr { public: Panel( - const QString &userDataPath, + const Webview::StorageId &storageId, rpl::producer title, not_null delegate, MenuButtons menuButtons, @@ -144,7 +144,7 @@ private: [[nodiscard]] QRect progressRect() const; void setupProgressGeometry(); - QString _userDataPath; + Webview::StorageId _storageId; const not_null _delegate; bool _closeNeedConfirmation = false; bool _hasSettingsButton = false; @@ -172,7 +172,7 @@ private: struct Args { QString url; - QString userDataPath; + Webview::StorageId storageId; rpl::producer title; rpl::producer bottom; not_null delegate; diff --git a/Telegram/SourceFiles/window/themes/window_theme.cpp b/Telegram/SourceFiles/window/themes/window_theme.cpp index b225b321e..450cfe541 100644 --- a/Telegram/SourceFiles/window/themes/window_theme.cpp +++ b/Telegram/SourceFiles/window/themes/window_theme.cpp @@ -35,9 +35,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "ui/style/style_palette_colorizer.h" #include "ui/ui_utility.h" #include "ui/boxes/confirm_box.h" -#include "webview/webview_interface.h" #include "boxes/background_box.h" #include "core/application.h" +#include "webview/webview_common.h" #include "styles/style_widgets.h" #include "styles/style_chat.h" diff --git a/Telegram/lib_webview b/Telegram/lib_webview index 7c346c6b0..9f9bcaaec 160000 --- a/Telegram/lib_webview +++ b/Telegram/lib_webview @@ -1 +1 @@ -Subproject commit 7c346c6b042266b5adb116a2114df1d46b37c03f +Subproject commit 9f9bcaaec922644406faadda4d37014c9dec2dd9