Support phone numbers in international format in internal links.

This commit is contained in:
levlam 2024-05-23 07:46:08 +03:00
parent f17c1eb444
commit 97baf4bda5
2 changed files with 42 additions and 21 deletions

View File

@ -773,8 +773,8 @@ class LinkManager::InternalLinkUserPhoneNumber final : public InternalLink {
} }
public: public:
InternalLinkUserPhoneNumber(string phone_number, string draft_text) InternalLinkUserPhoneNumber(Slice phone_number, string draft_text)
: phone_number_(std::move(phone_number)), draft_text_(std::move(draft_text)) { : phone_number_(PSTRING() << '+' << phone_number), draft_text_(std::move(draft_text)) {
} }
}; };
@ -1347,16 +1347,20 @@ unique_ptr<LinkManager::InternalLink> LinkManager::parse_tg_link_query(Slice que
} }
// resolve?domain=<username> // resolve?domain=<username>
return td::make_unique<InternalLinkPublicDialog>(std::move(username), get_url_query_draft_text(url_query)); return td::make_unique<InternalLinkPublicDialog>(std::move(username), get_url_query_draft_text(url_query));
} else if (is_valid_phone_number(get_arg("phone"))) { } else {
if (!url_query.get_arg("attach").empty()) { string phone_number_str = get_arg("phone");
// resolve?phone=<phone_number>&attach=<bot_username> auto phone_number = phone_number_str[0] == ' ' ? Slice(phone_number_str).substr(1) : Slice(phone_number_str);
// resolve?phone=<phone_number>&attach=<bot_username>&startattach=<start_parameter> if (is_valid_phone_number(phone_number)) {
return td::make_unique<InternalLinkAttachMenuBot>( if (!url_query.get_arg("attach").empty()) {
nullptr, td::make_unique<InternalLinkUserPhoneNumber>(get_arg("phone"), string()), // resolve?phone=<phone_number>&attach=<bot_username>
url_query.get_arg("attach").str(), url_query.get_arg("startattach")); // resolve?phone=<phone_number>&attach=<bot_username>&startattach=<start_parameter>
return td::make_unique<InternalLinkAttachMenuBot>(
nullptr, td::make_unique<InternalLinkUserPhoneNumber>(phone_number, string()),
url_query.get_arg("attach").str(), url_query.get_arg("startattach"));
}
// resolve?phone=12345
return td::make_unique<InternalLinkUserPhoneNumber>(phone_number, get_url_query_draft_text(url_query));
} }
// resolve?phone=12345
return td::make_unique<InternalLinkUserPhoneNumber>(get_arg("phone"), get_url_query_draft_text(url_query));
} }
} else if (path.size() == 1 && path[0] == "contact") { } else if (path.size() == 1 && path[0] == "contact") {
// contact?token=<token> // contact?token=<token>
@ -1938,15 +1942,21 @@ Result<string> LinkManager::get_internal_link_impl(const td_api::InternalLinkTyp
if (target->link_->get_id() == td_api::internalLinkTypeUserPhoneNumber::ID) { if (target->link_->get_id() == td_api::internalLinkTypeUserPhoneNumber::ID) {
auto user_phone_number_link = auto user_phone_number_link =
static_cast<const td_api::internalLinkTypeUserPhoneNumber *>(target->link_.get()); static_cast<const td_api::internalLinkTypeUserPhoneNumber *>(target->link_.get());
if (!is_valid_phone_number(user_phone_number_link->phone_number_)) { string phone_number;
if (user_phone_number_link->phone_number_[0] == '+') {
phone_number = user_phone_number_link->phone_number_.substr(1);
} else {
phone_number = user_phone_number_link->phone_number_;
}
if (!is_valid_phone_number(phone_number)) {
return Status::Error(400, "Invalid target phone number specified"); return Status::Error(400, "Invalid target phone number specified");
} }
if (is_internal) { if (is_internal) {
return PSTRING() << "tg://resolve?phone=" << user_phone_number_link->phone_number_ return PSTRING() << "tg://resolve?phone=+" << phone_number << "&attach=" << link->bot_username_
<< "&attach=" << link->bot_username_ << start_parameter; << start_parameter;
} else { } else {
return PSTRING() << get_t_me_url() << '+' << user_phone_number_link->phone_number_ return PSTRING() << get_t_me_url() << '+' << phone_number << "?attach=" << link->bot_username_
<< "?attach=" << link->bot_username_ << start_parameter; << start_parameter;
} }
} }
return Status::Error(400, "Unsupported target link specified"); return Status::Error(400, "Unsupported target link specified");
@ -2373,17 +2383,23 @@ Result<string> LinkManager::get_internal_link_impl(const td_api::InternalLinkTyp
} }
case td_api::internalLinkTypeUserPhoneNumber::ID: { case td_api::internalLinkTypeUserPhoneNumber::ID: {
auto link = static_cast<const td_api::internalLinkTypeUserPhoneNumber *>(type_ptr); auto link = static_cast<const td_api::internalLinkTypeUserPhoneNumber *>(type_ptr);
if (!is_valid_phone_number(link->phone_number_)) { string phone_number;
if (link->phone_number_[0] == '+') {
phone_number = link->phone_number_.substr(1);
} else {
phone_number = link->phone_number_;
}
if (!is_valid_phone_number(phone_number)) {
return Status::Error(400, "Invalid phone number specified"); return Status::Error(400, "Invalid phone number specified");
} }
if (!check_utf8(link->draft_text_)) { if (!check_utf8(link->draft_text_)) {
return Status::Error(400, "Draft text must be encoded in UTF-8"); return Status::Error(400, "Draft text must be encoded in UTF-8");
} }
if (is_internal) { if (is_internal) {
return PSTRING() << "tg://resolve?phone=" << link->phone_number_ << (link->draft_text_.empty() ? "" : "&text=") return PSTRING() << "tg://resolve?phone=+" << phone_number << (link->draft_text_.empty() ? "" : "&text=")
<< url_encode(link->draft_text_); << url_encode(link->draft_text_);
} else { } else {
return PSTRING() << get_t_me_url() << '+' << link->phone_number_ << (link->draft_text_.empty() ? "" : "?text=") return PSTRING() << get_t_me_url() << '+' << phone_number << (link->draft_text_.empty() ? "" : "?text=")
<< url_encode(link->draft_text_); << url_encode(link->draft_text_);
} }
} }

View File

@ -364,7 +364,7 @@ static auto unsupported_proxy() {
} }
static auto user_phone_number(const td::string &phone_number, const td::string &draft_text = td::string()) { static auto user_phone_number(const td::string &phone_number, const td::string &draft_text = td::string()) {
return td::td_api::make_object<td::td_api::internalLinkTypeUserPhoneNumber>(phone_number, draft_text); return td::td_api::make_object<td::td_api::internalLinkTypeUserPhoneNumber>('+' + phone_number, draft_text);
} }
static auto user_token(const td::string &token) { static auto user_token(const td::string &token) {
@ -467,6 +467,7 @@ TEST(Link, parse_internal_link_part1) {
attachment_menu_bot(nullptr, public_chat("telegram"), "test", "1")); attachment_menu_bot(nullptr, public_chat("telegram"), "test", "1"));
parse_internal_link("tg:resolve?phone=1", user_phone_number("1")); parse_internal_link("tg:resolve?phone=1", user_phone_number("1"));
parse_internal_link("tg:resolve?phone=+1", user_phone_number("1"));
parse_internal_link("tg:resolve?phone=123456", user_phone_number("123456")); parse_internal_link("tg:resolve?phone=123456", user_phone_number("123456"));
parse_internal_link("tg:resolve?phone=123456&startattach", user_phone_number("123456")); parse_internal_link("tg:resolve?phone=123456&startattach", user_phone_number("123456"));
parse_internal_link("tg:resolve?phone=123456&startattach=123", user_phone_number("123456")); parse_internal_link("tg:resolve?phone=123456&startattach=123", user_phone_number("123456"));
@ -475,6 +476,10 @@ TEST(Link, parse_internal_link_part1) {
parse_internal_link("tg:resolve?phone=123456&attach=&startattach=123", user_phone_number("123456")); parse_internal_link("tg:resolve?phone=123456&attach=&startattach=123", user_phone_number("123456"));
parse_internal_link("tg:resolve?phone=123456&attach=test", parse_internal_link("tg:resolve?phone=123456&attach=test",
attachment_menu_bot(nullptr, user_phone_number("123456"), "test", "")); attachment_menu_bot(nullptr, user_phone_number("123456"), "test", ""));
parse_internal_link("tg:resolve?phone=+123456&attach=test",
attachment_menu_bot(nullptr, user_phone_number("123456"), "test", ""));
parse_internal_link("tg:resolve?phone=++123456&attach=test",
unknown_deep_link("tg://resolve?phone=++123456&attach=test"));
parse_internal_link("tg:resolve?phone=123456&attach=test&startattach&choose=users", parse_internal_link("tg:resolve?phone=123456&attach=test&startattach&choose=users",
attachment_menu_bot(nullptr, user_phone_number("123456"), "test", "")); attachment_menu_bot(nullptr, user_phone_number("123456"), "test", ""));
parse_internal_link("tg:resolve?phone=123456&attach=test&startattach=123", parse_internal_link("tg:resolve?phone=123456&attach=test&startattach=123",
@ -484,7 +489,7 @@ TEST(Link, parse_internal_link_part1) {
parse_internal_link("tg:resolve?phone=012345678901234567890123456789123", parse_internal_link("tg:resolve?phone=012345678901234567890123456789123",
unknown_deep_link("tg://resolve?phone=012345678901234567890123456789123")); unknown_deep_link("tg://resolve?phone=012345678901234567890123456789123"));
parse_internal_link("tg:resolve?phone=", unknown_deep_link("tg://resolve?phone=")); parse_internal_link("tg:resolve?phone=", unknown_deep_link("tg://resolve?phone="));
parse_internal_link("tg:resolve?phone=+123", unknown_deep_link("tg://resolve?phone=+123")); parse_internal_link("tg:resolve?phone=+123", user_phone_number("123"));
parse_internal_link("tg:resolve?phone=123456 ", unknown_deep_link("tg://resolve?phone=123456 ")); parse_internal_link("tg:resolve?phone=123456 ", unknown_deep_link("tg://resolve?phone=123456 "));
parse_internal_link("tg:resolve?domain=telegram&text=asd", public_chat("telegram", "asd")); parse_internal_link("tg:resolve?domain=telegram&text=asd", public_chat("telegram", "asd"));
parse_internal_link("tg:resolve?phone=12345678901&text=asd", user_phone_number("12345678901", "asd")); parse_internal_link("tg:resolve?phone=12345678901&text=asd", user_phone_number("12345678901", "asd"));