Browse Source

Fixes #5258 - Inline images in outgoing mails break HTML structure.

Florian Liebe 7 months ago
parent
commit
77c5408b9d

+ 1 - 13
app/models/channel/email_build.rb

@@ -100,7 +100,7 @@ generate email with S/MIME
         logger.error e
       end
 
-      html_alternative.body = Channel::EmailBuild.adjust_inline_image_size(html_alternative.body.to_s) if found_content_ids.present?
+      html_alternative.body = HtmlSanitizer.adjust_inline_image_size(html_alternative.body.to_s) if found_content_ids.present?
 
       html_container = Mail::Part.new { content_type 'multipart/related' }
       html_container.add_part html_alternative
@@ -225,16 +225,4 @@ Add/change markup to display html in any mail client nice.
     new_html.gsub!(%r{</?hr>}mxi, '<hr style="margin-top: 6px; margin-bottom: 6px; border: 0; border-top: 1px solid #dfdfdf;">')
     new_html
   end
-
-=begin
-
-Adjust image size in html email for MS Outlook to always contain `width` and `height` as tags, not only as part of the `style`.
-
-  html_string_with_adjustments = Channel::EmailBuild.adjust_inline_image_size(html_string)
-
-=end
-
-  def self.adjust_inline_image_size(html)
-    Loofah.fragment(html).scrub!(HtmlSanitizer::Scrubber::Outgoing::ImageSize.new).to_html
-  end
 end

+ 1 - 1
lib/html_sanitizer.rb

@@ -57,7 +57,7 @@ sanitize style of img tags
 
 =begin
 
-Adjust height + width of img tags
+Adjust image size in html email for MS Outlook to always contain `width` and `height` as tags, not only as part of the `style`.
 
   string = HtmlSanitizer.adjust_inline_image_size(article.body)
 

+ 7 - 4
lib/html_sanitizer/adjust_inline_image_size.rb

@@ -3,10 +3,13 @@
 class HtmlSanitizer
   class AdjustInlineImageSize
     def sanitize(string)
-      Loofah
-        .fragment(string)
-        .scrub!(HtmlSanitizer::Scrubber::Outgoing::ImageSize.new)
-        .to_html
+      return string if string.exclude? '<img'
+
+      scrubber = HtmlSanitizer::Scrubber::Outgoing::ImageSize.new
+
+      return Loofah.scrub_document(string, scrubber).to_html if string.include? '<html'
+
+      Loofah.fragment(string).scrub!(scrubber).to_html
     end
   end
 end

+ 26 - 0
spec/models/channel/email_build/inline_image_adjustments_spec.rb

@@ -37,7 +37,33 @@ RSpec.describe 'Channel::EmailBuild > Inline Images Adjustments', aggregate_fail
 
   context 'when an email is built with inline images' do
     it 'adjusts the inline images width and height' do
+      expect(mail.html_part.body.to_s).to include('<!DOCTYPE html>')
+      expect(mail.html_part.body.to_s).to include('font-family:Geneva,Helvetica,Arial,sans-serif; font-size: 12px;')
       expect(mail.html_part.body.to_s).to include('<img style="width: 125px; max-width: 100%; height: 187.5px;" src="cid:1.e83460e9-7e36-48f7-97db-dc7f0ba7c51f@zammad.example.com" height="187.5" width="125">')
     end
   end
+
+  context 'when no complete HTML document is provided' do
+    let(:html_body) do
+      <<~HTML.chomp
+        <img style="width: 125px; max-width: 100%; height: 187.5px;" src="cid:1.e83460e9-7e36-48f7-97db-dc7f0ba7c51f@zammad.example.com">
+        <br><br>
+        <div data-signature="true" data-signature-id="1">
+          Test Admin Agent<br><br>
+          --<br>
+          Super Support - Waterford Business Park<br>
+          5201 Blue Lagoon Drive - 8th Floor &amp; 9th Floor - Miami, 33126 USA<br>
+          Email: hot@example.com - Web: <a href="http://www.example.com/" rel="nofollow noreferrer noopener" target="_blank">http://www.example.com/</a><br>
+          --
+        </div>
+      HTML
+    end
+
+    it 'completes the HTML document and adjusts the inline images width and height' do
+      expect(mail.html_part.body.to_s).to include('<!DOCTYPE html>')
+      expect(mail.html_part.body.to_s).to include("font-family:'Helvetica Neue', Helvetica, Arial, Geneva, sans-serif; font-size: 12px;")
+      expect(mail.html_part.body.to_s).to include('<img style="width: 125px; max-width: 100%; height: 187.5px;" src="cid:1.e83460e9-7e36-48f7-97db-dc7f0ba7c51f@zammad.example.com" height="187.5" width="125">')
+    end
+
+  end
 end