From ad3f0357e6bd5c1ded0236c500dad8ac28ac9dcf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Toni=20F=C3=B6rster?= Date: Mon, 13 Nov 2023 11:53:58 +0100 Subject: [PATCH 1/4] support for private instances This is a modification of PR #3728. And addresses #446 Server admins can set the instance to be private. Which means it is only accessible with a registered user account. The endpoints `/api/v1/popular` and `/api/v1/trending` are whitelisted because some clients expect them to be open. --- config/config.example.yml | 30 ++++++++++++++++-- src/invidious/config.cr | 4 +++ src/invidious/routes/before_all.cr | 49 ++++++++++++++++++++++-------- 3 files changed, 69 insertions(+), 14 deletions(-) diff --git a/config/config.example.yml b/config/config.example.yml index b44fcc0e0..1e9b12640 100644 --- a/config/config.example.yml +++ b/config/config.example.yml @@ -236,6 +236,32 @@ https_only: false # Users and accounts # ----------------------------- +## +## Allow/Forbid the usage of the Invidious Instance without an account. +## Only /login and /privacy are accessible on such instances for unregistered +## users on the web interface. Moreover, certain API endpoints are accessible, +## to allow third-party clients to add the instance and login to an existing +## account. +## +## To avoid any data leakage it is recommended to set popular_enabled and +## statistics_enabled to 'false'. Furthermore, registration_enabled should be +## set to 'false' to only allow existing users to access the instance. +## +## Accepted values: true, false +## Default: false +## +#private_instance: false + +## +## Redirect request to the login page on private instances. Also requires +## login_enabled to be 'true', otherwise the server sends status code 401 +## and closes the connection. +## +## Accepted values: true, false +## Default: false +## +#redirect_login: false + ## ## Allow/Forbid Invidious (local) account creation. Invidious ## accounts allow users to subscribe to channels and to create @@ -777,7 +803,7 @@ default_user_preferences: ## ## Default dash video quality. ## - ## Note: this setting only takes effet if the + ## Note: this setting only takes effect if the ## 'quality' parameter is set to "dash". ## ## Accepted values: @@ -812,7 +838,7 @@ default_user_preferences: ## Default: true ## #vr_mode: true - + ## ## Save the playback position ## Allow to continue watching at the previous position when diff --git a/src/invidious/config.cr b/src/invidious/config.cr index 429d92464..3d9070203 100644 --- a/src/invidious/config.cr +++ b/src/invidious/config.cr @@ -92,6 +92,10 @@ class Config property use_pubsub_feeds : Bool | Int32 = false property popular_enabled : Bool = true property captcha_enabled : Bool = true + # Only allow usage of the Invidious instance with an existing account + property private_instance : Bool = false + # Redirected requests to the login page on a private instance. Requires login_enabled: true + property redirect_login : Bool = false property login_enabled : Bool = true property registration_enabled : Bool = true property statistics_enabled : Bool = false diff --git a/src/invidious/routes/before_all.cr b/src/invidious/routes/before_all.cr index 396840a4b..ad547875d 100644 --- a/src/invidious/routes/before_all.cr +++ b/src/invidious/routes/before_all.cr @@ -61,18 +61,6 @@ module Invidious::Routes::BeforeAll 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 @@ -100,6 +88,43 @@ module Invidious::Routes::BeforeAll end end + unregistered_path_whitelist = { + "/login", + "/privacy" + "/api/v1/stats", + # TODO: popular and trending are here for clients that require these endpoints to be accessible e.g. Clipious + # can be removed as soon as those clients can handele these request on private instances + "/api/v1/popular", + "/api/v1/trending", + "/feed/webhook/v1:", + "/api/v1/videos/dQw4w9WgXcQ", + "/api/v1/comments/jNQXAC9IVRw", + } + + if CONFIG.private_instance && !env.get?("user") && !unregistered_path_whitelist.any? { |r| env.request.path.starts_with? r } + if CONFIG.redirect_login && CONFIG.login_enabled + env.response.headers["Location"] = "/login" + haltf env, status_code: 302 + else + env.response.status_code = 401 + env.response.close + end + end + + return if { + "/sb/", + "/vi/", + "/s_p/", + "/yts/", + "/ggpht/", + "/download", + "/licenses", + "/api/manifest/", + "/videoplayback", + "/latest_version", + "/opensearch.xml", + }.any? { |r| env.request.resource.starts_with? r } + 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" From 5a967a710383681caec4b95a17ea7a6bd9c70d83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Toni=20F=C3=B6rster?= Date: Mon, 13 Nov 2023 13:14:58 +0100 Subject: [PATCH 2/4] addressed linting issues --- src/invidious/routes/before_all.cr | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/invidious/routes/before_all.cr b/src/invidious/routes/before_all.cr index ad547875d..f66925793 100644 --- a/src/invidious/routes/before_all.cr +++ b/src/invidious/routes/before_all.cr @@ -88,12 +88,12 @@ module Invidious::Routes::BeforeAll end end + # TODO: popular and trending are here for clients that require these endpoints to be accessible e.g. Clipious + # can be removed as soon as those clients can handele these request on private instances unregistered_path_whitelist = { "/login", "/privacy" "/api/v1/stats", - # TODO: popular and trending are here for clients that require these endpoints to be accessible e.g. Clipious - # can be removed as soon as those clients can handele these request on private instances "/api/v1/popular", "/api/v1/trending", "/feed/webhook/v1:", From a563aabd5fc1fc72b78824f0c8842aa71b730f48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Toni=20F=C3=B6rster?= Date: Mon, 13 Nov 2023 15:24:11 +0100 Subject: [PATCH 3/4] fix linting once and for all --- src/invidious/routes/before_all.cr | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/invidious/routes/before_all.cr b/src/invidious/routes/before_all.cr index f66925793..cd2feda63 100644 --- a/src/invidious/routes/before_all.cr +++ b/src/invidious/routes/before_all.cr @@ -88,11 +88,11 @@ module Invidious::Routes::BeforeAll end end - # TODO: popular and trending are here for clients that require these endpoints to be accessible e.g. Clipious + # TODO: popular and trending are whitelisted for clients that require these endpoints to be accessible e.g. Clipious # can be removed as soon as those clients can handele these request on private instances unregistered_path_whitelist = { "/login", - "/privacy" + "/privacy", "/api/v1/stats", "/api/v1/popular", "/api/v1/trending", From 0e98711e935070a3941e21a79e02729feec61592 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Toni=20F=C3=B6rster?= Date: Mon, 13 Nov 2023 22:02:12 +0100 Subject: [PATCH 4/4] removed redirect_login --- config/config.example.yml | 10 --------- src/invidious/config.cr | 2 -- src/invidious/routes/before_all.cr | 35 +++++++++++++----------------- 3 files changed, 15 insertions(+), 32 deletions(-) diff --git a/config/config.example.yml b/config/config.example.yml index 1e9b12640..39c72785c 100644 --- a/config/config.example.yml +++ b/config/config.example.yml @@ -252,16 +252,6 @@ https_only: false ## #private_instance: false -## -## Redirect request to the login page on private instances. Also requires -## login_enabled to be 'true', otherwise the server sends status code 401 -## and closes the connection. -## -## Accepted values: true, false -## Default: false -## -#redirect_login: false - ## ## Allow/Forbid Invidious (local) account creation. Invidious ## accounts allow users to subscribe to channels and to create diff --git a/src/invidious/config.cr b/src/invidious/config.cr index 3d9070203..9ae261281 100644 --- a/src/invidious/config.cr +++ b/src/invidious/config.cr @@ -94,8 +94,6 @@ class Config property captcha_enabled : Bool = true # Only allow usage of the Invidious instance with an existing account property private_instance : Bool = false - # Redirected requests to the login page on a private instance. Requires login_enabled: true - property redirect_login : Bool = false property login_enabled : Bool = true property registration_enabled : Bool = true property statistics_enabled : Bool = false diff --git a/src/invidious/routes/before_all.cr b/src/invidious/routes/before_all.cr index cd2feda63..67bdc7af1 100644 --- a/src/invidious/routes/before_all.cr +++ b/src/invidious/routes/before_all.cr @@ -99,31 +99,26 @@ module Invidious::Routes::BeforeAll "/feed/webhook/v1:", "/api/v1/videos/dQw4w9WgXcQ", "/api/v1/comments/jNQXAC9IVRw", - } + } if CONFIG.private_instance && !env.get?("user") && !unregistered_path_whitelist.any? { |r| env.request.path.starts_with? r } - if CONFIG.redirect_login && CONFIG.login_enabled - env.response.headers["Location"] = "/login" - haltf env, status_code: 302 - else - env.response.status_code = 401 - env.response.close - end + env.response.headers["Location"] = "/login" + haltf env, status_code: 302 end return if { - "/sb/", - "/vi/", - "/s_p/", - "/yts/", - "/ggpht/", - "/download", - "/licenses", - "/api/manifest/", - "/videoplayback", - "/latest_version", - "/opensearch.xml", - }.any? { |r| env.request.resource.starts_with? r } + "/sb/", + "/vi/", + "/s_p/", + "/yts/", + "/ggpht/", + "/download", + "/licenses", + "/api/manifest/", + "/videoplayback", + "/latest_version", + "/opensearch.xml", + }.any? { |r| env.request.resource.starts_with? r } 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