diff --git a/app/controllers/admin/settings/general_settings_controller.rb b/app/controllers/admin/settings/general_settings_controller.rb index 711c03bcf93..1a7175bf00e 100644 --- a/app/controllers/admin/settings/general_settings_controller.rb +++ b/app/controllers/admin/settings/general_settings_controller.rb @@ -32,7 +32,9 @@ module Admin::Settings def settings_params super.tap do |settings| - settings["allowed_link_protocols"] = settings["allowed_link_protocols"].split(/\r?\n/) + settings["allowed_link_protocols"] = settings["allowed_link_protocols"] + .split(/\r?\n/) + .map { |protocol| protocol.strip.downcase.gsub(/[^a-z0-9+\-.]+/, "") } end end diff --git a/frontend/src/app/shared/components/editor/components/ckeditor/ckeditor-setup.service.ts b/frontend/src/app/shared/components/editor/components/ckeditor/ckeditor-setup.service.ts index 8f3253916ee..2721da2de9b 100644 --- a/frontend/src/app/shared/components/editor/components/ckeditor/ckeditor-setup.service.ts +++ b/frontend/src/app/shared/components/editor/components/ckeditor/ckeditor-setup.service.ts @@ -106,7 +106,7 @@ export class CKEditorSetupService { const allowedLinkProtocols = this.configurationService.allowedLinkProtocols; if (allowedLinkProtocols) { - config.link = { allowedProtocols: allowedLinkProtocols }; + config.link = { allowedProtocols: allowedLinkProtocols.map((el:string) => _.escapeRegExp(el)) }; } return config; diff --git a/lib/open_project/text_formatting/filters/autolink_custom_protocols_filter.rb b/lib/open_project/text_formatting/filters/autolink_custom_protocols_filter.rb index 1c817834e24..82596bd45c3 100644 --- a/lib/open_project/text_formatting/filters/autolink_custom_protocols_filter.rb +++ b/lib/open_project/text_formatting/filters/autolink_custom_protocols_filter.rb @@ -45,9 +45,15 @@ module OpenProject::TextFormatting # Skip text nodes that are within preformatted or linked blocks SKIPPED_BLOCKS = %w(pre code kbd a).to_set + def self.protocols + Setting + .allowed_link_protocols + .map { |protocol| Regexp.escape(protocol) } + end + # Match custom schemes and ignore trailing punctuation def self.regexp - %r{((?:#{Setting.allowed_link_protocols.join('|')}):/?/?[^\s<\u00A0"]*[^\s<\u00A0",;\.])}i + %r{((?:#{protocols.join('|')}):/?/?[^\s<\u00A0"]*[^\s<\u00A0",;\.])}i end def call diff --git a/spec/features/admin/allowed_link_protocols_spec.rb b/spec/features/admin/allowed_link_protocols_spec.rb index 4dda8ebd881..ab1ad9de3aa 100644 --- a/spec/features/admin/allowed_link_protocols_spec.rb +++ b/spec/features/admin/allowed_link_protocols_spec.rb @@ -57,5 +57,15 @@ RSpec.describe "Allowed link protocols", :js do expect(Setting.allowed_link_protocols).to match_array(custom_protocols) expect(Setting::AllowedLinkProtocols.all).to include(*custom_protocols) expect(Setting::AllowedLinkProtocols.all).to include(*always_allowed_protocols) + + scroll_to_element find_by_id("settings_allowed_link_protocols") + custom_protocols = %w[http+ssh f[oa]x] + find_by_id("settings_allowed_link_protocols").set(custom_protocols.join("\n")) + + click_on "Save" + expect(page).to have_text I18n.t(:notice_successful_update) + + RequestStore.clear! + expect(Setting.allowed_link_protocols).to contain_exactly("http+ssh", "foax") end end