message_validator.rb 3.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. # Copyright (C) 2012-2025 Zammad Foundation, https://zammad-foundation.org/
  2. class Channel::Driver::BaseEmailInbound
  3. class MessageValidator
  4. attr_reader :headers, :size
  5. # @param headers [Hash] in key-value format
  6. # @param size [Integer] in bytes
  7. def initialize(headers, size = nil)
  8. @headers = headers
  9. @size = size
  10. end
  11. # Checks if email is not too big for processing
  12. #
  13. # This method is used by IMAP and MicrosoftGraphInbound only
  14. # It may be possible to reuse them with POP3 too, but it needs further refactoring
  15. def too_large?
  16. max_message_size = Setting.get('postmaster_max_size').to_f
  17. real_message_size = size.to_f / 1024 / 1024
  18. if real_message_size > max_message_size
  19. return [real_message_size, max_message_size]
  20. end
  21. false
  22. end
  23. # Checks if a message with the given headers is a Zammad verify message
  24. #
  25. # This method is used by IMAP and MicrosoftGraphInbound only
  26. # It may be possible to reuse them with POP3 too, but it needs further refactoring
  27. def verify_message?
  28. headers['X-Zammad-Verify'] == 'true'
  29. end
  30. # Checks if a message with the given headers marked to be ignored by Zammad
  31. #
  32. # This method is used by IMAP and MicrosoftGraphInbound only
  33. # It may be possible to reuse them with POP3 too, but it needs further refactoring
  34. def ignore?
  35. headers['X-Zammad-Ignore'] == 'true'
  36. end
  37. # Checks if a message is a new Zammad verify message
  38. #
  39. # Returns false only if a verify message is less than 30 minutes old
  40. #
  41. # This method is used by IMAP and MicrosoftGraphInbound only
  42. # It may be possible to reuse them with POP3 too, but it needs further refactoring
  43. def fresh_verify_message?
  44. return false if !verify_message?
  45. return false if headers['X-Zammad-Verify-Time'].blank?
  46. begin
  47. verify_time = Time.zone.parse(headers['X-Zammad-Verify-Time'])
  48. rescue => e
  49. Rails.logger.error e
  50. return false
  51. end
  52. verify_time > 30.minutes.ago
  53. end
  54. # Checks if a message is already imported in a given channel
  55. # This check is skipped for channels which do not keep messages on the server
  56. #
  57. # This method is used by IMAP and MicrosoftGraphInbound only
  58. # It may be possible to reuse them with POP3 too, but it needs further refactoring
  59. def already_imported?(keep_on_server, channel)
  60. return false if !keep_on_server
  61. return false if !headers
  62. local_message_id = headers['Message-ID']
  63. return false if local_message_id.blank?
  64. local_message_id_md5 = Digest::MD5.hexdigest(local_message_id)
  65. article = Ticket::Article.where(message_id_md5: local_message_id_md5).reorder('created_at DESC, id DESC').limit(1).first
  66. return false if !article
  67. # verify if message is already imported via same channel, if not, import it again
  68. ticket = article.ticket
  69. return false if ticket&.preferences && ticket.preferences[:channel_id].present? && channel.present? && ticket.preferences[:channel_id] != channel[:id]
  70. true
  71. end
  72. end
  73. end