diff options
| author | levlam <levlam@telegram.org> | 2026-02-15 01:01:48 +0300 |
|---|---|---|
| committer | levlam <levlam@telegram.org> | 2026-02-15 01:01:48 +0300 |
| commit | 9756091daadcf79005ac62e1c064c24407944821 (patch) | |
| tree | d61f7a26f900b51f9e80109de871ac93a99dc6a2 | |
| parent | c3ce0d0e8e62a7e3bf695081a561646dcfc68990 (diff) | |
Add td_api::internalLinkTypeOauth.
| -rw-r--r-- | td/generate/scheme/td_api.tl | 5 | ||||
| -rw-r--r-- | td/telegram/LinkManager.cpp | 32 | ||||
| -rw-r--r-- | td/telegram/LinkManager.h | 1 | ||||
| -rw-r--r-- | test/link.cpp | 11 |
4 files changed, 45 insertions, 4 deletions
diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index e5bc77371..d13dcc861 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -8707,6 +8707,11 @@ internalLinkTypeNewPrivateChat = InternalLinkType; //@description The link is a link to open the story posting interface @content_type The type of the content of the story to post; may be null if unspecified internalLinkTypeNewStory content_type:StoryContentType = InternalLinkType; +//@description The link is an OAuth link. Call getOauthLinkInfo with the given URL to process the link, then show the user confirmation dialog and +//-call either acceptOauthRequest or declineOauthRequest +//@url URL to be passed to getOauthLinkInfo +internalLinkTypeOauth url:string = InternalLinkType; + //@description The link contains a request of Telegram passport data. Call getPassportAuthorizationForm with the given parameters to process the link if the link was received from outside of the application; otherwise, ignore it //@bot_user_id User identifier of the service's bot; the corresponding user may be unknown yet //@scope Telegram Passport element types requested by the service diff --git a/td/telegram/LinkManager.cpp b/td/telegram/LinkManager.cpp index e41e130f7..841ea9490 100644 --- a/td/telegram/LinkManager.cpp +++ b/td/telegram/LinkManager.cpp @@ -957,6 +957,18 @@ class LinkManager::InternalLinkNewPrivateChat final : public InternalLink { } }; +class LinkManager::InternalLinkOauth final : public InternalLink { + string url_; + + td_api::object_ptr<td_api::InternalLinkType> get_internal_link_type_object() const final { + return td_api::make_object<td_api::internalLinkTypeOauth>(url_); + } + + public: + explicit InternalLinkOauth(string url) : url_(std::move(url)) { + } +}; + class LinkManager::InternalLinkPassportDataRequest final : public InternalLink { UserId bot_user_id_; string scope_; @@ -2008,7 +2020,8 @@ unique_ptr<LinkManager::InternalLink> LinkManager::parse_tg_link_query(Slice que << copy_arg("thread") << copy_arg("comment") << copy_arg("t")); } if (username == "oauth" && has_arg("startapp")) { - return nullptr; + return td::make_unique<InternalLinkOauth>(PSTRING() + << "tg://resolve" << copy_arg("domain") << copy_arg("startapp")); } for (auto &arg : url_query.args_) { if ((arg.first == "voicechat" || arg.first == "videochat" || arg.first == "livestream") && @@ -2177,7 +2190,7 @@ unique_ptr<LinkManager::InternalLink> LinkManager::parse_tg_link_query(Slice que return td::make_unique<InternalLinkNewGroupChat>(); } else if (path.size() == 1 && path[0] == "oauth" && has_arg("token")) { // oauth?token=... - return nullptr; + return td::make_unique<InternalLinkOauth>(PSTRING() << "tg://oauth" << copy_arg("token")); } else if (path.size() <= 2 && path[0] == "post") { // post[/content-type] return td::make_unique<InternalLinkPostStory>(path.size() == 2 ? path[1] : string()); @@ -3303,6 +3316,21 @@ Result<string> LinkManager::get_internal_link_impl(const td_api::InternalLinkTyp } return "tg://post"; } + case td_api::internalLinkTypeOauth::ID: { + auto link = static_cast<const td_api::internalLinkTypeOauth *>(type_ptr); + if (!is_internal) { + return Status::Error("HTTP link is unavailable for the link type"); + } + auto parsed_link = parse_internal_link(link->url_); + if (parsed_link == nullptr) { + return Status::Error(400, "Invalid message URL specified"); + } + auto parsed_object = parsed_link->get_internal_link_type_object(); + if (parsed_object->get_id() != td_api::internalLinkTypeOauth::ID) { + return Status::Error(400, "Invalid OAuth URL specified"); + } + return std::move(static_cast<td_api::internalLinkTypeOauth &>(*parsed_object).url_); + } case td_api::internalLinkTypePassportDataRequest::ID: { auto link = static_cast<const td_api::internalLinkTypePassportDataRequest *>(type_ptr); if (!is_internal) { diff --git a/td/telegram/LinkManager.h b/td/telegram/LinkManager.h index ad659c23e..0a89097e4 100644 --- a/td/telegram/LinkManager.h +++ b/td/telegram/LinkManager.h @@ -156,6 +156,7 @@ class LinkManager final : public Actor { class InternalLinkNewChannelChat; class InternalLinkNewGroupChat; class InternalLinkNewPrivateChat; + class InternalLinkOauth; class InternalLinkPassportDataRequest; class InternalLinkPostStory; class InternalLinkPremiumFeatures; diff --git a/test/link.cpp b/test/link.cpp index 35d4e0d6f..0bd771c7b 100644 --- a/test/link.cpp +++ b/test/link.cpp @@ -422,6 +422,10 @@ static auto new_story(td::td_api::object_ptr<td::td_api::StoryContentType> conte return td::td_api::make_object<td::td_api::internalLinkTypeNewStory>(std::move(content_type)); } +static auto oauth(const td::string &url) { + return td::td_api::make_object<td::td_api::internalLinkTypeOauth>(url); +} + static auto passport_data_request(td::int32 bot_user_id, const td::string &scope, const td::string &public_key, const td::string &nonce, const td::string &callback_url) { return td::td_api::make_object<td::td_api::internalLinkTypePassportDataRequest>(bot_user_id, scope, public_key, nonce, @@ -668,10 +672,13 @@ TEST(Link, parse_internal_link_part1) { parse_internal_link("tg:resolve?phone=123456&attach=test%30&startattach=*", attachment_menu_bot(nullptr, user_phone_number("123456"), "test0", "")); - parse_internal_link("tg:resolve?domain=oauth&startapp=12345", nullptr); + parse_internal_link("tg:resolve?domain=oauth&startapp=12345", oauth("tg://resolve?domain=oauth&startapp=12345")); + parse_internal_link("tg:resolve?domain=oauth&startapp=%312345&token=asd", + oauth("tg://resolve?domain=oauth&startapp=12345")); parse_internal_link("tg:resolve?domain=oauth&startapp=", main_web_app("oauth", "", false, false)); parse_internal_link("tg:resolve?domain=oauth", public_chat("oauth")); - parse_internal_link("tg:oauth?token=12345", nullptr); + parse_internal_link("tg:oauth?token=12345", oauth("tg://oauth?token=12345")); + parse_internal_link("tg:oauth?token=%312345&startapp=1231", oauth("tg://oauth?token=12345")); parse_internal_link("tg:oauth?token=", unknown_deep_link("tg://oauth?token=")); parse_internal_link("tg:contact?token=1", user_token("1")); |
