diff --git a/app/models/channel/driver/imap.rb b/app/models/channel/driver/imap.rb index 42c7c8e46..89ccf342c 100644 --- a/app/models/channel/driver/imap.rb +++ b/app/models/channel/driver/imap.rb @@ -145,11 +145,12 @@ example end # check how many content messages we have, for notice used - header = message_meta['RFC822.HEADER'] - if header && header !~ /x-zammad-ignore/i - content_messages += 1 - break if content_max_check < content_messages - end + headers = parse_headers(message_meta['RFC822.HEADER']) + next if messages_is_verify_message?(headers) + next if messages_is_ignore_message?(headers) + + content_messages += 1 + break if content_max_check < content_messages end if content_messages >= content_max_check content_messages = message_ids.count @@ -207,9 +208,12 @@ example message_meta = nil timeout(1.minute) do - message_meta = @imap.fetch(message_id, ['RFC822.SIZE', 'ENVELOPE', 'FLAGS', 'INTERNALDATE'])[0] + message_meta = @imap.fetch(message_id, ['RFC822.SIZE', 'ENVELOPE', 'FLAGS', 'INTERNALDATE', 'RFC822.HEADER'])[0] end + # ignore verify messages + next if !messages_is_too_old_verify?(message_meta, count, count_all) + # ignore to big messages info = too_big?(message_meta, count, count_all) if info @@ -283,6 +287,50 @@ returns private + def messages_is_too_old_verify?(message_meta, count, count_all) + headers = parse_headers(message_meta.attr['RFC822.HEADER']) + return true if !messages_is_verify_message?(headers) + return true if headers['X-Zammad-Verify-Time'].blank? + + begin + verify_time = Time.zone.parse(headers['X-Zammad-Verify-Time']) + rescue => e + Rails.logger.error e + return true + end + return true if verify_time < Time.zone.now - 30.minutes + + Rails.logger.info " - ignore message #{count}/#{count_all} - because message has a verify message" + + false + end + + def messages_is_verify_message?(headers) + return true if headers['X-Zammad-Verify'] == 'true' + + false + end + + def messages_is_ignore_message?(headers) + return true if headers['X-Zammad-Ignore'] == 'true' + + false + end + + def parse_headers(string) + return {} if string.blank? + + headers = {} + headers_pairs = string.split("\r\n") + headers_pairs.each do |pair| + key_value = pair.split(': ') + next if key_value[0].blank? + + headers[key_value[0]] = key_value[1] + end + headers + end + # rubocop:disable Metrics/ParameterLists def already_imported?(message_id, message_meta, count, count_all, keep_on_server, channel) # rubocop:enable Metrics/ParameterLists diff --git a/app/models/channel/driver/pop3.rb b/app/models/channel/driver/pop3.rb index 346f9d444..71725824f 100644 --- a/app/models/channel/driver/pop3.rb +++ b/app/models/channel/driver/pop3.rb @@ -91,7 +91,7 @@ returns next if !mail # check how many content messages we have, for notice used - if !mail.match?(/x-zammad-ignore/i) + if !mail.match?(/(X-Zammad-Ignore: true|X-Zammad-Verify: true)/) content_messages += 1 break if content_max_check < content_messages end @@ -112,7 +112,7 @@ returns mails.reverse! # check for verify message - mails.each do |m| + mails.first(2000).each do |m| mail = m.pop next if !mail @@ -137,12 +137,28 @@ returns count = 0 count_fetched = 0 notice = '' - mails.each do |m| + mails.first(2000).each do |m| count += 1 Rails.logger.info " - message #{count}/#{count_all}" mail = m.pop next if !mail + # ignore verify messages + if mail.match?(/(X-Zammad-Ignore: true|X-Zammad-Verify: true)/) + if mail =~ /X-Zammad-Verify-Time:\s(.+?)\s/ + begin + verify_time = Time.zone.parse($1) + if verify_time > Time.zone.now - 30.minutes + info = " - ignore message #{count}/#{count_all} - because it's a verify message" + Rails.logger.info info + next + end + rescue => e + Rails.logger.error e + end + end + end + # ignore to big messages max_message_size = Setting.get('postmaster_max_size').to_f real_message_size = mail.size.to_f / 1024 / 1024 diff --git a/lib/email_helper/probe.rb b/lib/email_helper/probe.rb index fcdad877a..f44404851 100644 --- a/lib/email_helper/probe.rb +++ b/lib/email_helper/probe.rb @@ -308,10 +308,13 @@ returns on fail body: "This is a Test Email of Zammad to verify if Zammad can send emails to an external address.\n\nIf you see this email, you can ignore and delete it.", } end - if subject + if subject.present? mail['X-Zammad-Test-Message'] = subject end mail['X-Zammad-Ignore'] = 'true' + mail['X-Zammad-Fqdn'] = Setting.get('fqdn') + mail['X-Zammad-Verify'] = 'true' + mail['X-Zammad-Verify-Time'] = Time.zone.now.iso8601 mail['X-Loop'] = 'yes' mail['Precedence'] = 'bulk' mail['Auto-Submitted'] = 'auto-generated'