Handle socks internal links.

This commit is contained in:
John Preston 2017-06-27 23:11:38 +03:00
parent 1968ca07de
commit 82912f4a0b
15 changed files with 147 additions and 96 deletions

View File

@ -151,6 +151,8 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
"lng_sure_add_admin_unban" = "This user is currently restricted or banned in this group. Are you sure you want to unban and promote them?";
"lng_sure_ban_admin" = "This user is an admin in this group. Are you sure you want to go ahead and restrict them?";
"lng_sure_ban_user_group" = "Ban {user} in the group?";
"lng_sure_enable_socks" = "Are you sure you want to enable this proxy?\n\nServer: {server}\nPort: {port}\n\nYou can change your proxy server later in the Settings (Connection Type).";
"lng_sure_enable" = "Enable";
"lng_edit_deleted" = "This message was deleted";
"lng_edit_too_long" = "Your message text is too long";

View File

@ -286,9 +286,7 @@ void Application::readClients() {
if (!startUrl.isEmpty()) {
cSetStartUrl(startUrl);
}
if (auto main = App::main()) {
main->checkStartUrl();
}
Messenger::Instance().checkStartUrl();
}
void Application::removeClients() {

View File

@ -20,6 +20,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
*/
#include "boxes/connection_box.h"
#include "boxes/confirm_box.h"
#include "lang/lang_keys.h"
#include "storage/localstorage.h"
#include "mainwidget.h"
@ -30,6 +31,30 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
#include "history/history_location_manager.h"
#include "styles/style_boxes.h"
void ConnectionBox::ShowApplyProxyConfirmation(const QMap<QString, QString> &fields) {
auto server = fields.value(qsl("server"));
auto port = fields.value(qsl("port")).toInt();
if (!server.isEmpty() && port != 0) {
auto weakBox = std::make_shared<QPointer<ConfirmBox>>(nullptr);
auto box = Ui::show(Box<ConfirmBox>(lng_sure_enable_socks(lt_server, server, lt_port, QString::number(port)), lang(lng_sure_enable), [fields, weakBox] {
auto p = ProxyData();
p.host = fields.value(qsl("server"));
p.user = fields.value(qsl("user"));
p.password = fields.value(qsl("pass"));
p.port = fields.value(qsl("port")).toInt();
Global::SetConnectionType(dbictTcpProxy);
Global::SetConnectionProxy(p);
Local::writeSettings();
Global::RefConnectionTypeChanged().notify();
MTP::restart();
reinitLocationManager();
reinitWebLoadManager();
if (*weakBox) (*weakBox)->closeBox();
}), KeepOtherLayers);
*weakBox = box;
}
}
ConnectionBox::ConnectionBox(QWidget *parent)
: _hostInput(this, st::connectionHostInputField, langFactory(lng_connection_host_ph), Global::ConnectionProxy().host)
, _portInput(this, st::connectionPortInputField, langFactory(lng_connection_port_ph), QString::number(Global::ConnectionProxy().port))

View File

@ -39,6 +39,8 @@ class ConnectionBox : public BoxContent {
public:
ConnectionBox(QWidget *parent);
static void ShowApplyProxyConfirmation(const QMap<QString, QString> &fields);
protected:
void prepare() override;
void setInnerFocus() override;

View File

@ -809,7 +809,7 @@ QVector<PeerData*> ShareBox::Inner::selected() const {
return result;
}
QString appendShareGameScoreUrl(const QString &url, const FullMsgId &fullId) {
QString AppendShareGameScoreUrl(const QString &url, const FullMsgId &fullId) {
auto shareHashData = QByteArray(0x10, Qt::Uninitialized);
auto shareHashDataInts = reinterpret_cast<int32*>(shareHashData.data());
auto channel = fullId.channel ? App::channelLoaded(fullId.channel) : static_cast<ChannelData*>(nullptr);
@ -854,7 +854,7 @@ QString appendShareGameScoreUrl(const QString &url, const FullMsgId &fullId) {
namespace {
void shareGameScoreFromItem(HistoryItem *item) {
void ShareGameScoreFromItem(HistoryItem *item) {
struct ShareGameScoreData {
ShareGameScoreData(const FullMsgId &msgId) : msgId(msgId) {
}
@ -949,7 +949,7 @@ void shareGameScoreFromItem(HistoryItem *item) {
} // namespace
void shareGameScoreByHash(const QString &hash) {
void ShareGameScoreByHash(const QString &hash) {
auto key128Size = 0x10;
auto hashEncrypted = QByteArray::fromBase64(hash.toLatin1(), QByteArray::Base64UrlEncoding | QByteArray::OmitTrailingEquals);
@ -1000,12 +1000,12 @@ void shareGameScoreByHash(const QString &hash) {
}
if (auto item = App::histItemById(channelId, msgId)) {
shareGameScoreFromItem(item);
ShareGameScoreFromItem(item);
} else if (App::api()) {
auto resolveMessageAndShareScore = [msgId](ChannelData *channel) {
App::api()->requestMessageData(channel, msgId, [](ChannelData *channel, MsgId msgId) {
if (auto item = App::histItemById(channel, msgId)) {
shareGameScoreFromItem(item);
ShareGameScoreFromItem(item);
} else {
Ui::show(Box<InformBox>(lang(lng_edit_deleted)));
}

View File

@ -37,8 +37,8 @@ namespace Ui {
class MultiSelect;
} // namespace Ui
QString appendShareGameScoreUrl(const QString &url, const FullMsgId &fullId);
void shareGameScoreByHash(const QString &hash);
QString AppendShareGameScoreUrl(const QString &url, const FullMsgId &fullId);
void ShareGameScoreByHash(const QString &hash);
class ShareBox : public BoxContent, public RPCSender {
Q_OBJECT

View File

@ -21,6 +21,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
#include "core/click_handler_types.h"
#include "lang/lang_keys.h"
#include "messenger.h"
#include "platform/platform_specific.h"
#include "boxes/confirm_box.h"
#include "base/qthelp_regex.h"
@ -58,6 +59,8 @@ QString tryConvertUrlToLocal(QString url) {
|| previewedUrl.startsWith(qstr("https://"), Qt::CaseInsensitive)) {
return previewedUrl;
}
} else if (auto socksMatch = regex_match(qsl("socks/?\\?(.+)(#|$)"), query, matchOptions)) {
return qsl("tg://socks?") + socksMatch->captured(1);
} else if (auto usernameMatch = regex_match(qsl("^([a-zA-Z0-9\\.\\_]+)(/?\\?|/?$|/(\\d+)/?(?:\\?|$))"), query, matchOptions)) {
auto params = query.mid(usernameMatch->captured(0).size()).toString();
auto postParam = QString();
@ -83,7 +86,7 @@ void UrlClickHandler::doOpen(QString url) {
url = tryConvertUrlToLocal(url);
if (url.startsWith(qstr("tg://"), Qt::CaseInsensitive)) {
App::openLocalUrl(url);
Messenger::Instance().openLocalUrl(url);
} else {
QDesktopServices::openUrl(url);
}
@ -113,7 +116,7 @@ void HiddenUrlClickHandler::doOpen(QString url) {
auto urlText = tryConvertUrlToLocal(url);
if (urlText.startsWith(qstr("tg://"), Qt::CaseInsensitive)) {
App::openLocalUrl(urlText);
Messenger::Instance().openLocalUrl(urlText);
} else {
auto parsedUrl = QUrl::fromUserInput(urlText);
auto displayUrl = parsedUrl.isValid() ? parsedUrl.toDisplayString() : urlText;
@ -128,7 +131,7 @@ void BotGameUrlClickHandler::onClick(Qt::MouseButton button) const {
auto urlText = tryConvertUrlToLocal(url());
if (urlText.startsWith(qstr("tg://"), Qt::CaseInsensitive)) {
App::openLocalUrl(urlText);
Messenger::Instance().openLocalUrl(urlText);
} else if (!_bot || _bot->isVerified() || Local::isBotTrusted(_bot)) {
doOpen(urlText);
} else {

View File

@ -167,10 +167,6 @@ void stickersBox(const QString &name) {
if (MainWidget *m = main()) m->stickersBox(MTP_inputStickerSetShortName(MTP_string(name)));
}
void openLocalUrl(const QString &url) {
if (MainWidget *m = main()) m->openLocalUrl(url);
}
bool forward(const PeerId &peer, ForwardWhatMessages what) {
if (MainWidget *m = main()) return m->onForward(peer, what);
return false;

View File

@ -73,7 +73,6 @@ void searchByHashtag(const QString &tag, PeerData *inPeer);
void openPeerByName(const QString &username, MsgId msgId = ShowAtUnreadMsgId, const QString &startToken = QString());
void joinGroupByHash(const QString &hash);
void stickersBox(const QString &name);
void openLocalUrl(const QString &url);
bool forward(const PeerId &peer, ForwardWhatMessages what);
void removeDialog(History *history);
void showSettings();

View File

@ -3510,7 +3510,7 @@ void HistoryWidget::botCallbackDone(BotCallbackInfo info, const MTPmessages_BotC
} else if (answerData.has_url()) {
auto url = qs(answerData.vurl);
if (info.game) {
url = appendShareGameScoreUrl(url, info.msgId);
url = AppendShareGameScoreUrl(url, info.msgId);
BotGameUrlClickHandler(info.bot, url).onClick(Qt::LeftButton);
if (item && (!item->history()->peer->isChannel() || item->history()->peer->isMegagroup())) {
updateSendAction(item->history(), SendAction::Type::PlayGame);

View File

@ -51,8 +51,6 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
#include "boxes/sticker_set_box.h"
#include "boxes/contacts_box.h"
#include "boxes/download_path_box.h"
#include "boxes/confirm_phone_box.h"
#include "boxes/share_box.h"
#include "storage/localstorage.h"
#include "shortcuts.h"
#include "media/media_audio.h"
@ -4088,81 +4086,13 @@ void MainWidget::start(const MTPUser *self) {
Local::readSavedGifs();
_history->start();
checkStartUrl();
Messenger::Instance().checkStartUrl();
}
bool MainWidget::started() {
return _started;
}
void MainWidget::checkStartUrl() {
if (!cStartUrl().isEmpty() && App::self() && !App::passcoded()) {
auto url = cStartUrl();
cSetStartUrl(QString());
openLocalUrl(url);
}
}
void MainWidget::openLocalUrl(const QString &url) {
auto urlTrimmed = url.trimmed();
if (urlTrimmed.size() > 8192) urlTrimmed = urlTrimmed.mid(0, 8192);
if (!urlTrimmed.startsWith(qstr("tg://"), Qt::CaseInsensitive)) {
return;
}
auto command = urlTrimmed.midRef(qstr("tg://").size());
using namespace qthelp;
auto matchOptions = RegExOption::CaseInsensitive;
if (auto joinChatMatch = regex_match(qsl("^join/?\\?invite=([a-zA-Z0-9\\.\\_\\-]+)(&|$)"), command, matchOptions)) {
joinGroupByHash(joinChatMatch->captured(1));
} else if (auto stickerSetMatch = regex_match(qsl("^addstickers/?\\?set=([a-zA-Z0-9\\.\\_]+)(&|$)"), command, matchOptions)) {
stickersBox(MTP_inputStickerSetShortName(MTP_string(stickerSetMatch->captured(1))));
} else if (auto shareUrlMatch = regex_match(qsl("^msg_url/?\\?(.+)(#|$)"), command, matchOptions)) {
auto params = url_parse_params(shareUrlMatch->captured(1), UrlParamNameTransform::ToLower);
auto url = params.value(qsl("url"));
if (!url.isEmpty()) {
shareUrlLayer(url, params.value("text"));
}
} else if (auto confirmPhoneMatch = regex_match(qsl("^confirmphone/?\\?(.+)(#|$)"), command, matchOptions)) {
auto params = url_parse_params(confirmPhoneMatch->captured(1), UrlParamNameTransform::ToLower);
auto phone = params.value(qsl("phone"));
auto hash = params.value(qsl("hash"));
if (!phone.isEmpty() && !hash.isEmpty()) {
ConfirmPhoneBox::start(phone, hash);
}
} else if (auto usernameMatch = regex_match(qsl("^resolve/?\\?(.+)(#|$)"), command, matchOptions)) {
auto params = url_parse_params(usernameMatch->captured(1), UrlParamNameTransform::ToLower);
auto domain = params.value(qsl("domain"));
if (regex_match(qsl("^[a-zA-Z0-9\\.\\_]+$"), domain, matchOptions)) {
auto start = qsl("start");
auto startToken = params.value(start);
if (startToken.isEmpty()) {
start = qsl("startgroup");
startToken = params.value(start);
if (startToken.isEmpty()) {
start = QString();
}
}
auto post = (start == qsl("startgroup")) ? ShowAtProfileMsgId : ShowAtUnreadMsgId;
auto postParam = params.value(qsl("post"));
if (auto postId = postParam.toInt()) {
post = postId;
}
auto gameParam = params.value(qsl("game"));
if (!gameParam.isEmpty() && regex_match(qsl("^[a-zA-Z0-9\\.\\_]+$"), gameParam, matchOptions)) {
startToken = gameParam;
post = ShowAtGameShareMsgId;
}
openPeerByName(domain, post, startToken);
}
} else if (auto shareGameScoreMatch = regex_match(qsl("^share_game_score/?\\?(.+)(#|$)"), command, matchOptions)) {
auto params = url_parse_params(shareGameScoreMatch->captured(1), UrlParamNameTransform::ToLower);
shareGameScoreByHash(params.value(qsl("hash")));
}
}
void MainWidget::openPeerByName(const QString &username, MsgId msgId, const QString &startToken) {
App::wnd()->hideMediaview();

View File

@ -168,8 +168,6 @@ public:
void start(const MTPUser *self = nullptr);
void checkStartUrl();
void openLocalUrl(const QString &str);
void openPeerByName(const QString &name, MsgId msgId = ShowAtUnreadMsgId, const QString &startToken = QString());
void joinGroupByHash(const QString &hash);
void stickersBox(const MTPInputStickerSet &set);

View File

@ -218,7 +218,7 @@ void MainWindow::clearPasscode() {
} else {
t_assert(_main != nullptr);
_main->showAnimated(bg, true);
_main->checkStartUrl();
Messenger::Instance().checkStartUrl();
}
}
@ -609,9 +609,7 @@ bool MainWindow::eventFilter(QObject *object, QEvent *e) {
QString url = static_cast<QFileOpenEvent*>(e)->url().toEncoded().trimmed();
if (url.startsWith(qstr("tg://"), Qt::CaseInsensitive)) {
cSetStartUrl(url.mid(0, 8192));
if (_main) {
_main->checkStartUrl();
}
Messenger::Instance().checkStartUrl();
}
activate();
}

View File

@ -45,6 +45,11 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
#include "ui/widgets/tooltip.h"
#include "storage/serialize_common.h"
#include "window/window_controller.h"
#include "base/qthelp_regex.h"
#include "base/qthelp_url.h"
#include "boxes/connection_box.h"
#include "boxes/confirm_phone_box.h"
#include "boxes/share_box.h"
namespace {
@ -651,6 +656,98 @@ QString Messenger::createInternalLinkFull(const QString &query) const {
return Global::InternalLinksDomain() + query;
}
void Messenger::checkStartUrl() {
if (!cStartUrl().isEmpty() && !App::passcoded()) {
auto url = cStartUrl();
cSetStartUrl(QString());
if (!openLocalUrl(url)) {
cSetStartUrl(url);
}
}
}
bool Messenger::openLocalUrl(const QString &url) {
auto urlTrimmed = url.trimmed();
if (urlTrimmed.size() > 8192) urlTrimmed = urlTrimmed.mid(0, 8192);
if (!urlTrimmed.startsWith(qstr("tg://"), Qt::CaseInsensitive) || App::passcoded()) {
return false;
}
auto command = urlTrimmed.midRef(qstr("tg://").size());
using namespace qthelp;
auto matchOptions = RegExOption::CaseInsensitive;
if (auto joinChatMatch = regex_match(qsl("^join/?\\?invite=([a-zA-Z0-9\\.\\_\\-]+)(&|$)"), command, matchOptions)) {
if (auto main = App::main()) {
main->joinGroupByHash(joinChatMatch->captured(1));
return true;
}
} else if (auto stickerSetMatch = regex_match(qsl("^addstickers/?\\?set=([a-zA-Z0-9\\.\\_]+)(&|$)"), command, matchOptions)) {
if (auto main = App::main()) {
main->stickersBox(MTP_inputStickerSetShortName(MTP_string(stickerSetMatch->captured(1))));
return true;
}
} else if (auto shareUrlMatch = regex_match(qsl("^msg_url/?\\?(.+)(#|$)"), command, matchOptions)) {
if (auto main = App::main()) {
auto params = url_parse_params(shareUrlMatch->captured(1), UrlParamNameTransform::ToLower);
auto url = params.value(qsl("url"));
if (!url.isEmpty()) {
main->shareUrlLayer(url, params.value("text"));
return true;
}
}
} else if (auto confirmPhoneMatch = regex_match(qsl("^confirmphone/?\\?(.+)(#|$)"), command, matchOptions)) {
if (auto main = App::main()) {
auto params = url_parse_params(confirmPhoneMatch->captured(1), UrlParamNameTransform::ToLower);
auto phone = params.value(qsl("phone"));
auto hash = params.value(qsl("hash"));
if (!phone.isEmpty() && !hash.isEmpty()) {
ConfirmPhoneBox::start(phone, hash);
return true;
}
}
} else if (auto usernameMatch = regex_match(qsl("^resolve/?\\?(.+)(#|$)"), command, matchOptions)) {
if (auto main = App::main()) {
auto params = url_parse_params(usernameMatch->captured(1), UrlParamNameTransform::ToLower);
auto domain = params.value(qsl("domain"));
if (regex_match(qsl("^[a-zA-Z0-9\\.\\_]+$"), domain, matchOptions)) {
auto start = qsl("start");
auto startToken = params.value(start);
if (startToken.isEmpty()) {
start = qsl("startgroup");
startToken = params.value(start);
if (startToken.isEmpty()) {
start = QString();
}
}
auto post = (start == qsl("startgroup")) ? ShowAtProfileMsgId : ShowAtUnreadMsgId;
auto postParam = params.value(qsl("post"));
if (auto postId = postParam.toInt()) {
post = postId;
}
auto gameParam = params.value(qsl("game"));
if (!gameParam.isEmpty() && regex_match(qsl("^[a-zA-Z0-9\\.\\_]+$"), gameParam, matchOptions)) {
startToken = gameParam;
post = ShowAtGameShareMsgId;
}
main->openPeerByName(domain, post, startToken);
return true;
}
}
} else if (auto shareGameScoreMatch = regex_match(qsl("^share_game_score/?\\?(.+)(#|$)"), command, matchOptions)) {
if (auto main = App::main()) {
auto params = url_parse_params(shareGameScoreMatch->captured(1), UrlParamNameTransform::ToLower);
ShareGameScoreByHash(params.value(qsl("hash")));
return true;
}
} else if (auto socksMatch = regex_match(qsl("^socks/?\\?(.+)(#|$)"), command, matchOptions)) {
auto params = url_parse_params(socksMatch->captured(1), UrlParamNameTransform::ToLower);
ConnectionBox::ShowApplyProxyConfirmation(params);
return true;
}
return false;
}
FileUploader *Messenger::uploader() {
if (!_uploader && !App::quitting()) _uploader = new FileUploader();
return _uploader;

View File

@ -128,9 +128,12 @@ public:
return *_audio;
}
// Internal links.
void setInternalLinkDomain(const QString &domain) const;
QString createInternalLink(const QString &query) const;
QString createInternalLinkFull(const QString &query) const;
void checkStartUrl();
bool openLocalUrl(const QString &url);
FileUploader *uploader();
void uploadProfilePhoto(const QImage &tosend, const PeerId &peerId);