From a02b55b2c084aa994cec26548bf0fc851b242e85 Mon Sep 17 00:00:00 2001 From: unlxam <177877261+unlxam@users.noreply.github.com> Date: Thu, 8 Aug 2024 22:51:24 -0300 Subject: [PATCH 01/11] feat: add confirm leaving Invidious view and route --- src/invidious/routes/misc.cr | 10 ++++++++++ src/invidious/routing.cr | 1 + src/invidious/views/confirm_leave.ecr | 24 ++++++++++++++++++++++++ 3 files changed, 35 insertions(+) create mode 100644 src/invidious/views/confirm_leave.ecr diff --git a/src/invidious/routes/misc.cr b/src/invidious/routes/misc.cr index d6bd9571..28a134a9 100644 --- a/src/invidious/routes/misc.cr +++ b/src/invidious/routes/misc.cr @@ -43,4 +43,14 @@ module Invidious::Routes::Misc instance_url = fetch_random_instance env.redirect "https://#{instance_url}#{referer}" end + + def self.confirm_leave(env) + locale = env.get("preferences").as(Preferences).locale + + link = env.params.query["link"]? + + referer = get_referer(env) + + templated "confirm_leave" + end end diff --git a/src/invidious/routing.cr b/src/invidious/routing.cr index ba05da19..1504e7ea 100644 --- a/src/invidious/routing.cr +++ b/src/invidious/routing.cr @@ -21,6 +21,7 @@ module Invidious::Routing get "/privacy", Routes::Misc, :privacy get "/licenses", Routes::Misc, :licenses get "/redirect", Routes::Misc, :cross_instance_redirect + get "/confirm_leave", Routes::Misc, :confirm_leave self.register_channel_routes self.register_watch_routes diff --git a/src/invidious/views/confirm_leave.ecr b/src/invidious/views/confirm_leave.ecr new file mode 100644 index 00000000..1b9027af --- /dev/null +++ b/src/invidious/views/confirm_leave.ecr @@ -0,0 +1,24 @@ +<% content_for "header" do %> +<%= translate(locale, "Leave Invidious") %> - Invidious +<% end %> + +
+
+ + <%= translate(locale, "You are leaving Invidious. Continue to external link?") %> + + + +
+
From f7e5a88dad8df6a08d413d80678a849f61396f99 Mon Sep 17 00:00:00 2001 From: unlxam <177877261+unlxam@users.noreply.github.com> Date: Sat, 10 Aug 2024 12:40:59 -0300 Subject: [PATCH 02/11] feat: update youtube.com links to confirm before leaving --- src/invidious/frontend/comments_youtube.cr | 6 +++++- src/invidious/views/watch.ecr | 7 +++++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/invidious/frontend/comments_youtube.cr b/src/invidious/frontend/comments_youtube.cr index a0e1d783..93edffdc 100644 --- a/src/invidious/frontend/comments_youtube.cr +++ b/src/invidious/frontend/comments_youtube.cr @@ -1,3 +1,5 @@ +require "uri" + module Invidious::Frontend::Comments extend self @@ -148,8 +150,10 @@ module Invidious::Frontend::Comments END_HTML if comments["videoId"]? + permalink = "https://www.youtube.com/watch?v=#{comments["videoId"]}&lc=#{child["commentId"]}" + permalink_confirm = "/confirm_leave?link=#{URI.encode_path(permalink)}" html << <<-END_HTML - [YT] + [YT] | END_HTML elsif comments["authorId"]? diff --git a/src/invidious/views/watch.ecr b/src/invidious/views/watch.ecr index 45c58a16..1753a331 100644 --- a/src/invidious/views/watch.ecr +++ b/src/invidious/views/watch.ecr @@ -122,9 +122,12 @@ we're going to need to do it here in order to allow for translations. link_yt_watch = IV::HttpServer::Utils.add_params_to_url(link_yt_watch, link_yt_param) link_yt_embed = IV::HttpServer::Utils.add_params_to_url(link_yt_embed, link_yt_param) end + + confirm_yt_watch = "/confirm_leave?link=#{URI.encode_path(link_yt_watch.to_s)}" + confirm_yt_embed = "/confirm_leave?link=#{URI.encode_path(link_yt_embed.to_s)}" -%> - <%= translate(locale, "videoinfo_watch_on_youTube") %> - (<%= translate(locale, "videoinfo_youTube_embed_link") %>) + <%= translate(locale, "videoinfo_watch_on_youTube") %> + (<%= translate(locale, "videoinfo_youTube_embed_link") %>)

From e8511443f1a18cf726c1dc16908b3020b2bb25d4 Mon Sep 17 00:00:00 2001 From: unlxam <177877261+unlxam@users.noreply.github.com> Date: Sat, 10 Aug 2024 12:41:29 -0300 Subject: [PATCH 03/11] fix: remove redundant Invidious from title --- src/invidious/views/confirm_leave.ecr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/invidious/views/confirm_leave.ecr b/src/invidious/views/confirm_leave.ecr index 1b9027af..95f97c6a 100644 --- a/src/invidious/views/confirm_leave.ecr +++ b/src/invidious/views/confirm_leave.ecr @@ -1,5 +1,5 @@ <% content_for "header" do %> -<%= translate(locale, "Leave Invidious") %> - Invidious +<%= translate(locale, "Leave") %> - Invidious <% end %>

From ecfb9fed5a643fb34d3cc32be646260c01312b3f Mon Sep 17 00:00:00 2001 From: unlxam <177877261+unlxam@users.noreply.github.com> Date: Sat, 10 Aug 2024 18:28:04 -0300 Subject: [PATCH 04/11] feat: replace external links in description and comments to confirm before leaving --- src/invidious/comments/links_util.cr | 26 ++++++++++++++++++++++++++ src/invidious/comments/youtube.cr | 1 + src/invidious/videos/parser.cr | 3 +++ 3 files changed, 30 insertions(+) diff --git a/src/invidious/comments/links_util.cr b/src/invidious/comments/links_util.cr index f89b86d3..a28db740 100644 --- a/src/invidious/comments/links_util.cr +++ b/src/invidious/comments/links_util.cr @@ -73,4 +73,30 @@ module Invidious::Comments return html.to_xml(options: XML::SaveOptions::NO_DECL) end + + def replace_external_links(html) + # Check if the document is empty + # Prevents edge-case bug with Reddit comments, see issue #3115 + if html.nil? || html.empty? + return html + end + + html = XML.parse_html(html) + + html.xpath_nodes(%q(//a)).each do |anchor| + url = URI.parse(anchor["href"]) + + if !url.host.nil? && !url.host.not_nil!.ends_with?("youtube.com") && !url.host.not_nil!.ends_with?("youtu.be") + confirm_leave = "/confirm_leave?link=#{URI.encode_path(url.to_s)}" + anchor["href"] = confirm_leave + end + end + + html = html.xpath_node(%q(//body)).not_nil! + if node = html.xpath_node(%q(./p)) + html = node + end + + return html.to_xml(options: XML::SaveOptions::NO_DECL) + end end diff --git a/src/invidious/comments/youtube.cr b/src/invidious/comments/youtube.cr index 0716fcde..148f6cbe 100644 --- a/src/invidious/comments/youtube.cr +++ b/src/invidious/comments/youtube.cr @@ -303,6 +303,7 @@ module Invidious::Comments if format == "html" response = JSON.parse(response) content_html = Frontend::Comments.template_youtube(response, locale, thin_mode) + content_html = Comments.replace_external_links(content_html) response = JSON.build do |json| json.object do json.field "contentHtml", content_html diff --git a/src/invidious/videos/parser.cr b/src/invidious/videos/parser.cr index 95fa3d79..cd11995f 100644 --- a/src/invidious/videos/parser.cr +++ b/src/invidious/videos/parser.cr @@ -316,6 +316,9 @@ def parse_video_info(video_id : String, player_response : Hash(String, JSON::Any description_html = parse_description(video_secondary_renderer.try &.dig?("attributedDescription"), video_id) + # use comments link_utils to replace external links with the confirmation page + description_html = Invidious::Comments.replace_external_links(description_html) + # Video metadata metadata = video_secondary_renderer From b240f915b7606bd8596b48960433d0867906c4c5 Mon Sep 17 00:00:00 2001 From: unlxam <177877261+unlxam@users.noreply.github.com> Date: Sat, 10 Aug 2024 18:31:05 -0300 Subject: [PATCH 05/11] feat: add link url --- src/invidious/views/confirm_leave.ecr | 30 +++++++++++++-------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/src/invidious/views/confirm_leave.ecr b/src/invidious/views/confirm_leave.ecr index 95f97c6a..a46cb187 100644 --- a/src/invidious/views/confirm_leave.ecr +++ b/src/invidious/views/confirm_leave.ecr @@ -3,22 +3,20 @@ <% end %>
-
- - <%= translate(locale, "You are leaving Invidious. Continue to external link?") %> - -
- - +

<%= translate(locale, "You are leaving Invidious. Continue to external link?") %>

+ +

<%= link %>

+ +
From 01e9fa3af7b06cbcaf9761ec882f2e16ba315e18 Mon Sep 17 00:00:00 2001 From: unlxam <177877261+unlxam@users.noreply.github.com> Date: Sat, 24 Aug 2024 12:19:36 -0300 Subject: [PATCH 06/11] feat: add rel="noreferrer noopener" to external link --- src/invidious/views/confirm_leave.ecr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/invidious/views/confirm_leave.ecr b/src/invidious/views/confirm_leave.ecr index a46cb187..122c64bd 100644 --- a/src/invidious/views/confirm_leave.ecr +++ b/src/invidious/views/confirm_leave.ecr @@ -9,7 +9,7 @@
From 0fd38e52efc17191ffc2a8605e148050cdf064d6 Mon Sep 17 00:00:00 2001 From: unlxam <177877261+unlxam@users.noreply.github.com> Date: Sat, 24 Aug 2024 13:01:37 -0300 Subject: [PATCH 07/11] refactor: replace all youtube external links with confirmation page --- src/invidious/frontend/comments_youtube.cr | 4 +++- src/invidious/helpers/errors.cr | 5 ++++- src/invidious/views/components/video-context-buttons.ecr | 6 +++++- src/invidious/views/playlist.ecr | 6 +++++- 4 files changed, 17 insertions(+), 4 deletions(-) diff --git a/src/invidious/frontend/comments_youtube.cr b/src/invidious/frontend/comments_youtube.cr index 93edffdc..5e9faece 100644 --- a/src/invidious/frontend/comments_youtube.cr +++ b/src/invidious/frontend/comments_youtube.cr @@ -157,8 +157,10 @@ module Invidious::Frontend::Comments | END_HTML elsif comments["authorId"]? + permalink = "https://www.youtube.com/channel/#{comments["authorId"]}/community?lb=#{child["commentId"]}" + permalink_confirm = "/confirm_leave?link=#{URI.encode_path(permalink)}" html << <<-END_HTML - [YT] + [YT] | END_HTML end diff --git a/src/invidious/helpers/errors.cr b/src/invidious/helpers/errors.cr index b2df682d..c8e360dc 100644 --- a/src/invidious/helpers/errors.cr +++ b/src/invidious/helpers/errors.cr @@ -180,6 +180,9 @@ def error_redirect_helper(env : HTTP::Server::Context) go_to_youtube = translate(locale, "next_steps_error_message_go_to_youtube") switch_instance = translate(locale, "Switch Invidious Instance") + youtube_link = "https://youtube.com#{env.request.resource}" + youtube_link_confirm = "/confirm_leave?link=#{URI.encode_path(youtube_link)}" + return <<-END_HTML

#{next_steps_text}

END_HTML diff --git a/src/invidious/views/components/video-context-buttons.ecr b/src/invidious/views/components/video-context-buttons.ecr index 22458a03..a8078da8 100644 --- a/src/invidious/views/components/video-context-buttons.ecr +++ b/src/invidious/views/components/video-context-buttons.ecr @@ -1,6 +1,10 @@
- " rel="noreferrer noopener" href="https://www.youtube.com/watch<%=endpoint_params%>"> + <%- + watch_yt = "https://www.youtube.com/watch#{endpoint_params}" + confirm_watch_yt = "/confirm_leave?link=#{URI.encode_path(watch_yt)}" + -%> + " href="<%= confirm_watch_yt %>"> " href="/watch<%=endpoint_params%>&listen=1"> diff --git a/src/invidious/views/playlist.ecr b/src/invidious/views/playlist.ecr index c27ddba6..031a03ae 100644 --- a/src/invidious/views/playlist.ecr +++ b/src/invidious/views/playlist.ecr @@ -83,7 +83,11 @@ <% if !playlist.is_a? InvidiousPlaylist %>
- + <%- + view_yt = "https://www.youtube.com/playlist?list=#{playlist.id}" + confirm_view_yt = "/confirm_leave?link=#{URI.encode_path(view_yt)}" + -%> + <%= translate(locale, "View playlist on YouTube") %> | From effb642948d5b0f3bfe7be711279d401434da42c Mon Sep 17 00:00:00 2001 From: unlxam <177877261+unlxam@users.noreply.github.com> Date: Sat, 24 Aug 2024 13:16:02 -0300 Subject: [PATCH 08/11] feat: replace View channel on YouTube and channel's description external links --- src/invidious/channels/about.cr | 3 +++ src/invidious/views/components/channel_info.ecr | 5 ++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/invidious/channels/about.cr b/src/invidious/channels/about.cr index 13909527..a6495383 100644 --- a/src/invidious/channels/about.cr +++ b/src/invidious/channels/about.cr @@ -159,6 +159,9 @@ def get_about_info(ucid, locale) : AboutChannel end end + # use comments link_utils to replace external links with the confirmation page + description_html = Invidious::Comments.replace_external_links(description_html) + sub_count = 0 if (metadata_rows = initdata.dig?("header", "pageHeaderRenderer", "content", "pageHeaderViewModel", "metadata", "contentMetadataViewModel", "metadataRows").try &.as_a) diff --git a/src/invidious/views/components/channel_info.ecr b/src/invidious/views/components/channel_info.ecr index f4164f31..0d9820c5 100644 --- a/src/invidious/views/components/channel_info.ecr +++ b/src/invidious/views/components/channel_info.ecr @@ -37,7 +37,10 @@
- <%= translate(locale, "View channel on YouTube") %> + <%- + confirm_view_yt = "/confirm_leave?link=#{URI.encode_path(youtube_url)}" + -%> + <%= translate(locale, "View channel on YouTube") %>
<%= translate(locale, "Switch Invidious Instance") %> From 42ac3c8a21c8cf5e3b479367ea25eeba273353a0 Mon Sep 17 00:00:00 2001 From: unlxam <177877261+unlxam@users.noreply.github.com> Date: Sat, 24 Aug 2024 13:19:21 -0300 Subject: [PATCH 09/11] feat: add confirmation page text --- locales/en-US.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/locales/en-US.json b/locales/en-US.json index 3987f796..8801cb0a 100644 --- a/locales/en-US.json +++ b/locales/en-US.json @@ -496,5 +496,6 @@ "toggle_theme": "Toggle Theme", "carousel_slide": "Slide {{current}} of {{total}}", "carousel_skip": "Skip the Carousel", - "carousel_go_to": "Go to slide `x`" + "carousel_go_to": "Go to slide `x`", + "confirm_dialog_external_link": "You are leaving Invidious. Continue to external link?" } From be1ed83930187412fc60b2da283e9e7ffc8d4fba Mon Sep 17 00:00:00 2001 From: unlxam <177877261+unlxam@users.noreply.github.com> Date: Sat, 24 Aug 2024 13:40:28 -0300 Subject: [PATCH 10/11] feat: add presence checking and html escaping for link --- src/invidious/routes/misc.cr | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/invidious/routes/misc.cr b/src/invidious/routes/misc.cr index 28a134a9..c0bef5b4 100644 --- a/src/invidious/routes/misc.cr +++ b/src/invidious/routes/misc.cr @@ -48,9 +48,15 @@ module Invidious::Routes::Misc locale = env.get("preferences").as(Preferences).locale link = env.params.query["link"]? + link = HTML.escape(link.to_s) referer = get_referer(env) - templated "confirm_leave" + if link && !link.empty? + templated "confirm_leave" + else + env.redirect "#{referer}" + end + end end From 307e6f56863690ba9cd0c47d109ac8bf6cfbcf9b Mon Sep 17 00:00:00 2001 From: unlxam <177877261+unlxam@users.noreply.github.com> Date: Sun, 25 Aug 2024 15:24:05 -0300 Subject: [PATCH 11/11] refactor: add better link presence checking --- src/invidious/routes/misc.cr | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/invidious/routes/misc.cr b/src/invidious/routes/misc.cr index c0bef5b4..ff863f58 100644 --- a/src/invidious/routes/misc.cr +++ b/src/invidious/routes/misc.cr @@ -46,17 +46,14 @@ module Invidious::Routes::Misc def self.confirm_leave(env) locale = env.get("preferences").as(Preferences).locale - - link = env.params.query["link"]? - link = HTML.escape(link.to_s) - referer = get_referer(env) - if link && !link.empty? + if env.params.query["link"]? && !env.params.query["link"].empty? + link = HTML.escape(env.params.query["link"].to_s) + templated "confirm_leave" else env.redirect "#{referer}" end - end end