routes: move before_all logic to its own module
This commit is contained in:
parent
1e25894f7e
commit
870350fd61
153
src/invidious.cr
153
src/invidious.cr
|
@ -178,155 +178,10 @@ def popular_videos
|
||||||
Invidious::Jobs::PullPopularVideosJob::POPULAR_VIDEOS.get
|
Invidious::Jobs::PullPopularVideosJob::POPULAR_VIDEOS.get
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Routing
|
||||||
|
|
||||||
before_all do |env|
|
before_all do |env|
|
||||||
preferences = Preferences.from_json("{}")
|
Invidious::Routes::BeforeAll.handle(env)
|
||||||
|
|
||||||
begin
|
|
||||||
if prefs_cookie = env.request.cookies["PREFS"]?
|
|
||||||
preferences = Preferences.from_json(URI.decode_www_form(prefs_cookie.value))
|
|
||||||
else
|
|
||||||
if language_header = env.request.headers["Accept-Language"]?
|
|
||||||
if language = ANG.language_negotiator.best(language_header, LOCALES.keys)
|
|
||||||
preferences.locale = language.header
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
rescue
|
|
||||||
preferences = Preferences.from_json("{}")
|
|
||||||
end
|
|
||||||
|
|
||||||
env.set "preferences", preferences
|
|
||||||
env.response.headers["X-XSS-Protection"] = "1; mode=block"
|
|
||||||
env.response.headers["X-Content-Type-Options"] = "nosniff"
|
|
||||||
|
|
||||||
# Allow media resources to be loaded from google servers
|
|
||||||
# TODO: check if *.youtube.com can be removed
|
|
||||||
if CONFIG.disabled?("local") || !preferences.local
|
|
||||||
extra_media_csp = " https://*.googlevideo.com:443 https://*.youtube.com:443"
|
|
||||||
else
|
|
||||||
extra_media_csp = ""
|
|
||||||
end
|
|
||||||
|
|
||||||
# Only allow the pages at /embed/* to be embedded
|
|
||||||
if env.request.resource.starts_with?("/embed")
|
|
||||||
frame_ancestors = "'self' http: https:"
|
|
||||||
else
|
|
||||||
frame_ancestors = "'none'"
|
|
||||||
end
|
|
||||||
|
|
||||||
# TODO: Remove style-src's 'unsafe-inline', requires to remove all
|
|
||||||
# inline styles (<style> [..] </style>, style=" [..] ")
|
|
||||||
env.response.headers["Content-Security-Policy"] = {
|
|
||||||
"default-src 'none'",
|
|
||||||
"script-src 'self'",
|
|
||||||
"style-src 'self' 'unsafe-inline'",
|
|
||||||
"img-src 'self' data:",
|
|
||||||
"font-src 'self' data:",
|
|
||||||
"connect-src 'self'",
|
|
||||||
"manifest-src 'self'",
|
|
||||||
"media-src 'self' blob:" + extra_media_csp,
|
|
||||||
"child-src 'self' blob:",
|
|
||||||
"frame-src 'self'",
|
|
||||||
"frame-ancestors " + frame_ancestors,
|
|
||||||
}.join("; ")
|
|
||||||
|
|
||||||
env.response.headers["Referrer-Policy"] = "same-origin"
|
|
||||||
|
|
||||||
# Ask the chrom*-based browsers to disable FLoC
|
|
||||||
# See: https://blog.runcloud.io/google-floc/
|
|
||||||
env.response.headers["Permissions-Policy"] = "interest-cohort=()"
|
|
||||||
|
|
||||||
if (Kemal.config.ssl || CONFIG.https_only) && CONFIG.hsts
|
|
||||||
env.response.headers["Strict-Transport-Security"] = "max-age=31536000; includeSubDomains; preload"
|
|
||||||
end
|
|
||||||
|
|
||||||
next if {
|
|
||||||
"/sb/",
|
|
||||||
"/vi/",
|
|
||||||
"/s_p/",
|
|
||||||
"/yts/",
|
|
||||||
"/ggpht/",
|
|
||||||
"/api/manifest/",
|
|
||||||
"/videoplayback",
|
|
||||||
"/latest_version",
|
|
||||||
"/download",
|
|
||||||
}.any? { |r| env.request.resource.starts_with? r }
|
|
||||||
|
|
||||||
if env.request.cookies.has_key? "SID"
|
|
||||||
sid = env.request.cookies["SID"].value
|
|
||||||
|
|
||||||
if sid.starts_with? "v1:"
|
|
||||||
raise "Cannot use token as SID"
|
|
||||||
end
|
|
||||||
|
|
||||||
# Invidious users only have SID
|
|
||||||
if !env.request.cookies.has_key? "SSID"
|
|
||||||
if email = Invidious::Database::SessionIDs.select_email(sid)
|
|
||||||
user = Invidious::Database::Users.select!(email: email)
|
|
||||||
csrf_token = generate_response(sid, {
|
|
||||||
":authorize_token",
|
|
||||||
":playlist_ajax",
|
|
||||||
":signout",
|
|
||||||
":subscription_ajax",
|
|
||||||
":token_ajax",
|
|
||||||
":watch_ajax",
|
|
||||||
}, HMAC_KEY, 1.week)
|
|
||||||
|
|
||||||
preferences = user.preferences
|
|
||||||
env.set "preferences", preferences
|
|
||||||
|
|
||||||
env.set "sid", sid
|
|
||||||
env.set "csrf_token", csrf_token
|
|
||||||
env.set "user", user
|
|
||||||
end
|
|
||||||
else
|
|
||||||
headers = HTTP::Headers.new
|
|
||||||
headers["Cookie"] = env.request.headers["Cookie"]
|
|
||||||
|
|
||||||
begin
|
|
||||||
user, sid = get_user(sid, headers, false)
|
|
||||||
csrf_token = generate_response(sid, {
|
|
||||||
":authorize_token",
|
|
||||||
":playlist_ajax",
|
|
||||||
":signout",
|
|
||||||
":subscription_ajax",
|
|
||||||
":token_ajax",
|
|
||||||
":watch_ajax",
|
|
||||||
}, HMAC_KEY, 1.week)
|
|
||||||
|
|
||||||
preferences = user.preferences
|
|
||||||
env.set "preferences", preferences
|
|
||||||
|
|
||||||
env.set "sid", sid
|
|
||||||
env.set "csrf_token", csrf_token
|
|
||||||
env.set "user", user
|
|
||||||
rescue ex
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
dark_mode = convert_theme(env.params.query["dark_mode"]?) || preferences.dark_mode.to_s
|
|
||||||
thin_mode = env.params.query["thin_mode"]? || preferences.thin_mode.to_s
|
|
||||||
thin_mode = thin_mode == "true"
|
|
||||||
locale = env.params.query["hl"]? || preferences.locale
|
|
||||||
|
|
||||||
preferences.dark_mode = dark_mode
|
|
||||||
preferences.thin_mode = thin_mode
|
|
||||||
preferences.locale = locale
|
|
||||||
env.set "preferences", preferences
|
|
||||||
|
|
||||||
current_page = env.request.path
|
|
||||||
if env.request.query
|
|
||||||
query = HTTP::Params.parse(env.request.query.not_nil!)
|
|
||||||
|
|
||||||
if query["referer"]?
|
|
||||||
query["referer"] = get_referer(env, "/")
|
|
||||||
end
|
|
||||||
|
|
||||||
current_page += "?#{query}"
|
|
||||||
end
|
|
||||||
|
|
||||||
env.set "current_page", URI.encode_www_form(current_page)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
Invidious::Routing.register_all
|
Invidious::Routing.register_all
|
||||||
|
@ -386,6 +241,8 @@ static_headers do |response|
|
||||||
response.headers.add("Cache-Control", "max-age=2629800")
|
response.headers.add("Cache-Control", "max-age=2629800")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Init Kemal
|
||||||
|
|
||||||
public_folder "assets"
|
public_folder "assets"
|
||||||
|
|
||||||
Kemal.config.powered_by_header = false
|
Kemal.config.powered_by_header = false
|
||||||
|
|
152
src/invidious/routes/before_all.cr
Normal file
152
src/invidious/routes/before_all.cr
Normal file
|
@ -0,0 +1,152 @@
|
||||||
|
module Invidious::Routes::BeforeAll
|
||||||
|
def self.handle(env)
|
||||||
|
preferences = Preferences.from_json("{}")
|
||||||
|
|
||||||
|
begin
|
||||||
|
if prefs_cookie = env.request.cookies["PREFS"]?
|
||||||
|
preferences = Preferences.from_json(URI.decode_www_form(prefs_cookie.value))
|
||||||
|
else
|
||||||
|
if language_header = env.request.headers["Accept-Language"]?
|
||||||
|
if language = ANG.language_negotiator.best(language_header, LOCALES.keys)
|
||||||
|
preferences.locale = language.header
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
rescue
|
||||||
|
preferences = Preferences.from_json("{}")
|
||||||
|
end
|
||||||
|
|
||||||
|
env.set "preferences", preferences
|
||||||
|
env.response.headers["X-XSS-Protection"] = "1; mode=block"
|
||||||
|
env.response.headers["X-Content-Type-Options"] = "nosniff"
|
||||||
|
|
||||||
|
# Allow media resources to be loaded from google servers
|
||||||
|
# TODO: check if *.youtube.com can be removed
|
||||||
|
if CONFIG.disabled?("local") || !preferences.local
|
||||||
|
extra_media_csp = " https://*.googlevideo.com:443 https://*.youtube.com:443"
|
||||||
|
else
|
||||||
|
extra_media_csp = ""
|
||||||
|
end
|
||||||
|
|
||||||
|
# Only allow the pages at /embed/* to be embedded
|
||||||
|
if env.request.resource.starts_with?("/embed")
|
||||||
|
frame_ancestors = "'self' http: https:"
|
||||||
|
else
|
||||||
|
frame_ancestors = "'none'"
|
||||||
|
end
|
||||||
|
|
||||||
|
# TODO: Remove style-src's 'unsafe-inline', requires to remove all
|
||||||
|
# inline styles (<style> [..] </style>, style=" [..] ")
|
||||||
|
env.response.headers["Content-Security-Policy"] = {
|
||||||
|
"default-src 'none'",
|
||||||
|
"script-src 'self'",
|
||||||
|
"style-src 'self' 'unsafe-inline'",
|
||||||
|
"img-src 'self' data:",
|
||||||
|
"font-src 'self' data:",
|
||||||
|
"connect-src 'self'",
|
||||||
|
"manifest-src 'self'",
|
||||||
|
"media-src 'self' blob:" + extra_media_csp,
|
||||||
|
"child-src 'self' blob:",
|
||||||
|
"frame-src 'self'",
|
||||||
|
"frame-ancestors " + frame_ancestors,
|
||||||
|
}.join("; ")
|
||||||
|
|
||||||
|
env.response.headers["Referrer-Policy"] = "same-origin"
|
||||||
|
|
||||||
|
# Ask the chrom*-based browsers to disable FLoC
|
||||||
|
# See: https://blog.runcloud.io/google-floc/
|
||||||
|
env.response.headers["Permissions-Policy"] = "interest-cohort=()"
|
||||||
|
|
||||||
|
if (Kemal.config.ssl || CONFIG.https_only) && CONFIG.hsts
|
||||||
|
env.response.headers["Strict-Transport-Security"] = "max-age=31536000; includeSubDomains; preload"
|
||||||
|
end
|
||||||
|
|
||||||
|
return if {
|
||||||
|
"/sb/",
|
||||||
|
"/vi/",
|
||||||
|
"/s_p/",
|
||||||
|
"/yts/",
|
||||||
|
"/ggpht/",
|
||||||
|
"/api/manifest/",
|
||||||
|
"/videoplayback",
|
||||||
|
"/latest_version",
|
||||||
|
"/download",
|
||||||
|
}.any? { |r| env.request.resource.starts_with? r }
|
||||||
|
|
||||||
|
if env.request.cookies.has_key? "SID"
|
||||||
|
sid = env.request.cookies["SID"].value
|
||||||
|
|
||||||
|
if sid.starts_with? "v1:"
|
||||||
|
raise "Cannot use token as SID"
|
||||||
|
end
|
||||||
|
|
||||||
|
# Invidious users only have SID
|
||||||
|
if !env.request.cookies.has_key? "SSID"
|
||||||
|
if email = Invidious::Database::SessionIDs.select_email(sid)
|
||||||
|
user = Invidious::Database::Users.select!(email: email)
|
||||||
|
csrf_token = generate_response(sid, {
|
||||||
|
":authorize_token",
|
||||||
|
":playlist_ajax",
|
||||||
|
":signout",
|
||||||
|
":subscription_ajax",
|
||||||
|
":token_ajax",
|
||||||
|
":watch_ajax",
|
||||||
|
}, HMAC_KEY, 1.week)
|
||||||
|
|
||||||
|
preferences = user.preferences
|
||||||
|
env.set "preferences", preferences
|
||||||
|
|
||||||
|
env.set "sid", sid
|
||||||
|
env.set "csrf_token", csrf_token
|
||||||
|
env.set "user", user
|
||||||
|
end
|
||||||
|
else
|
||||||
|
headers = HTTP::Headers.new
|
||||||
|
headers["Cookie"] = env.request.headers["Cookie"]
|
||||||
|
|
||||||
|
begin
|
||||||
|
user, sid = get_user(sid, headers, false)
|
||||||
|
csrf_token = generate_response(sid, {
|
||||||
|
":authorize_token",
|
||||||
|
":playlist_ajax",
|
||||||
|
":signout",
|
||||||
|
":subscription_ajax",
|
||||||
|
":token_ajax",
|
||||||
|
":watch_ajax",
|
||||||
|
}, HMAC_KEY, 1.week)
|
||||||
|
|
||||||
|
preferences = user.preferences
|
||||||
|
env.set "preferences", preferences
|
||||||
|
|
||||||
|
env.set "sid", sid
|
||||||
|
env.set "csrf_token", csrf_token
|
||||||
|
env.set "user", user
|
||||||
|
rescue ex
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
dark_mode = convert_theme(env.params.query["dark_mode"]?) || preferences.dark_mode.to_s
|
||||||
|
thin_mode = env.params.query["thin_mode"]? || preferences.thin_mode.to_s
|
||||||
|
thin_mode = thin_mode == "true"
|
||||||
|
locale = env.params.query["hl"]? || preferences.locale
|
||||||
|
|
||||||
|
preferences.dark_mode = dark_mode
|
||||||
|
preferences.thin_mode = thin_mode
|
||||||
|
preferences.locale = locale
|
||||||
|
env.set "preferences", preferences
|
||||||
|
|
||||||
|
current_page = env.request.path
|
||||||
|
if env.request.query
|
||||||
|
query = HTTP::Params.parse(env.request.query.not_nil!)
|
||||||
|
|
||||||
|
if query["referer"]?
|
||||||
|
query["referer"] = get_referer(env, "/")
|
||||||
|
end
|
||||||
|
|
||||||
|
current_page += "?#{query}"
|
||||||
|
end
|
||||||
|
|
||||||
|
env.set "current_page", URI.encode_www_form(current_page)
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in a new issue