From c690fa0d19af6eb045b0f9d171798a452352e3df Mon Sep 17 00:00:00 2001 From: Robin Ward Date: Fri, 13 Jun 2014 17:11:04 -0400 Subject: [PATCH] FIX: Replace protocol relative URLs in emails --- lib/email/styles.rb | 18 +++++++++++- spec/components/email/styles_spec.rb | 44 ++++++++++++++++++++++++---- 2 files changed, 56 insertions(+), 6 deletions(-) diff --git a/lib/email/styles.rb b/lib/email/styles.rb index c848a5403e9..3c78661f08e 100644 --- a/lib/email/styles.rb +++ b/lib/email/styles.rb @@ -20,6 +20,8 @@ module Email end def format_basic + uri = URI(Discourse.base_url) + @fragment.css('img').each do |img| next if img['class'] == 'site-logo' @@ -38,7 +40,7 @@ module Email # ensure no schemaless urls if img['src'] && img['src'].starts_with?("//") - img['src'] = "http:" + img['src'] + img['src'] = "#{uri.scheme}:#{img['src']}" end end end @@ -101,6 +103,7 @@ module Email def to_html strip_classes_and_ids + replace_relative_urls @fragment.to_html.tap do |result| result.gsub!(/\[email-indent\]/, "
") result.gsub!(/\[\/email-indent\]/, "
") @@ -109,6 +112,19 @@ module Email private + def replace_relative_urls + forum_uri = URI(Discourse.base_url) + host = forum_uri.host + scheme = forum_uri.scheme + + @fragment.css('[href]').each do |element| + href = element['href'] + if href =~ /^\/\/#{host}/ + element['href'] = "#{scheme}:#{href}" + end + end + end + def correct_first_body_margin @fragment.css('.body p').each do |element| element['style'] = "margin-top:0; border: 0;" diff --git a/spec/components/email/styles_spec.rb b/spec/components/email/styles_spec.rb index cfa75c8bae6..6b4fdaed8cb 100644 --- a/spec/components/email/styles_spec.rb +++ b/spec/components/email/styles_spec.rb @@ -40,11 +40,6 @@ describe Email::Styles do expect(frag.at("img")["src"]).to eq("#{Discourse.base_url}/some-image.png") end - it "prefixes schemaless image urls with http:" do - frag = basic_fragment("") - expect(frag.at("img")["src"]).to eq("http://www.discourse.com/some-image.gif") - end - it "strips classes and ids" do frag = basic_fragment("
") expect(frag.to_html).to eq("
") @@ -84,6 +79,45 @@ describe Email::Styles do expect(frag.at('ul')['style']).to be_present expect(frag.at('li')['style']).to be_present end + end + + context "rewriting protocol relative URLs to the forum" do + it "doesn't rewrite a url to another site" do + frag = html_fragment('hello') + frag.at('a')['href'].should == "//youtube.com/discourse" + end + + context "without https" do + before do + SiteSetting.stubs(:use_https).returns(false) + end + + it "rewrites the href to have http" do + frag = html_fragment('hello') + frag.at('a')['href'].should == "http://test.localhost/discourse" + end + + it "rewrites the src to have http" do + frag = html_fragment('') + frag.at('img')['src'].should == "http://test.localhost/blah.jpg" + end + end + + context "with https" do + before do + SiteSetting.stubs(:use_https).returns(true) + end + + it "rewrites the forum URL to have http" do + frag = html_fragment('hello') + frag.at('a')['href'].should == "https://test.localhost/discourse" + end + + it "rewrites the src to have https" do + frag = html_fragment('') + frag.at('img')['src'].should == "https://test.localhost/blah.jpg" + end + end end