diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index baef5d7d8..97da59211 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -3016,6 +3016,10 @@ internalLinkTypeMessage = InternalLinkType; //@text Message draft text @contains_link True, if the first line of the text contains a link. If true, the input field needs to be focused and the text after the link should be selected internalLinkTypeMessageDraft text:formattedText contains_link:Bool = InternalLinkType; +//@description The link can be used to confirm ownership of a phone number to prevent account deletion. Call sendPhoneNumberConfirmationCode with the given hash and phone number to process the link +//@hash Hash value from the link @phone_number Phone number value from the link +internalLinkTypePhoneNumberConfirmation hash:string phone_number:string = InternalLinkType; + //@description The link can be used to login the current user on another device, but it must be scanned from QR-code using in-app camera. An alert similar to //-"This code can be used to allow someone to log in to your Telegram account. To confirm Telegram login, please go to Settings > Devices > Scan QR and scan the code" needs to be shown internalLinkTypeQrCodeAuthentication = InternalLinkType; @@ -5212,8 +5216,7 @@ getPassportAuthorizationFormAvailableElements autorization_form_id:int32 passwor sendPassportAuthorizationForm autorization_form_id:int32 types:vector = Ok; -//@description Sends phone number confirmation code. Should be called when user presses "https://t.me/confirmphone?phone=*******&hash=**********" or "tg://confirmphone?phone=*******&hash=**********" link @hash Value of the "hash" parameter from the link -//@phone_number Value of the "phone" parameter from the link @settings Settings for the authentication of the user's phone number +//@description Sends phone number confirmation code to handle links of the type internalLinkTypePhoneNumberConfirmation @hash Hash value from the link @phone_number Phone number value from the link @settings Settings for the authentication of the user's phone number sendPhoneNumberConfirmationCode hash:string phone_number:string settings:phoneNumberAuthenticationSettings = AuthenticationCodeInfo; //@description Resends phone number confirmation code diff --git a/td/telegram/LinkManager.cpp b/td/telegram/LinkManager.cpp index 662219804..bae4020b7 100644 --- a/td/telegram/LinkManager.cpp +++ b/td/telegram/LinkManager.cpp @@ -55,6 +55,24 @@ class LinkManager::InternalLinkBackground : public InternalLink { } }; +class LinkManager::InternalLinkConfirmPhone : public InternalLink { + string hash_; + string phone_number_; + + td_api::object_ptr get_internal_link_type_object() const final { + return td_api::make_object(hash_, phone_number_); + } + + InternalLinkType get_type() const final { + return InternalLinkType::ConfirmPhone; + } + + public: + InternalLinkConfirmPhone(string hash, string phone_number) + : hash_(std::move(hash)), phone_number_(std::move(phone_number)) { + } +}; + class LinkManager::InternalLinkDialogInvite : public InternalLink { td_api::object_ptr get_internal_link_type_object() const final { return td_api::make_object(); @@ -426,9 +444,12 @@ unique_ptr LinkManager::parse_tg_link_query(Slice que auto copy_arg = [&](Slice name) { return CopyArg(name, &url_query, &is_first_arg); }; - auto get_arg = [&](Slice name) { + auto pass_arg = [&](Slice name) { return url_encode(url_query.get_arg(name)); }; + auto get_arg = [&](Slice name) { + return url_query.get_arg(name).str(); + }; auto has_arg = [&](Slice name) { return !url_query.get_arg(name).empty(); }; @@ -457,6 +478,11 @@ unique_ptr LinkManager::parse_tg_link_query(Slice que if (has_arg("set")) { return td::make_unique(get_arg("set")); } + } else if (path.size() == 1 && path[0] == "confirmphone") { + if (has_arg("hash") && has_arg("phone")) { + // confirmphone?phone=&hash= + return td::make_unique(get_arg("hash"), get_arg("phone")); + } } else if (path.size() == 1 && path[0] == "privatepost") { // privatepost?channel=123456789&msg_id=12345 if (has_arg("channel") && has_arg("msg_id")) { @@ -469,20 +495,20 @@ unique_ptr LinkManager::parse_tg_link_query(Slice que // bg?slug=&mode=blur+motion // bg?slug=&intensity=...&bg_color=...&mode=blur+motion if (has_arg("color")) { - return td::make_unique(get_arg("color")); + return td::make_unique(pass_arg("color")); } if (has_arg("gradient")) { - return td::make_unique(PSTRING() << get_arg("gradient") << copy_arg("rotation")); + return td::make_unique(PSTRING() << pass_arg("gradient") << copy_arg("rotation")); } if (has_arg("slug")) { return td::make_unique(PSTRING() - << get_arg("slug") << copy_arg("mode") << copy_arg("intensity") + << pass_arg("slug") << copy_arg("mode") << copy_arg("intensity") << copy_arg("bg_color") << copy_arg("rotation")); } } else if (path.size() == 1 && (path[0] == "share" || path[0] == "msg" || path[0] == "msg_url")) { // msg_url?url= // msg_url?url=&text= - return get_internal_link_message_draft(url_query.get_arg("url"), url_query.get_arg("text")); + return get_internal_link_message_draft(get_arg("url"), get_arg("text")); } if (!path.empty()) { return td::make_unique(); @@ -502,8 +528,12 @@ unique_ptr LinkManager::parse_t_me_link_query(Slice q auto copy_arg = [&](Slice name) { return CopyArg(name, &url_query, &is_first_arg); }; + auto get_arg = [&](Slice name) { - return url_encode(url_query.get_arg(name)); + return url_query.get_arg(name).str(); + }; + auto has_arg = [&](Slice name) { + return !url_query.get_arg(name).empty(); }; if (path[0] == "c") { @@ -526,6 +556,11 @@ unique_ptr LinkManager::parse_t_me_link_query(Slice q // /addstickers/ return td::make_unique(path[1]); } + } else if (path[0] == "confirmphone") { + if (has_arg("hash") && has_arg("phone")) { + // /confirmphone?phone=&hash= + return td::make_unique(get_arg("hash"), get_arg("phone")); + } } else if (path[0][0] == ' ' || path[0][0] == '+') { if (path[0].size() >= 2) { // /+ @@ -546,7 +581,7 @@ unique_ptr LinkManager::parse_t_me_link_query(Slice q if (!(path.size() > 1 && (path[1] == "bookmarklet" || path[1] == "embed"))) { // /share?url= // /share/url?url=&text= - return get_internal_link_message_draft(url_query.get_arg("url"), url_query.get_arg("text")); + return get_internal_link_message_draft(get_arg("url"), get_arg("text")); } } else { if (path.size() >= 2 && to_integer(path[1]) > 0) { diff --git a/td/telegram/LinkManager.h b/td/telegram/LinkManager.h index 11ecb4abe..b996a1744 100644 --- a/td/telegram/LinkManager.h +++ b/td/telegram/LinkManager.h @@ -37,6 +37,7 @@ class LinkManager : public Actor { enum class InternalLinkType : int32 { AuthenticationCode, Background, + ConfirmPhone, DialogInvite, Message, MessageDraft, @@ -85,6 +86,7 @@ class LinkManager : public Actor { class InternalLinkAuthenticationCode; class InternalLinkBackground; + class InternalLinkConfirmPhone; class InternalLinkDialogInvite; class InternalLinkMessage; class InternalLinkMessageDraft; diff --git a/test/link.cpp b/test/link.cpp index ed0a5e801..8eb4d0669 100644 --- a/test/link.cpp +++ b/test/link.cpp @@ -81,6 +81,9 @@ TEST(Link, parse_internal_link) { formatted_text->text_ = std::move(text); return td::td_api::make_object(std::move(formatted_text), contains_url); }; + auto phone_number_confirmation = [](td::string hash, td::string phone_number) { + return td::td_api::make_object(hash, phone_number); + }; auto qr_code_authentication = []() { return td::td_api::make_object(); }; @@ -293,13 +296,28 @@ TEST(Link, parse_internal_link) { parse_internal_link("t.me/addstickers?/abcdef", nullptr); parse_internal_link("t.me/addstickers/?abcdef", nullptr); parse_internal_link("t.me/addstickers/#abcdef", nullptr); - parse_internal_link("t.me/addstickers/abacaba", sticker_set()); - parse_internal_link("t.me/addstickers/aba%20aba", sticker_set()); - parse_internal_link("t.me/addstickers/123456a", sticker_set()); - parse_internal_link("t.me/addstickers/12345678901", sticker_set()); - parse_internal_link("t.me/addstickers/123456", sticker_set()); - parse_internal_link("t.me/addstickers/123456/123123/12/31/a/s//21w/?asdas#test", sticker_set()); + parse_internal_link("t.me/addstickers/abacaba", sticker_set("abacaba")); + parse_internal_link("t.me/addstickers/aba%20aba", sticker_set("aba aba")); + parse_internal_link("t.me/addstickers/123456a", sticker_set("123456a")); + parse_internal_link("t.me/addstickers/12345678901", sticker_set("12345678901")); + parse_internal_link("t.me/addstickers/123456", sticker_set("123456")); + parse_internal_link("t.me/addstickers/123456/123123/12/31/a/s//21w/?asdas#test", sticker_set("123456")); - parse_internal_link("tg:addstickers?set=abcdef", sticker_set()); + parse_internal_link("tg:addstickers?set=abcdef", sticker_set("abcdef")); + parse_internal_link("tg:addstickers?set=abc%30ef", sticker_set("abc0ef")); parse_internal_link("tg://addstickers?set=", unknown_deep_link()); + + parse_internal_link("t.me/confirmphone?hash=abc%30ef&phone=", nullptr); + parse_internal_link("t.me/confirmphone/123456/123123/12/31/a/s//21w/?hash=abc%30ef&phone=123456789", + phone_number_confirmation("abc0ef", "123456789")); + parse_internal_link("t.me/confirmphone?hash=abc%30ef&phone=123456789", + phone_number_confirmation("abc0ef", "123456789")); + + parse_internal_link("tg:confirmphone?hash=abc%30ef&phone=", unknown_deep_link()); + parse_internal_link("tg:confirmphone?hash=abc%30ef&phone=123456789", + phone_number_confirmation("abc0ef", "123456789")); + parse_internal_link("tg://confirmphone?hash=123&phone=123456789123456789", + phone_number_confirmation("123", "123456789123456789")); + parse_internal_link("tg://confirmphone?hash=&phone=123456789123456789", unknown_deep_link()); + parse_internal_link("tg://confirmphone?hash=123456789123456789&phone=", unknown_deep_link()); }