Merge 9b406008358005ceb4110756c6d16f13b2b5c293 into 2c857b5ab6af36ec625fad688db6673f5d150d20

This commit is contained in:
Samantaz Fox 2025-05-18 07:02:36 +00:00 committed by GitHub
commit 3b0d17a152
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 71 additions and 48 deletions

View File

@ -343,6 +343,28 @@ input[type="search"]::-webkit-search-cancel-button {
} }
/*
* Error page
*/
div.center-hv {
height: 100%;
display: flex;
justify-content: center;
align-items: center;
flex-flow: column;
}
p#error-code, p#error-message {
position: relative;
padding: 0;
margin: 0;
}
p#error-code { font-size: 8em; bottom: 3vh; right: 5vw; }
p#error-message { font-size: 2em; bottom: 2vh; left: 3vw; }
/* /*
* Responsive rules * Responsive rules
*/ */

View File

@ -1,52 +1,38 @@
module Invidious::Routes::ErrorRoutes module Invidious::Routes::ErrorRoutes
def self.error_404(env) def self.error_404(env)
# Try to fetch user account/preferences and add CSP headers
begin
BeforeAll.handle(env)
rescue ex
end
# Workaround for #3117 # Workaround for #3117
if HOST_URL.empty? && env.request.path.starts_with?("/v1/storyboards/sb") if HOST_URL.empty? && env.request.path.starts_with?("/v1/storyboards/sb")
return env.redirect "#{env.request.path[15..]}?#{env.params.query}" return env.redirect "#{env.request.path[15..]}?#{env.params.query}"
end end
if md = env.request.path.match(/^\/(?<id>([a-zA-Z0-9_-]{11})|(\w+))$/) if match = env.request.path.match(/^\/(?<id>[a-zA-Z0-9_-]{11})$/)
item = md["id"] # NOTE: we assume that a 11 chars long path is a video ID
# to spare a call to 'resolve_url' and improve response time.
id = match["id"]
url = HttpServer::Utils.add_params_to_url("/watch?v=#{id}", env.params.query)
return env.redirect url.to_s
#
elsif match = env.request.path.match(/^\/(?<name>\w+)$/)
# Check if item is branding URL e.g. https://youtube.com/gaming # Check if item is branding URL e.g. https://youtube.com/gaming
response = YT_POOL.client &.get("/#{item}") begin
response = YoutubeAPI.resolve_url("https://youtube.com/#{env.request.path}")
endpoint = response["endpoint"]
if response.status_code == 301 if ucid = endpoint.dig?("browseEndpoint", "browseId")
response = YT_POOL.client &.get(URI.parse(response.headers["Location"]).request_target) url = HttpServer::Utils.add_params_to_url("/channel/#{ucid}", env.params.query)
return env.redirect url.to_s
end end
rescue ex
if response.body.empty?
env.response.headers["Location"] = "/"
haltf env, status_code: 302
end
html = XML.parse_html(response.body)
ucid = html.xpath_node(%q(//link[@rel="canonical"])).try &.["href"].split("/")[-1]
if ucid
env.response.headers["Location"] = "/channel/#{ucid}"
haltf env, status_code: 302
end
params = [] of String
env.params.query.each do |k, v|
params << "#{k}=#{v}"
end
params = params.join("&")
url = "/watch?v=#{item}"
if !params.empty?
url += "&#{params}"
end
# Check if item is video ID
if item.match(/^[a-zA-Z0-9_-]{11}$/) && YT_POOL.client &.head("/watch?v=#{item}").status_code != 404
env.response.headers["Location"] = url
haltf env, status_code: 302
end end
end end
env.response.headers["Location"] = "/" env.response.status_code = 404
haltf env, status_code: 302 templated "error_code"
end end
end end

View File

@ -0,0 +1,11 @@
<% message = HTML.escape(env.response.status.description || "Unknown error") %>
<% content_for "header" do %>
<title><%= message %> - Invidious</title>
<% end %>
<div class="h-box center-hv">
<div><p class="error-code"><%= env.response.status.code %></p></div>
<div><p class="error-message"><%= message %></p></div>
</div>

View File

@ -1,8 +1,12 @@
<%
locale = env.get("preferences").as(Preferences).locale
dark_mode = env.get("preferences").as(Preferences).dark_mode
%>
<!DOCTYPE html> <!DOCTYPE html>
<%-
user = env.get?("user").try &.as(IV::User)
prefs = env.get?("preferences").try &.as(Preferences)
locale = prefs.try &.locale || "en-US"
dark_mode = prefs.try &.dark_mode || "auto"
show_nick = prefs.try &.show_nick || false
-%>
<html lang="<%= locale %>"> <html lang="<%= locale %>">
<head> <head>
@ -40,7 +44,7 @@
<% end %> <% end %>
<div class="pure-u-1 pure-u-md-8-24 user-field"> <div class="pure-u-1 pure-u-md-8-24 user-field">
<% if env.get? "user" %> <% if user %>
<div class="pure-u-1-4"> <div class="pure-u-1-4">
<a id="toggle_theme" href="/toggle_theme?referer=<%= env.get?("current_page") %>" class="pure-menu-heading" title="<%= translate(locale, "toggle_theme") %>"> <a id="toggle_theme" href="/toggle_theme?referer=<%= env.get?("current_page") %>" class="pure-menu-heading" title="<%= translate(locale, "toggle_theme") %>">
<% if dark_mode == "dark" %> <% if dark_mode == "dark" %>
@ -52,7 +56,7 @@
</div> </div>
<div class="pure-u-1-4"> <div class="pure-u-1-4">
<a id="notification_ticker" title="<%= translate(locale, "Subscriptions") %>" href="/feed/subscriptions" class="pure-menu-heading"> <a id="notification_ticker" title="<%= translate(locale, "Subscriptions") %>" href="/feed/subscriptions" class="pure-menu-heading">
<% notification_count = env.get("user").as(Invidious::User).notifications.size %> <% notification_count = user.try &.notifications.size || 0 %>
<% if CONFIG.enable_user_notifications && notification_count > 0 %> <% if CONFIG.enable_user_notifications && notification_count > 0 %>
<span id="notification_count"><%= notification_count %></span> <i class="icon ion-ios-notifications"></i> <span id="notification_count"><%= notification_count %></span> <i class="icon ion-ios-notifications"></i>
<% else %> <% else %>
@ -65,11 +69,11 @@
<i class="icon ion-ios-cog"></i> <i class="icon ion-ios-cog"></i>
</a> </a>
</div> </div>
<% if env.get("preferences").as(Preferences).show_nick %> <%- if show_nick -%>
<div class="pure-u-1-4" style="overflow: hidden; white-space: nowrap;"> <div class="pure-u-1-4" style="overflow: hidden; white-space: nowrap;">
<span id="user_name"><%= HTML.escape(env.get("user").as(Invidious::User).email) %></span> <span id="user_name"><%= HTML.escape(user.try &.email) %></span>
</div> </div>
<% end %> <%- end -%>
<div class="pure-u-1-4"> <div class="pure-u-1-4">
<form action="/signout?referer=<%= env.get?("current_page") %>" method="post"> <form action="/signout?referer=<%= env.get?("current_page") %>" method="post">
<input type="hidden" name="csrf_token" value="<%= HTML.escape(env.get?("csrf_token").try &.as(String) || "") %>"> <input type="hidden" name="csrf_token" value="<%= HTML.escape(env.get?("csrf_token").try &.as(String) || "") %>">
@ -158,7 +162,7 @@
</div> </div>
<script src="/js/handlers.js?v=<%= ASSET_COMMIT %>"></script> <script src="/js/handlers.js?v=<%= ASSET_COMMIT %>"></script>
<script src="/js/themes.js?v=<%= ASSET_COMMIT %>"></script> <script src="/js/themes.js?v=<%= ASSET_COMMIT %>"></script>
<% if env.get? "user" %> <% if user %>
<script src="/js/sse.js?v=<%= ASSET_COMMIT %>"></script> <script src="/js/sse.js?v=<%= ASSET_COMMIT %>"></script>
<script id="notification_data" type="application/json"> <script id="notification_data" type="application/json">
<%= <%=