From 4ec0543362e58cd950d0cf23dc09fad526206ce1 Mon Sep 17 00:00:00 2001 From: Neil Lalonde <neillalonde@gmail.com> Date: Thu, 28 Nov 2013 15:57:21 -0500 Subject: [PATCH] FIX: emails with embedded posts should always use absolute URLs --- app/views/email/_post.html.erb | 2 +- lib/pretty_text.rb | 16 ++++++++++++++++ spec/components/pretty_text_spec.rb | 29 +++++++++++++++++++++++++++++ 3 files changed, 46 insertions(+), 1 deletion(-) diff --git a/app/views/email/_post.html.erb b/app/views/email/_post.html.erb index 7293eb1e341..dfa2939897f 100644 --- a/app/views/email/_post.html.erb +++ b/app/views/email/_post.html.erb @@ -10,7 +10,7 @@ </td> </tr> <tr> - <td class='body'><%= post.cooked.html_safe %></td> + <td class='body'><%= PrettyText.make_all_links_absolute(post.cooked).html_safe %></td> </tr> </tbody> </table> diff --git a/lib/pretty_text.rb b/lib/pretty_text.rb index d0c87a2fe43..84503d6c62e 100644 --- a/lib/pretty_text.rb +++ b/lib/pretty_text.rb @@ -234,6 +234,22 @@ module PrettyText fragment.to_html end + def self.make_all_links_absolute(html) + site_uri = nil + doc = Nokogiri::HTML.fragment(html) + doc.css("a").each do |l| + href = l["href"].to_s + begin + uri = URI(href) + site_uri ||= URI(Discourse.base_url) + l["href"] = "#{site_uri}#{l['href']}" unless uri.host.present? + rescue URI::InvalidURIError + # leave it + end + end + doc.to_html + end + protected def self.ctx_load(ctx, *files) diff --git a/spec/components/pretty_text_spec.rb b/spec/components/pretty_text_spec.rb index be9e55c1914..1398937d0db 100644 --- a/spec/components/pretty_text_spec.rb +++ b/spec/components/pretty_text_spec.rb @@ -177,4 +177,33 @@ describe PrettyText do end end + describe "make_all_links_absolute" do + let(:base_url) { "http://baseurl.net" } + + before do + Discourse.stubs(:base_url).returns(base_url) + end + + it "adds base url to relative links" do + html = "<p><a class=\"mention\" href=\"/users/wiseguy\">@wiseguy</a>, <a class=\"mention\" href=\"/users/trollol\">@trollol</a> what do you guys think? </p>" + output = described_class.make_all_links_absolute(html) + output.should == "<p><a class=\"mention\" href=\"#{base_url}/users/wiseguy\">@wiseguy</a>, <a class=\"mention\" href=\"#{base_url}/users/trollol\">@trollol</a> what do you guys think? </p>" + end + + it "doesn't change external absolute links" do + html = "<p>Check out <a href=\"http://mywebsite.com/users/boss\">this guy</a>.</p>" + described_class.make_all_links_absolute(html).should == html + end + + it "doesn't change internal absolute links" do + html = "<p>Check out <a href=\"#{base_url}/users/boss\">this guy</a>.</p>" + described_class.make_all_links_absolute(html).should == html + end + + it "can tolerate invalid URLs" do + html = "<p>Check out <a href=\"not a real url\">this guy</a>.</p>" + expect { described_class.make_all_links_absolute(html) }.to_not raise_error + end + end + end