Commit 0ea170b4 authored by Yorick Peterse's avatar Yorick Peterse

Merge branch '18582-banzai-filter-external-link-filter' into 'master'

Banzai::Filter::ExternalLinkFilter use XPath

See merge request !4702
parents 3fdf104b ae6a54f7
...@@ -120,6 +120,7 @@ v 8.8.5 ...@@ -120,6 +120,7 @@ v 8.8.5
- Forbid scripting for wiki files - Forbid scripting for wiki files
- Only show notes through JSON on confidential issues that the user has access to - Only show notes through JSON on confidential issues that the user has access to
- Banzai::Filter::UploadLinkFilter use XPath instead CSS expressions - Banzai::Filter::UploadLinkFilter use XPath instead CSS expressions
- Banzai::Filter::ExternalLinkFilter use XPath instead CSS expressions
v 8.8.4 v 8.8.4
- Fix LDAP-based login for users with 2FA enabled. !4493 - Fix LDAP-based login for users with 2FA enabled. !4493
......
...@@ -3,17 +3,8 @@ module Banzai ...@@ -3,17 +3,8 @@ module Banzai
# HTML Filter to modify the attributes of external links # HTML Filter to modify the attributes of external links
class ExternalLinkFilter < HTML::Pipeline::Filter class ExternalLinkFilter < HTML::Pipeline::Filter
def call def call
doc.search('a').each do |node| # Skip non-HTTP(S) links and internal links
link = node.attr('href') doc.xpath("descendant-or-self::a[starts-with(@href, 'http') and not(starts-with(@href, '#{internal_url}'))]").each do |node|
next unless link
# Skip non-HTTP(S) links
next unless link.start_with?('http')
# Skip internal links
next if link.start_with?(internal_url)
node.set_attribute('rel', 'nofollow noreferrer') node.set_attribute('rel', 'nofollow noreferrer')
node.set_attribute('target', '_blank') node.set_attribute('target', '_blank')
end end
......
...@@ -19,19 +19,31 @@ describe Banzai::Filter::ExternalLinkFilter, lib: true do ...@@ -19,19 +19,31 @@ describe Banzai::Filter::ExternalLinkFilter, lib: true do
expect(filter(act).to_html).to eq exp expect(filter(act).to_html).to eq exp
end end
it 'adds rel="nofollow" to external links' do context 'for root links on document' do
act = %q(<a href="https://google.com/">Google</a>) let(:doc) { filter %q(<a href="https://google.com/">Google</a>) }
doc = filter(act)
it 'adds rel="nofollow" to external links' do
expect(doc.at_css('a')).to have_attribute('rel') expect(doc.at_css('a')).to have_attribute('rel')
expect(doc.at_css('a')['rel']).to include 'nofollow' expect(doc.at_css('a')['rel']).to include 'nofollow'
end end
it 'adds rel="noreferrer" to external links' do it 'adds rel="noreferrer" to external links' do
act = %q(<a href="https://google.com/">Google</a>) expect(doc.at_css('a')).to have_attribute('rel')
doc = filter(act) expect(doc.at_css('a')['rel']).to include 'noreferrer'
end
end
context 'for nested links on document' do
let(:doc) { filter %q(<p><a href="https://google.com/">Google</a></p>) }
it 'adds rel="nofollow" to external links' do
expect(doc.at_css('a')).to have_attribute('rel')
expect(doc.at_css('a')['rel']).to include 'nofollow'
end
it 'adds rel="noreferrer" to external links' do
expect(doc.at_css('a')).to have_attribute('rel') expect(doc.at_css('a')).to have_attribute('rel')
expect(doc.at_css('a')['rel']).to include 'noreferrer' expect(doc.at_css('a')['rel']).to include 'noreferrer'
end end
end
end end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment