diff --git a/locales/en-US.json b/locales/en-US.json index 2d0adc27..1aa2ab92 100644 --- a/locales/en-US.json +++ b/locales/en-US.json @@ -504,5 +504,7 @@ "preferences_search_enabled_label": "Search enabled: ", "timeline_parse_error_placeholder_heading": "Unable to parse item", "timeline_parse_error_placeholder_message": "Invidious encountered an error while trying to parse this item. For more information see below:", - "timeline_parse_error_show_technical_details": "Show technical details" -} + "timeline_parse_error_show_technical_details": "Show technical details", + "Search has been disabled by the administrator.": "Search has been disabled by the administrator.", + "This helps protect our community. Learn more": "This helps protect our community. Learn more" +} \ No newline at end of file diff --git a/src/invidious/config.cr b/src/invidious/config.cr index 9bf5be44..36cb40a3 100644 --- a/src/invidious/config.cr +++ b/src/invidious/config.cr @@ -111,13 +111,29 @@ class Config # Used to tell Invidious it is behind a proxy, so links to resources should be https:// property https_only : Bool? + # HMAC signing key for CSRF tokens and verifying pubsub subscriptions property hmac_key : String = "" # Domain to be used for links to resources on the site where an absolute URL is required property domain : String? # Subscribe to channels using PubSubHubbub (requires domain, hmac_key) property use_pubsub_feeds : Bool | Int32 = false - property pages_enabled : Hash(String, Bool) = {"trending" => true, "popular" => true, "search" => true} + + # ————————————————————————————————————————————————————————————————————————————————————— + # DEPRECATED: use `pages_enabled["popular"]` instead. + @[Deprecated("`popular_enabled` will be removed in a future release; use pages_enabled[\"popular\"] instead")] + property popular_enabled : Bool = true + + # Global per-page feature toggles. + # Valid keys: "trending", "popular", "search" + # If someone sets both `popular_enabled` and `pages_enabled["popular"]`, the latter takes precedence. + property pages_enabled : Hash(String, Bool) = { + "trending" => true, + "popular" => true, + "search" => true, + } + # ————————————————————————————————————————————————————————————————————————————————————— + property captcha_enabled : Bool = true property login_enabled : Bool = true property registration_enabled : Bool = true @@ -188,18 +204,21 @@ class Config when Bool return disabled when Array - if disabled.includes? option - return true - else - return false - end + disabled.includes?(option) else - return false + false end end + # Centralized page toggle with legacy fallback for `popular_enabled` def page_enabled?(page : String) : Bool - @pages_enabled[page]? || false + if pages_enabled.has_key?(page) + pages_enabled[page] + elsif page == "popular" + popular_enabled + else + true + end end def self.load diff --git a/src/invidious/routes/search.cr b/src/invidious/routes/search.cr index cbae9183..bd76775d 100644 --- a/src/invidious/routes/search.cr +++ b/src/invidious/routes/search.cr @@ -40,79 +40,51 @@ module Invidious::Routes::Search prefs = env.get("preferences").as(Preferences) locale = prefs.locale - if CONFIG.page_enabled?("search") - region = env.params.query["region"]? || prefs.region - - query = Invidious::Search::Query.new(env.params.query, :regular, region) - - if query.empty? - # Display the full page search box implemented in #1977 - env.set "search", "" - templated "search_homepage", navbar_search: false - else - user = env.get? "user" - - # An URL was copy/pasted in the search box. - # Redirect the user to the appropriate page. - if query.url? - return env.redirect UrlSanitizer.process(query.text).to_s - end - - begin - if user - items = query.process(user.as(User)) - else - items = query.process - end - rescue ex : ChannelSearchException - return error_template(404, "Unable to find channel with id of '#{HTML.escape(ex.channel)}'. Are you sure that's an actual channel id? It should look like 'UC4QobU6STFB0P71PMvOGN5A'.") - rescue ex - return error_template(500, ex) - end - - redirect_url = Invidious::Frontend::Misc.redirect_url(env) - - # Pagination - page_nav_html = Frontend::Pagination.nav_numeric(locale, - base_url: "/search?#{query.to_http_params}", - current_page: query.page, - show_next: (items.size >= 20) - ) - - if query.type == Invidious::Search::Query::Type::Channel - env.set "search", "channel:#{query.channel} #{query.text}" - else - user = env.get? "user" - - begin - items = query.process - rescue ex : ChannelSearchException - return error_template(404, "Unable to find channel with id of '#{HTML.escape(ex.channel)}'. Are you sure that's an actual channel id? It should look like 'UC4QobU6STFB0P71PMvOGN5A'.") - rescue ex - return error_template(500, ex) - end - - redirect_url = Invidious::Frontend::Misc.redirect_url(env) - - # Pagination - page_nav_html = Frontend::Pagination.nav_numeric(locale, - base_url: "/search?#{query.to_http_params}", - current_page: query.page, - show_next: (items.size >= 20) - ) - - if query.type == Invidious::Search::Query::Type::Channel - env.set "search", "channel:#{query.channel} #{query.text}" - else - env.set "search", query.text - end - - templated "search" - end - else + # if search is disabled, show the “disabled” message immediately + unless CONFIG.page_enabled?("search") message = translate(locale, "Search has been disabled by the administrator.") - templated "message" + return templated "message" end + + # otherwise, do a normal search + region = env.params.query["region"]? || prefs.region + query = Invidious::Search::Query.new(env.params.query, :regular, region) + + # empty query → show homepage + if query.empty? + env.set "search", "" + return templated "search_homepage", navbar_search: false + end + + # non‐empty query → process it + user = env.get?("user") + if query.url? + return env.redirect UrlSanitizer.process(query.text).to_s + end + + begin + items = user ? query.process(user.as(User)) : query.process + rescue ex : ChannelSearchException + return error_template 404, "Unable to find channel with id “#{HTML.escape(ex.channel)}”…" + rescue ex + return error_template 500, ex + end + + # Pagination + page_nav_html = Frontend::Pagination.nav_numeric(locale, + base_url: "/search?#{query.to_http_params}", + current_page: query.page, + show_next: (items.size >= 20) + ) + + # If it's a channel search, prefix the box; otherwise just show the text + if query.type == Invidious::Search::Query::Type::Channel + env.set "search", "channel:#{query.channel} #{query.text}" + else + env.set "search", query.text + end + + templated "search" end def self.hashtag(env : HTTP::Server::Context)