From 97a4026cfdaa5c41e01c5e246c5bbf3b2dae5b07 Mon Sep 17 00:00:00 2001 From: "Pia B." Date: Thu, 1 Oct 2026 14:16:38 +0000 Subject: [PATCH] add new tab to server settings for external discovery (#40768) --- .../admin/settings/external_controller.rb | 9 +++ .../admin/settings/discovery/show.html.haml | 45 -------------- .../admin/settings/external/show.html.haml | 59 +++++++++++++++++++ .../admin/settings/shared/_links.html.haml | 1 + config/locales/en-GB.yml | 5 +- config/locales/en.yml | 7 ++- config/routes/admin.rb | 1 + spec/requests/admin/settings/external_spec.rb | 29 +++++++++ 8 files changed, 107 insertions(+), 49 deletions(-) create mode 100644 app/controllers/admin/settings/external_controller.rb create mode 100644 app/views/admin/settings/external/show.html.haml create mode 100644 spec/requests/admin/settings/external_spec.rb diff --git a/app/controllers/admin/settings/external_controller.rb b/app/controllers/admin/settings/external_controller.rb new file mode 100644 index 00000000000..f6ec99c5e18 --- /dev/null +++ b/app/controllers/admin/settings/external_controller.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +class Admin::Settings::ExternalController < Admin::SettingsController + private + + def after_update_redirect_path + admin_settings_external_path + end +end diff --git a/app/views/admin/settings/discovery/show.html.haml b/app/views/admin/settings/discovery/show.html.haml index eabace0417c..57425f2968f 100644 --- a/app/views/admin/settings/discovery/show.html.haml +++ b/app/views/admin/settings/discovery/show.html.haml @@ -55,51 +55,6 @@ label_method: ->(mode) { I18n.t("admin.settings.feed_access.modes.#{mode}") }, wrapper: :with_label - %h2= t('admin.settings.discovery.privacy') - - .fields-group - = f.input :noindex, - as: :boolean, - hint: t('admin.settings.default_noindex.desc_html'), - label: t('admin.settings.default_noindex.title'), - wrapper: :with_label - - .fields-group - = f.input :allow_referrer_origin, - as: :boolean, - hint: t('admin.settings.allow_referrer_origin.desc'), - label: t('admin.settings.allow_referrer_origin.title'), - wrapper: :with_label - - %h2= t('admin.settings.discovery.publish_statistics') - - .fields-group - = f.input :activity_api_enabled, - as: :boolean, - wrapper: :with_label, - recommended: :recommended - - .fields-group - = f.input :peers_api_enabled, - as: :boolean, - wrapper: :with_label, - recommended: :recommended - - %h2= t('admin.settings.security.federation_authentication') - - .fields-group - = f.input :authorized_fetch, - as: :radio_buttons, - collection: f.object.class::AUTHORIZED_FETCH_MODES, - disabled: authorized_fetch_overridden?, - hint: authorized_fetch_hint_text, - label: t('admin.settings.security.authorized_fetch'), - include_blank: false, - label_method: ->(mode) { safe_join([I18n.t(mode, scope: 'admin.settings.security.authorized_fetch_modes'), content_tag(:span, I18n.t(mode, scope: 'admin.settings.security.authorized_fetch_hints'), class: 'hint')]) }, - recommended: authorized_fetch_recommended_value, - warning_hint: authorized_fetch_warning_hint_text, - wrapper: :with_block_label - %h2= t('admin.settings.discovery.follow_recommendations') .fields-group diff --git a/app/views/admin/settings/external/show.html.haml b/app/views/admin/settings/external/show.html.haml new file mode 100644 index 00000000000..8ef4ea453e0 --- /dev/null +++ b/app/views/admin/settings/external/show.html.haml @@ -0,0 +1,59 @@ +- content_for :page_title do + = t('admin.settings.external.title') + +- content_for :heading do + %h1= t('admin.settings.title') + = render partial: 'admin/settings/shared/links' + += simple_form_for @admin_settings, url: admin_settings_external_path do |f| + = render 'shared/error_messages', object: @admin_settings + + %p.lead= t('admin.settings.external.preamble') + + %h2= t('admin.settings.external.privacy') + + .fields-group + = f.input :noindex, + as: :boolean, + hint: t('admin.settings.default_noindex.desc_html'), + label: t('admin.settings.default_noindex.title'), + wrapper: :with_label + + .fields-group + = f.input :allow_referrer_origin, + as: :boolean, + hint: t('admin.settings.allow_referrer_origin.desc'), + label: t('admin.settings.allow_referrer_origin.title'), + wrapper: :with_label + + %h2= t('admin.settings.external.publish_statistics') + + .fields-group + = f.input :activity_api_enabled, + as: :boolean, + wrapper: :with_label, + recommended: :recommended + + .fields-group + = f.input :peers_api_enabled, + as: :boolean, + wrapper: :with_label, + recommended: :recommended + + %h2= t('admin.settings.security.federation_authentication') + + .fields-group + = f.input :authorized_fetch, + as: :radio_buttons, + collection: f.object.class::AUTHORIZED_FETCH_MODES, + disabled: authorized_fetch_overridden?, + hint: authorized_fetch_hint_text, + label: t('admin.settings.security.authorized_fetch'), + include_blank: false, + label_method: ->(mode) { safe_join([I18n.t(mode, scope: 'admin.settings.security.authorized_fetch_modes'), content_tag(:span, I18n.t(mode, scope: 'admin.settings.security.authorized_fetch_hints'), class: 'hint')]) }, + recommended: authorized_fetch_recommended_value, + warning_hint: authorized_fetch_warning_hint_text, + wrapper: :with_block_label + + .actions + = f.button :button, t('generic.save_changes'), type: :submit diff --git a/app/views/admin/settings/shared/_links.html.haml b/app/views/admin/settings/shared/_links.html.haml index c03e5cfd9fa..8f43c9a3809 100644 --- a/app/views/admin/settings/shared/_links.html.haml +++ b/app/views/admin/settings/shared/_links.html.haml @@ -5,5 +5,6 @@ primary.item :about, safe_join([material_symbol('description'), t('admin.settings.about.title')]), admin_settings_about_path primary.item :registrations, safe_join([material_symbol('group'), t('admin.settings.registrations.title')]), admin_settings_registrations_path primary.item :discovery, safe_join([material_symbol('search'), t('admin.settings.discovery.title')]), admin_settings_discovery_path + primary.item :external, safe_join([material_symbol('globe'), t('admin.settings.external.title')]), admin_settings_external_path primary.item :content_retention, safe_join([material_symbol('history'), t('admin.settings.content_retention.title')]), admin_settings_content_retention_path primary.item :appearance, safe_join([material_symbol('computer'), t('admin.settings.appearance.title')]), admin_settings_appearance_path diff --git a/config/locales/en-GB.yml b/config/locales/en-GB.yml index 23c1fb2f50a..21169b4f0fd 100644 --- a/config/locales/en-GB.yml +++ b/config/locales/en-GB.yml @@ -879,10 +879,8 @@ en-GB: discovery: follow_recommendations: Follow recommendations preamble: Surfacing interesting content is instrumental in onboarding new users who may not know anyone on Mastodon. Control how various discovery features work on your server. - privacy: Privacy profile_directory: Profile directory public_timelines: Public timelines - publish_statistics: Publish statistics title: Discovery trends: Trends wrapstodon: Wrapstodon @@ -890,6 +888,9 @@ en-GB: all: To everyone disabled: To no one users: To logged-in local users + external: + preamble: Control how much information about your server gets shared with other services and how discoverable your server should be. + title: External Discovery feed_access: modes: authenticated: Authenticated users only diff --git a/config/locales/en.yml b/config/locales/en.yml index dbcb68e9c9e..e27c9dea8ba 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -987,10 +987,8 @@ en: discovery: follow_recommendations: Follow recommendations preamble: Surfacing interesting content is instrumental in onboarding new users who may not know anyone on Mastodon. Control how various discovery features work on your server. - privacy: Privacy profile_directory: Profile directory public_timelines: Public timelines - publish_statistics: Publish statistics title: Discovery trends: Trends wrapstodon: Wrapstodon @@ -998,6 +996,11 @@ en: all: To everyone disabled: To no one users: To logged-in local users + external: + preamble: Control how much information about your server gets shared with other services and how discoverable your server should be. + privacy: Privacy + publish_statistics: Publish statistics + title: External Discovery feed_access: modes: authenticated: Authenticated users only diff --git a/config/routes/admin.rb b/config/routes/admin.rb index 38f40052413..68da27421be 100644 --- a/config/routes/admin.rb +++ b/config/routes/admin.rb @@ -83,6 +83,7 @@ namespace :admin do resource :about, only: [:show, :update], controller: 'about' resource :appearance, only: [:show, :update], controller: 'appearance' resource :discovery, only: [:show, :update], controller: 'discovery' + resource :external, only: [:show, :update], controller: 'external' end resources :site_uploads, only: [:destroy] diff --git a/spec/requests/admin/settings/external_spec.rb b/spec/requests/admin/settings/external_spec.rb new file mode 100644 index 00000000000..5aaa1f07ce2 --- /dev/null +++ b/spec/requests/admin/settings/external_spec.rb @@ -0,0 +1,29 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe 'Admin Settings External Discovery' do + describe 'When signed in as an admin' do + before { sign_in Fabricate(:admin_user) } + + describe 'PUT /admin/settings/external' do + it 'cannot create a setting value for a non-admin key' do + expect { put admin_settings_external_path, params: { form_admin_settings: { new_setting_key: 'New key value' } } } + .to_not change(Setting, :new_setting_key).from(nil) + + expect(response) + .to have_http_status(400) + end + end + + describe 'PUT /admin/settings/external with valid params' do + let(:request) { put admin_settings_external_path, params: { form_admin_settings: { activity_api_enabled: 'false' } } } + + it 'saves the value for a valid key' do + expect { request }.to change(Setting, :activity_api_enabled).from(true) + expect(request).to redirect_to(admin_settings_external_path) + expect(response).to have_http_status(302) + end + end + end +end