Add confirmation on first webview open.

This commit is contained in:
John Preston 2022-04-06 11:45:51 +04:00
parent 73c5988e7e
commit 646682b6a0
6 changed files with 101 additions and 13 deletions

View File

@ -1720,6 +1720,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_open_link" = "Open";
"lng_allow_bot_pass" = "Allow {bot_name} to pass your Telegram name and ID to the web pages you open via this bot?";
"lng_allow_bot" = "Allow";
"lng_allow_bot_webview" = "{bot_name} would like to open its web app to proceed.\n\nIt will be able to access your **IP address** and basic device info.";
"lng_url_auth_open_confirm" = "Do you want to open {link}?";
"lng_url_auth_login_option" = "Log in to {domain} as {user}";
"lng_url_auth_allow_messages" = "Allow {bot} to send me messages";

View File

@ -224,18 +224,24 @@ void activateBotCommand(
case ButtonType::WebView: {
if (const auto bot = msg->getMessageBot()) {
bot->session().attachWebView().request(
bot,
bot,
{ .text = button->text, .url = button->data });
if (sessionController) {
bot->session().attachWebView().request(
sessionController,
bot,
bot,
{ .text = button->text, .url = button->data });
}
}
} break;
case ButtonType::SimpleWebView: {
if (const auto bot = msg->getMessageBot()) {
bot->session().attachWebView().requestSimple(
bot,
{ .text = button->text, .url = button->data });
if (sessionController) {
bot->session().attachWebView().requestSimple(
sessionController,
bot,
{ .text = button->text, .url = button->data });
}
}
} break;
}

View File

@ -22,6 +22,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/widgets/dropdown_menu.h"
#include "ui/widgets/popup_menu.h"
#include "ui/widgets/menu/menu_item_base.h"
#include "ui/text/text_utilities.h"
#include "ui/effects/ripple_animation.h"
#include "window/themes/window_theme.h"
#include "window/window_controller.h"
@ -31,6 +32,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/basic_click_handlers.h"
#include "history/history.h"
#include "history/history_item.h"
#include "storage/storage_account.h"
#include "lang/lang_keys.h"
#include "base/random.h"
#include "base/timer_rpl.h"
@ -325,6 +327,7 @@ void AttachWebView::request(
}
void AttachWebView::request(
Window::SessionController *controller,
not_null<PeerData*> peer,
not_null<UserData*> bot,
const WebViewButton &button) {
@ -339,7 +342,13 @@ void AttachWebView::request(
_bot = bot;
_peer = peer;
request(button);
if (controller) {
confirmOpen(controller, [=] {
request(button);
});
} else {
request(button);
}
}
void AttachWebView::request(const WebViewButton &button) {
@ -444,7 +453,11 @@ void AttachWebView::requestAddToMenu(
if (!contextPeer) {
return false;
}
request(contextPeer, bot, { .startCommand = startCommand });
request(
nullptr,
contextPeer,
bot,
{ .startCommand = startCommand });
return true;
};
result.match([&](const MTPDattachMenuBotsBot &data) {
@ -529,15 +542,22 @@ void AttachWebView::resolveUsername(
}
void AttachWebView::requestSimple(
not_null<Window::SessionController*> controller,
not_null<UserData*> bot,
const WebViewButton &button) {
cancel();
_bot = bot;
_peer = bot;
confirmOpen(controller, [=] {
requestSimple(button);
});
}
void AttachWebView::requestSimple(const WebViewButton &button) {
using Flag = MTPmessages_RequestSimpleWebView::Flag;
_requestId = _session->api().request(MTPmessages_RequestSimpleWebView(
MTP_flags(Flag::f_theme_params),
bot->inputUser,
_bot->inputUser,
MTP_bytes(button.url),
MTP_dataJSON(MTP_bytes(Window::Theme::WebViewParams()))
)).done([=](const MTPSimpleWebViewResult &result) {
@ -552,6 +572,32 @@ void AttachWebView::requestSimple(
}).send();
}
void AttachWebView::confirmOpen(
not_null<Window::SessionController*> controller,
Fn<void()> done) {
if (!_bot) {
return;
} else if (_bot->isVerified()
|| _bot->session().local().isBotTrustedOpenWebView(_bot->id)) {
done();
return;
}
const auto callback = [=] {
_bot->session().local().markBotTrustedOpenWebView(_bot->id);
controller->hideLayer();
done();
};
controller->show(Ui::MakeConfirmBox({
.text = tr::lng_allow_bot_webview(
tr::now,
lt_bot_name,
Ui::Text::Bold(_bot->name),
Ui::Text::RichLangValue),
.confirmed = callback,
.confirmText = tr::lng_box_ok(),
}));
}
void AttachWebView::ClearAll() {
while (!ActiveWebViews().empty()) {
ActiveWebViews().front()->cancel();
@ -706,7 +752,7 @@ std::unique_ptr<Ui::DropdownMenu> MakeAttachBotsMenu(
const auto callback = [=] {
const auto active = controller->activeChatCurrent();
if (const auto history = active.history()) {
bots->request(history->peer, bot.user, {});
bots->request(nullptr, history->peer, bot.user, {});
}
};
auto action = base::make_unique_q<BotAction>(

View File

@ -56,10 +56,12 @@ public:
const QString &botUsername,
const QString &startCommand);
void request(
Window::SessionController *controller,
not_null<PeerData*> peer,
not_null<UserData*> bot,
const WebViewButton &button);
void requestSimple(
not_null<Window::SessionController*> controller,
not_null<UserData*> bot,
const WebViewButton &button);
@ -84,10 +86,15 @@ public:
private:
void resolve();
void request(const WebViewButton &button);
void requestSimple(const WebViewButton &button);
void resolveUsername(
const QString &username,
Fn<void(not_null<PeerData*>)> done);
void confirmOpen(
not_null<Window::SessionController*> controller,
Fn<void()> done);
void toggleInMenu(
not_null<UserData*> bot,
bool enabled,

View File

@ -2797,6 +2797,31 @@ bool Account::isBotTrustedPayment(PeerId botId) {
&& ((i->second & BotTrustFlag::Payment) != 0);
}
void Account::markBotTrustedOpenWebView(PeerId botId) {
if (isBotTrustedOpenWebView(botId)) {
return;
}
const auto i = _trustedBots.find(botId);
if (i == end(_trustedBots)) {
_trustedBots.emplace(
botId,
BotTrustFlag::NoOpenGame | BotTrustFlag::OpenWebView);
} else {
i->second |= BotTrustFlag::OpenWebView;
}
writeTrustedBots();
}
bool Account::isBotTrustedOpenWebView(PeerId botId) {
if (!_trustedBotsRead) {
readTrustedBots();
_trustedBotsRead = true;
}
const auto i = _trustedBots.find(botId);
return (i != end(_trustedBots))
&& ((i->second & BotTrustFlag::OpenWebView) != 0);
}
bool Account::encrypt(
const void *src,
void *dst,

View File

@ -157,6 +157,8 @@ public:
[[nodiscard]] bool isBotTrustedOpenGame(PeerId botId);
void markBotTrustedPayment(PeerId botId);
[[nodiscard]] bool isBotTrustedPayment(PeerId botId);
void markBotTrustedOpenWebView(PeerId botId);
[[nodiscard]] bool isBotTrustedOpenWebView(PeerId botId);
[[nodiscard]] bool encrypt(
const void *src,
@ -178,8 +180,9 @@ private:
Failed,
};
enum class BotTrustFlag : uchar {
NoOpenGame = (1 << 0),
Payment = (1 << 1),
NoOpenGame = (1 << 0),
Payment = (1 << 1),
OpenWebView = (1 << 2),
};
friend inline constexpr bool is_flag_type(BotTrustFlag) { return true; };