mirror of
https://github.com/iv-org/invidious.git
synced 2026-03-10 21:08:29 -05:00
Add support for alternative domains for Invidious cookies
This commit is contained in:
parent
fda8d1b528
commit
52d64e37ea
@ -151,6 +151,20 @@ db:
|
|||||||
##
|
##
|
||||||
domain:
|
domain:
|
||||||
|
|
||||||
|
##
|
||||||
|
## List of alternative domains where the invidious instance is being served.
|
||||||
|
## This needs to be set in order to be able to login and update user preferences
|
||||||
|
## when using a domain that is not the same as the `domain` configuration,
|
||||||
|
## like a .`onion` address, `.i2p` address, `.b32.i2p` address, etc.
|
||||||
|
##
|
||||||
|
## It will detect the alternative domain trough the `X-Forwarded-Host` header.
|
||||||
|
## https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/X-Forwarded-Host
|
||||||
|
##
|
||||||
|
## Accepted values: a list of fully qualified domain names (FQDN)
|
||||||
|
## Default: <none>
|
||||||
|
##
|
||||||
|
alternative_domains:
|
||||||
|
|
||||||
##
|
##
|
||||||
## Tell Invidious that it is behind a proxy that provides only
|
## Tell Invidious that it is behind a proxy that provides only
|
||||||
## HTTPS, so all links must use the https:// scheme. This
|
## HTTPS, so all links must use the https:// scheme. This
|
||||||
|
|||||||
@ -120,6 +120,8 @@ class Config
|
|||||||
property hmac_key : String = ""
|
property hmac_key : String = ""
|
||||||
# Domain to be used for links to resources on the site where an absolute URL is required
|
# Domain to be used for links to resources on the site where an absolute URL is required
|
||||||
property domain : String?
|
property domain : String?
|
||||||
|
# Additional domain list that is going to be used for cookie domain validation
|
||||||
|
property alternative_domains : Array(String) = [] of String
|
||||||
# Subscribe to channels using PubSubHubbub (requires domain, hmac_key)
|
# Subscribe to channels using PubSubHubbub (requires domain, hmac_key)
|
||||||
property use_pubsub_feeds : Bool | Int32 = false
|
property use_pubsub_feeds : Bool | Int32 = false
|
||||||
property popular_enabled : Bool = true
|
property popular_enabled : Bool = true
|
||||||
|
|||||||
@ -32,6 +32,8 @@ module Invidious::Routes::BeforeAll
|
|||||||
env.response.headers["X-XSS-Protection"] = "1; mode=block"
|
env.response.headers["X-XSS-Protection"] = "1; mode=block"
|
||||||
env.response.headers["X-Content-Type-Options"] = "nosniff"
|
env.response.headers["X-Content-Type-Options"] = "nosniff"
|
||||||
|
|
||||||
|
env.set "header_x-forwarded-host", env.request.headers["X-Forwarded-Host"]?
|
||||||
|
|
||||||
# Only allow the pages at /embed/* to be embedded
|
# Only allow the pages at /embed/* to be embedded
|
||||||
if env.request.resource.starts_with?("/embed")
|
if env.request.resource.starts_with?("/embed")
|
||||||
frame_ancestors = "'self' file: http: https:"
|
frame_ancestors = "'self' file: http: https:"
|
||||||
|
|||||||
@ -26,6 +26,7 @@ module Invidious::Routes::Login
|
|||||||
|
|
||||||
def self.login(env)
|
def self.login(env)
|
||||||
locale = env.get("preferences").as(Preferences).locale
|
locale = env.get("preferences").as(Preferences).locale
|
||||||
|
host = env.get("header_x-forwarded-host")
|
||||||
|
|
||||||
referer = get_referer(env, "/feed/subscriptions")
|
referer = get_referer(env, "/feed/subscriptions")
|
||||||
|
|
||||||
@ -57,7 +58,11 @@ module Invidious::Routes::Login
|
|||||||
sid = Base64.urlsafe_encode(Random::Secure.random_bytes(32))
|
sid = Base64.urlsafe_encode(Random::Secure.random_bytes(32))
|
||||||
Invidious::Database::SessionIDs.insert(sid, email)
|
Invidious::Database::SessionIDs.insert(sid, email)
|
||||||
|
|
||||||
env.response.cookies["SID"] = Invidious::User::Cookies.sid(CONFIG.domain, sid)
|
if alt = CONFIG.alternative_domains.index(host)
|
||||||
|
env.response.cookies["SID"] = Invidious::User::Cookies.sid(CONFIG.alternative_domains[alt], sid)
|
||||||
|
else
|
||||||
|
env.response.cookies["SID"] = Invidious::User::Cookies.sid(CONFIG.domain, sid)
|
||||||
|
end
|
||||||
else
|
else
|
||||||
return error_template(401, "Wrong username or password")
|
return error_template(401, "Wrong username or password")
|
||||||
end
|
end
|
||||||
@ -123,7 +128,11 @@ module Invidious::Routes::Login
|
|||||||
view_name = "subscriptions_#{sha256(user.email)}"
|
view_name = "subscriptions_#{sha256(user.email)}"
|
||||||
PG_DB.exec("CREATE MATERIALIZED VIEW #{view_name} AS #{MATERIALIZED_VIEW_SQL.call(user.email)}")
|
PG_DB.exec("CREATE MATERIALIZED VIEW #{view_name} AS #{MATERIALIZED_VIEW_SQL.call(user.email)}")
|
||||||
|
|
||||||
env.response.cookies["SID"] = Invidious::User::Cookies.sid(CONFIG.domain, sid)
|
if alt = CONFIG.alternative_domains.index(host)
|
||||||
|
env.response.cookies["SID"] = Invidious::User::Cookies.sid(CONFIG.alternative_domains[alt], sid)
|
||||||
|
else
|
||||||
|
env.response.cookies["SID"] = Invidious::User::Cookies.sid(CONFIG.domain, sid)
|
||||||
|
end
|
||||||
|
|
||||||
if env.request.cookies["PREFS"]?
|
if env.request.cookies["PREFS"]?
|
||||||
user.preferences = env.get("preferences").as(Preferences)
|
user.preferences = env.get("preferences").as(Preferences)
|
||||||
|
|||||||
@ -226,7 +226,12 @@ module Invidious::Routes::PreferencesRoute
|
|||||||
File.write("config/config.yml", CONFIG.to_yaml)
|
File.write("config/config.yml", CONFIG.to_yaml)
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
env.response.cookies["PREFS"] = Invidious::User::Cookies.prefs(CONFIG.domain, preferences)
|
host = env.get("header_x-forwarded-host")
|
||||||
|
if alt = CONFIG.alternative_domains.index(host)
|
||||||
|
env.response.cookies["PREFS"] = Invidious::User::Cookies.prefs(CONFIG.alternative_domains[alt], preferences)
|
||||||
|
else
|
||||||
|
env.response.cookies["PREFS"] = Invidious::User::Cookies.prefs(CONFIG.domain, preferences)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
env.redirect referer
|
env.redirect referer
|
||||||
@ -261,7 +266,12 @@ module Invidious::Routes::PreferencesRoute
|
|||||||
preferences.dark_mode = "dark"
|
preferences.dark_mode = "dark"
|
||||||
end
|
end
|
||||||
|
|
||||||
env.response.cookies["PREFS"] = Invidious::User::Cookies.prefs(CONFIG.domain, preferences)
|
host = env.get("header_x-forwarded-host")
|
||||||
|
if alt = CONFIG.alternative_domains.index(host)
|
||||||
|
env.response.cookies["PREFS"] = Invidious::User::Cookies.prefs(CONFIG.alternative_domains[alt], preferences)
|
||||||
|
else
|
||||||
|
env.response.cookies["PREFS"] = Invidious::User::Cookies.prefs(CONFIG.domain, preferences)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if redirect
|
if redirect
|
||||||
|
|||||||
@ -6,17 +6,24 @@ struct Invidious::User
|
|||||||
|
|
||||||
# Note: we use ternary operator because the two variables
|
# Note: we use ternary operator because the two variables
|
||||||
# used in here are not booleans.
|
# used in here are not booleans.
|
||||||
SECURE = (Kemal.config.ssl || CONFIG.https_only) ? true : false
|
@@secure = (Kemal.config.ssl || CONFIG.https_only) ? true : false
|
||||||
|
|
||||||
# Session ID (SID) cookie
|
# Session ID (SID) cookie
|
||||||
# Parameter "domain" comes from the global config
|
# Parameter "domain" comes from the global config
|
||||||
def sid(domain : String?, sid) : HTTP::Cookie
|
def sid(domain : String?, sid) : HTTP::Cookie
|
||||||
|
# Not secure if it's being accessed from I2P
|
||||||
|
# Browsers expect the domain to include https. On I2P there is no HTTPS
|
||||||
|
# Tor browser works fine with secure being true
|
||||||
|
if domain.try &.split(".").last == "i2p"
|
||||||
|
@@secure = false
|
||||||
|
end
|
||||||
|
|
||||||
return HTTP::Cookie.new(
|
return HTTP::Cookie.new(
|
||||||
name: "SID",
|
name: "SID",
|
||||||
domain: domain,
|
domain: domain,
|
||||||
value: sid,
|
value: sid,
|
||||||
expires: Time.utc + 2.years,
|
expires: Time.utc + 2.years,
|
||||||
secure: SECURE,
|
secure: @@secure,
|
||||||
http_only: true,
|
http_only: true,
|
||||||
samesite: HTTP::Cookie::SameSite::Lax
|
samesite: HTTP::Cookie::SameSite::Lax
|
||||||
)
|
)
|
||||||
@ -25,12 +32,19 @@ struct Invidious::User
|
|||||||
# Preferences (PREFS) cookie
|
# Preferences (PREFS) cookie
|
||||||
# Parameter "domain" comes from the global config
|
# Parameter "domain" comes from the global config
|
||||||
def prefs(domain : String?, preferences : Preferences) : HTTP::Cookie
|
def prefs(domain : String?, preferences : Preferences) : HTTP::Cookie
|
||||||
|
# Not secure if it's being accessed from I2P
|
||||||
|
# Browsers expect the domain to include https. On I2P there is no HTTPS
|
||||||
|
# Tor browser works fine with secure being true
|
||||||
|
if domain.try &.split(".").last == "i2p"
|
||||||
|
@@secure = false
|
||||||
|
end
|
||||||
|
|
||||||
return HTTP::Cookie.new(
|
return HTTP::Cookie.new(
|
||||||
name: "PREFS",
|
name: "PREFS",
|
||||||
domain: domain,
|
domain: domain,
|
||||||
value: URI.encode_www_form(preferences.to_json),
|
value: URI.encode_www_form(preferences.to_json),
|
||||||
expires: Time.utc + 2.years,
|
expires: Time.utc + 2.years,
|
||||||
secure: SECURE,
|
secure: @@secure,
|
||||||
http_only: false,
|
http_only: false,
|
||||||
samesite: HTTP::Cookie::SameSite::Lax
|
samesite: HTTP::Cookie::SameSite::Lax
|
||||||
)
|
)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user