inline_images.rb 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. # Copyright (C) 2012-2023 Zammad Foundation, https://zammad-foundation.org/
  2. class HtmlSanitizer
  3. module Scrubber
  4. class InlineImages < Base
  5. attr_reader :attachments_inline, :prefix
  6. def initialize(prefix = SecureRandom.uuid) # rubocop:disable Lint/MissingSuper
  7. @direction = :top_down
  8. @attachments_inline = []
  9. @prefix = prefix
  10. end
  11. def scrub(node)
  12. return CONTINUE if node.name != 'img'
  13. if node['src'] && node['src'] =~ %r{^(data:image/(jpeg|png);base64,.+?)$}i
  14. process_inline_image(node, $1)
  15. end
  16. STOP
  17. end
  18. private
  19. def inline_image_data(src)
  20. return if src.blank?
  21. matchdata = src.match %r{^(data:image/(jpeg|png);base64,.+?)$}i
  22. return if !matchdata
  23. matchdata[0]
  24. end
  25. def process_inline_image(node, data)
  26. cid = generate_cid
  27. attachment = parse_inline_image(data, cid)
  28. @attachments_inline.push attachment
  29. node['src'] = "cid:#{cid}"
  30. end
  31. def parse_inline_image(data, cid)
  32. file_attributes = ImageHelper.data_url_attributes(data)
  33. filename = "image#{@attachments_inline.length + 1}.#{file_attributes[:file_extention]}"
  34. {
  35. data: file_attributes[:content],
  36. filename: filename,
  37. preferences: {
  38. 'Content-Type' => file_attributes[:mime_type],
  39. 'Mime-Type' => file_attributes[:mime_type],
  40. 'Content-ID' => cid,
  41. 'Content-Disposition' => 'inline',
  42. }
  43. }
  44. end
  45. def generate_cid
  46. "#{prefix}.#{SecureRandom.uuid}@#{fqdn}"
  47. end
  48. def fqdn
  49. @fqdn ||= Setting.get('fqdn')
  50. end
  51. end
  52. end
  53. end