From 65f7bdb91411e5f03fb97df7b5f1f5b3adb01069 Mon Sep 17 00:00:00 2001 From: John Preston Date: Sun, 30 Jun 2024 21:13:25 +0400 Subject: [PATCH] Update API scheme on layer 183. --- .../inline_bots/bot_attach_web_view.cpp | 79 +++++++++++++++---- .../inline_bots/bot_attach_web_view.h | 4 + Telegram/SourceFiles/mtproto/scheme/api.tl | 12 +-- .../ui/chat/attach/attach_bot_webview.cpp | 3 +- .../ui/chat/attach/attach_bot_webview.h | 1 + 5 files changed, 75 insertions(+), 24 deletions(-) diff --git a/Telegram/SourceFiles/inline_bots/bot_attach_web_view.cpp b/Telegram/SourceFiles/inline_bots/bot_attach_web_view.cpp index 68da29a3a..eb938ed26 100644 --- a/Telegram/SourceFiles/inline_bots/bot_attach_web_view.cpp +++ b/Telegram/SourceFiles/inline_bots/bot_attach_web_view.cpp @@ -9,6 +9,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "api/api_blocked_peers.h" #include "api/api_common.h" +#include "base/qthelp_url.h" #include "core/click_handler_types.h" #include "data/data_bot_app.h" #include "data/data_changes.h" @@ -18,6 +19,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "data/data_document_media.h" #include "data/data_session.h" #include "data/data_web_page.h" +#include "main/main_app_config.h" #include "main/main_session.h" #include "main/main_domain.h" #include "storage/storage_domain.h" @@ -664,6 +666,19 @@ void AttachWebView::botHandleMenuButton(Ui::BotWebView::MenuButton button) { } } +bool AttachWebView::botValidateExternalLink(QString uri) { + const auto lower = uri.toLower(); + const auto allowed = _session->appConfig().get>( + "web_app_allowed_protocols", + std::vector{ u"http"_q, u"https"_q }); + for (const auto &protocol : allowed) { + if (lower.startsWith(protocol + u"://"_q)) { + return true; + } + } + return false; +} + void AttachWebView::botOpenIvLink(QString uri) { const auto window = _context ? _context->controller.get() : nullptr; if (window) { @@ -895,7 +910,7 @@ void AttachWebView::request(const WebViewButton &button) { _requestId = 0; const auto &data = result.data(); show( - data.vquery_id().v, + data.vquery_id().value_or_empty(), qs(data.vurl()), button.text, button.fromAttachMenu || button.url.isEmpty()); @@ -1208,25 +1223,61 @@ void AttachWebView::requestSimple(const WebViewButton &button) { MTP_string(button.startCommand), MTP_dataJSON(MTP_bytes(Window::Theme::WebViewParams().json)), MTP_string("tdesktop") - )).done([=](const MTPSimpleWebViewResult &result) { + )).done([=](const MTPWebViewResult &result) { _requestId = 0; - result.match([&](const MTPDsimpleWebViewResultUrl &data) { - show( - uint64(), - qs(data.vurl()), - button.text, - false, - nullptr, - button.fromMainMenu); - }); + const auto &data = result.data(); + const auto queryId = uint64(); + show( + queryId, + qs(data.vurl()), + button.text, + false, + nullptr, + button.fromMainMenu); }).fail([=](const MTP::Error &error) { _requestId = 0; }).send(); } -void AttachWebView::requestMenu( +bool AttachWebView::openAppFromMenuLink( not_null controller, not_null bot) { + Expects(bot->botInfo != nullptr); + + const auto &url = bot->botInfo->botMenuButtonUrl; + const auto local = Core::TryConvertUrlToLocal(url); + const auto prefix = u"tg://resolve?"_q; + if (!local.startsWith(prefix)) { + return false; + } + const auto params = qthelp::url_parse_params( + local.mid(prefix.size()), + qthelp::UrlParamNameTransform::ToLower); + const auto domainParam = params.value(u"domain"_q); + const auto appnameParam = params.value(u"appname"_q); + const auto webChannelPreviewLink = (domainParam == u"s"_q) + && !appnameParam.isEmpty(); + const auto appname = webChannelPreviewLink ? QString() : appnameParam; + if (appname.isEmpty()) { + return false; + } + requestApp( + controller, + Api::SendAction(bot->owner().history(bot)), + bot, + appname, + params.value(u"startapp"_q), + true); + return true; +} + +void AttachWebView::requestMenu( + not_null controller, + not_null bot) { + if (openAppFromMenuLink(controller, bot)) { + return; + } + cancel(); _bot = bot; _context = std::make_unique(LookupContext( @@ -1257,7 +1308,7 @@ void AttachWebView::requestMenu( )).done([=](const MTPWebViewResult &result) { _requestId = 0; const auto &data = result.data(); - show(data.vquery_id().v, qs(data.vurl()), text); + show(data.vquery_id().value_or_empty(), qs(data.vurl()), text); }).fail([=](const MTP::Error &error) { _requestId = 0; if (error.type() == u"BOT_INVALID"_q) { @@ -1380,7 +1431,7 @@ void AttachWebView::requestAppView(bool allowWrite) { MTP_string(_startCommand), MTP_dataJSON(MTP_bytes(Window::Theme::WebViewParams().json)), MTP_string("tdesktop") - )).done([=](const MTPAppWebViewResult &result) { + )).done([=](const MTPWebViewResult &result) { _requestId = 0; const auto &data = result.data(); const auto queryId = uint64(); diff --git a/Telegram/SourceFiles/inline_bots/bot_attach_web_view.h b/Telegram/SourceFiles/inline_bots/bot_attach_web_view.h index aebf99332..0f8cb6e13 100644 --- a/Telegram/SourceFiles/inline_bots/bot_attach_web_view.h +++ b/Telegram/SourceFiles/inline_bots/bot_attach_web_view.h @@ -165,6 +165,7 @@ private: bool botHandleLocalUri(QString uri, bool keepOpen) override; void botHandleInvoice(QString slug) override; void botHandleMenuButton(Ui::BotWebView::MenuButton button) override; + bool botValidateExternalLink(QString uri) override; void botOpenIvLink(QString uri) override; void botSendData(QByteArray data) override; void botSwitchInlineQuery( @@ -184,6 +185,9 @@ private: const std::unique_ptr &a, const Context &b); + bool openAppFromMenuLink( + not_null controller, + not_null bot); void requestWithOptionalConfirm( not_null bot, const WebViewButton &button, diff --git a/Telegram/SourceFiles/mtproto/scheme/api.tl b/Telegram/SourceFiles/mtproto/scheme/api.tl index 91b310021..7b8700811 100644 --- a/Telegram/SourceFiles/mtproto/scheme/api.tl +++ b/Telegram/SourceFiles/mtproto/scheme/api.tl @@ -1424,9 +1424,7 @@ attachMenuBots#3c4301c0 hash:long bots:Vector users:Vector attachMenuBotsBot#93bf667f bot:AttachMenuBot users:Vector = AttachMenuBotsBot; -webViewResultUrl#c14557c query_id:long url:string = WebViewResult; - -simpleWebViewResultUrl#882f76bb url:string = SimpleWebViewResult; +webViewResultUrl#4d22ff98 flags:# fullsize:flags.1?true query_id:flags.0?long url:string = WebViewResult; webViewMessageSent#c94511c flags:# msg_id:flags.0?InputBotInlineMessageID = WebViewMessageSent; @@ -1556,8 +1554,6 @@ botApp#95fcd1d6 flags:# id:long access_hash:long short_name:string title:string messages.botApp#eb50adf5 flags:# inactive:flags.0?true request_write_access:flags.1?true has_settings:flags.2?true app:BotApp = messages.BotApp; -appWebViewResultUrl#3c1b4f0d url:string = AppWebViewResult; - inlineBotWebView#b57295d5 text:string url:string = InlineBotWebView; readParticipantDate#4a4ff172 user_id:long date:int = ReadParticipantDate; @@ -2172,9 +2168,9 @@ messages.searchSentMedia#107e31a0 q:string filter:MessagesFilter limit:int = mes messages.getAttachMenuBots#16fcc2cb hash:long = AttachMenuBots; messages.getAttachMenuBot#77216192 bot:InputUser = AttachMenuBotsBot; messages.toggleBotInAttachMenu#69f59d69 flags:# write_allowed:flags.0?true bot:InputUser enabled:Bool = Bool; -messages.requestWebView#269dc2c1 flags:# from_bot_menu:flags.4?true silent:flags.5?true peer:InputPeer bot:InputUser url:flags.1?string start_param:flags.3?string theme_params:flags.2?DataJSON platform:string reply_to:flags.0?InputReplyTo send_as:flags.13?InputPeer = WebViewResult; +messages.requestWebView#269dc2c1 flags:# from_bot_menu:flags.4?true silent:flags.5?true compact:flags.7?true peer:InputPeer bot:InputUser url:flags.1?string start_param:flags.3?string theme_params:flags.2?DataJSON platform:string reply_to:flags.0?InputReplyTo send_as:flags.13?InputPeer = WebViewResult; messages.prolongWebView#b0d81a83 flags:# silent:flags.5?true peer:InputPeer bot:InputUser query_id:long reply_to:flags.0?InputReplyTo send_as:flags.13?InputPeer = Bool; -messages.requestSimpleWebView#1a46500a flags:# from_switch_webview:flags.1?true from_side_menu:flags.2?true bot:InputUser url:flags.3?string start_param:flags.4?string theme_params:flags.0?DataJSON platform:string = SimpleWebViewResult; +messages.requestSimpleWebView#413a3e73 flags:# from_switch_webview:flags.1?true from_side_menu:flags.2?true compact:flags.7?true bot:InputUser url:flags.3?string start_param:flags.4?string theme_params:flags.0?DataJSON platform:string = WebViewResult; messages.sendWebViewResultMessage#a4314f5 bot_query_id:string result:InputBotInlineResult = WebViewMessageSent; messages.sendWebViewData#dc0242c8 bot:InputUser random_id:long button_text:string data:string = Updates; messages.transcribeAudio#269e9a49 peer:InputPeer msg_id:int = messages.TranscribedAudio; @@ -2196,7 +2192,7 @@ messages.getEmojiProfilePhotoGroups#21a548f3 hash:int = messages.EmojiGroups; messages.searchCustomEmoji#2c11c0d7 emoticon:string hash:long = EmojiList; messages.togglePeerTranslations#e47cb579 flags:# disabled:flags.0?true peer:InputPeer = Bool; messages.getBotApp#34fdc5c3 app:InputBotApp hash:long = messages.BotApp; -messages.requestAppWebView#8c5a3b3c flags:# write_allowed:flags.0?true peer:InputPeer app:InputBotApp start_param:flags.1?string theme_params:flags.2?DataJSON platform:string = AppWebViewResult; +messages.requestAppWebView#53618bce flags:# write_allowed:flags.0?true compact:flags.7?true peer:InputPeer app:InputBotApp start_param:flags.1?string theme_params:flags.2?DataJSON platform:string = WebViewResult; messages.setChatWallPaper#8ffacae1 flags:# for_both:flags.3?true revert:flags.4?true peer:InputPeer wallpaper:flags.0?InputWallPaper settings:flags.2?WallPaperSettings id:flags.1?int = Updates; messages.searchEmojiStickerSets#92b4494c flags:# exclude_featured:flags.0?true q:string hash:long = messages.FoundStickerSets; messages.getSavedDialogs#5381d21a flags:# exclude_pinned:flags.0?true offset_date:int offset_id:int offset_peer:InputPeer limit:int hash:long = messages.SavedDialogs; diff --git a/Telegram/SourceFiles/ui/chat/attach/attach_bot_webview.cpp b/Telegram/SourceFiles/ui/chat/attach/attach_bot_webview.cpp index 3fbe6e484..5e9dde92e 100644 --- a/Telegram/SourceFiles/ui/chat/attach/attach_bot_webview.cpp +++ b/Telegram/SourceFiles/ui/chat/attach/attach_bot_webview.cpp @@ -803,8 +803,7 @@ void Panel::openExternalLink(const QJsonObject &args) { } const auto iv = args["try_instant_view"].toBool(); const auto url = args["url"].toString(); - const auto lower = url.toLower(); - if (!lower.startsWith("http://") && !lower.startsWith("https://")) { + if (!_delegate->botValidateExternalLink(url)) { LOG(("BotWebView Error: Bad url in openExternalLink: %1").arg(url)); _delegate->botClose(); return; diff --git a/Telegram/SourceFiles/ui/chat/attach/attach_bot_webview.h b/Telegram/SourceFiles/ui/chat/attach/attach_bot_webview.h index fb0231a01..91e423279 100644 --- a/Telegram/SourceFiles/ui/chat/attach/attach_bot_webview.h +++ b/Telegram/SourceFiles/ui/chat/attach/attach_bot_webview.h @@ -57,6 +57,7 @@ public: virtual bool botHandleLocalUri(QString uri, bool keepOpen) = 0; virtual void botHandleInvoice(QString slug) = 0; virtual void botHandleMenuButton(MenuButton button) = 0; + virtual bool botValidateExternalLink(QString uri) = 0; virtual void botOpenIvLink(QString uri) = 0; virtual void botSendData(QByteArray data) = 0; virtual void botSwitchInlineQuery(