/* 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 */ #include "boxes/url_auth_box.h" #include "history/history.h" #include "history/history_item.h" #include "history/history_item_components.h" #include "data/data_session.h" #include "data/data_user.h" #include "core/click_handler_types.h" #include "ui/wrap/vertical_layout.h" #include "ui/widgets/checkbox.h" #include "ui/widgets/labels.h" #include "lang/lang_keys.h" #include "auth_session.h" #include "apiwrap.h" #include "styles/style_boxes.h" void UrlAuthBox::Activate( not_null message, int row, int column) { const auto itemId = message->fullId(); const auto button = HistoryMessageMarkupButton::Get(itemId, row, column); if (button->requestId || !IsServerMsgId(itemId.msg)) { return; } const auto session = &message->history()->session(); const auto inputPeer = message->history()->peer->input; const auto buttonId = button->buttonId; const auto url = QString::fromUtf8(button->data); button->requestId = session->api().request(MTPmessages_RequestUrlAuth( inputPeer, MTP_int(itemId.msg), MTP_int(buttonId) )).done([=](const MTPUrlAuthResult &result) { const auto button = HistoryMessageMarkupButton::Get( itemId, row, column); if (!button) return; button->requestId = 0; result.match([&](const MTPDurlAuthResultAccepted &data) { UrlClickHandler::Open(qs(data.vurl)); }, [&](const MTPDurlAuthResultDefault &data) { HiddenUrlClickHandler::Open(url); }, [&](const MTPDurlAuthResultRequest &data) { Request(data, session->data().message(itemId), row, column); }); }).fail([=](const RPCError &error) { const auto button = HistoryMessageMarkupButton::Get( itemId, row, column); if (!button) return; button->requestId = 0; HiddenUrlClickHandler::Open(url); }).send(); } void UrlAuthBox::Request( const MTPDurlAuthResultRequest &request, not_null message, int row, int column) { const auto itemId = message->fullId(); const auto button = HistoryMessageMarkupButton::Get(itemId, row, column); if (button->requestId || !IsServerMsgId(itemId.msg)) { return; } const auto session = &message->history()->session(); const auto inputPeer = message->history()->peer->input; const auto buttonId = button->buttonId; const auto url = QString::fromUtf8(button->data); const auto bot = request.is_request_write_access() ? session->data().processUser(request.vbot).get() : nullptr; const auto box = std::make_shared>(); const auto finishWithUrl = [=](const QString &url) { if (*box) { (*box)->closeBox(); } UrlClickHandler::Open(url); }; const auto callback = [=](Result result) { if (result == Result::None) { finishWithUrl(url); } else if (const auto msg = session->data().message(itemId)) { const auto allowWrite = (result == Result::AuthAndAllowWrite); using Flag = MTPmessages_AcceptUrlAuth::Flag; session->api().request(MTPmessages_AcceptUrlAuth( MTP_flags(allowWrite ? Flag::f_write_allowed : Flag(0)), inputPeer, MTP_int(itemId.msg), MTP_int(buttonId) )).done([=](const MTPUrlAuthResult &result) { const auto to = result.match( [&](const MTPDurlAuthResultAccepted &data) { return qs(data.vurl); }, [&](const MTPDurlAuthResultDefault &data) { return url; }, [&](const MTPDurlAuthResultRequest &data) { LOG(("API Error: " "got urlAuthResultRequest after acceptUrlAuth.")); return url; }); finishWithUrl(to); }).fail([=](const RPCError &error) { finishWithUrl(url); }).send(); } }; *box = Ui::show( Box(url, qs(request.vdomain), bot, callback), LayerOption::KeepOther); } UrlAuthBox::UrlAuthBox( QWidget*, const QString &url, const QString &domain, UserData *bot, Fn callback) : _content(setupContent(url, domain, bot, std::move(callback))) { } void UrlAuthBox::prepare() { setDimensionsToContent(st::boxWidth, _content); addButton(langFactory(lng_open_link), [=] { _callback(); }); addButton(langFactory(lng_cancel), [=] { closeBox(); }); } not_null UrlAuthBox::setupContent( const QString &url, const QString &domain, UserData *bot, Fn callback) { const auto result = Ui::CreateChild(this); result->add( object_ptr( result, lng_url_auth_open_confirm(lt_link, url), Ui::FlatLabel::InitType::Simple, st::boxLabel), st::boxPadding); const auto addCheckbox = [&](const QString &text) { const auto checkbox = result->add( object_ptr( result, QString(), true, st::urlAuthCheckbox), style::margins( st::boxPadding.left(), st::boxPadding.bottom(), st::boxPadding.right(), st::boxPadding.bottom())); checkbox->setAllowMultiline(true); checkbox->setText(text, true); return checkbox; }; const auto auth = addCheckbox( lng_url_auth_login_option( lt_domain, textcmdStartSemibold() + domain + textcmdStopSemibold(), lt_user, (textcmdStartSemibold() + App::peerName(Auth().user()) + textcmdStopSemibold()))); const auto allow = bot ? addCheckbox(lng_url_auth_allow_messages( lt_bot, textcmdStartSemibold() + bot->firstName + textcmdStopSemibold())) : nullptr; if (allow) { rpl::single( auth->checked() ) | rpl::then( auth->checkedChanges() ) | rpl::start_with_next([=](bool checked) { if (!checked) { allow->setChecked(false); } allow->setDisabled(!checked); }, auth->lifetime()); } _callback = [=, callback = std::move(callback)]() { const auto authed = auth->checked(); const auto allowed = (authed && allow && allow->checked()); const auto onstack = callback; onstack(allowed ? Result::AuthAndAllowWrite : authed ? Result::Auth : Result::None); }; return result; }