diff --git a/app/models/channel/email_parser.rb b/app/models/channel/email_parser.rb index 216e56cc4..dde40eeb7 100644 --- a/app/models/channel/email_parser.rb +++ b/app/models/channel/email_parser.rb @@ -78,6 +78,8 @@ class Channel::EmailParser msg = Mail::Utilities.binary_unsafe_to_crlf(msg) mail = Mail.new(msg) + message_ensure_message_id(msg, mail) + force_parts_encoding_if_needed(mail) headers = message_header_hash(mail) @@ -545,6 +547,17 @@ process unprocessable_mails (tmp/unprocessable_mail/*.eml) again end end + # generate Message ID on the fly if it was missing + # yes, Mail gem generates one in some cases + # but it is 100% random so duplicate messages would not be detected + def message_ensure_message_id(raw, parsed) + field = parsed.header.fields.find { |elem| elem.name == 'Message-ID' } + + return true if field&.unparsed_value.present? + + parsed.message_id = generate_message_id(raw, parsed.from) + end + def message_header_hash(mail) imported_fields = mail.header.fields.map do |f| begin @@ -909,6 +922,18 @@ process unprocessable_mails (tmp/unprocessable_mail/*.eml) again 'In-Reply-To': parsed_incoming_mail[:message_id], ) end + + def guess_email_fqdn(from) + Mail::Address.new(from).domain.strip + rescue + nil + end + + def generate_message_id(raw_message, from) + fqdn = guess_email_fqdn(from) || 'zammad_generated' + + "" + end end module Mail diff --git a/test/data/mail/mail095.box b/test/data/mail/mail095.box new file mode 100644 index 000000000..f4ef1e588 --- /dev/null +++ b/test/data/mail/mail095.box @@ -0,0 +1,27 @@ +Return-Path: +Delivered-To: user@example.com +Received: from host.example.com + by host.example.com with LMTP id kFSRC5u/I1tJHBAAz53O+w + for ; Fri, 15 Jun 2018 09:31:07 -0400 +Return-path: +Envelope-to: user@example.com +Delivery-date: Fri, 15 Jun 2018 09:31:07 -0400 +Received: from mail-do1ram03ok0780.emails.users.example.com ([0.0.0.0]:15241 helo=do1ram03ok0780.emails.users.example.com) + by host.example.com with esmtps (TLSv1.2:ECDHE-RSA-AES256-SHA384:256) + (Exim 4.91) + (envelope-from ) + id 1dFool-1004vt-2z + for user@example.com; Fri, 15 Jun 2018 09:31:07 -0400 +From: "Name R. John" +To: To This Person +Subject: Subject of message +Thread-Topic: Subject of message +Thread-Index: AdQDSn2ZjObO2qLmRLWd8iIbgua/6gBYoT0g +Sender: "Name R. John" +Date: Fri, 15 Jun 2018 13:30:23 +0000 +Message-ID: + +Accept-Language: en-US +Content-Language: en-US + +Message text diff --git a/test/data/mail/mail095.yml b/test/data/mail/mail095.yml new file mode 100644 index 000000000..b05cadbd6 --- /dev/null +++ b/test/data/mail/mail095.yml @@ -0,0 +1,12 @@ +--- !ruby/hash:ActiveSupport::HashWithIndifferentAccess +from: '"Name R. John" ' +from_email: user.name@example.com +from_display_name: Name R. John +to: To This Person +subject: Subject of message +body: 'Message text + + ' +content_type: text/plain +attachments: [] +message_id: "" diff --git a/test/data/mail/mail096.box b/test/data/mail/mail096.box new file mode 100644 index 000000000..8c32e7f6e --- /dev/null +++ b/test/data/mail/mail096.box @@ -0,0 +1,26 @@ +Return-Path: +Delivered-To: user@example.com +Received: from host.example.com + by host.example.com with LMTP id kFSRC5u/I1tJHBAAz53O+w + for ; Fri, 15 Jun 2018 09:31:07 -0400 +Return-path: +Envelope-to: user@example.com +Delivery-date: Fri, 15 Jun 2018 09:31:07 -0400 +Received: from mail-do1ram03ok0780.emails.users.example.com ([0.0.0.0]:15241 helo=do1ram03ok0780.emails.users.example.com) + by host.example.com with esmtps (TLSv1.2:ECDHE-RSA-AES256-SHA384:256) + (Exim 4.91) + (envelope-from ) + id 1dFool-1004vt-2z + for user@example.com; Fri, 15 Jun 2018 09:31:07 -0400 +From: "Name R. John" +To: To This Person +Subject: Subject of message +Thread-Topic: Subject of message +Thread-Index: AdQDSn2ZjObO2qLmRLWd8iIbgua/6gBYoT0g +Sender: "Name R. John" +Date: Fri, 15 Jun 2018 13:30:23 +0000 +Message-ID: +Accept-Language: en-US +Content-Language: en-US + +Message text diff --git a/test/data/mail/mail096.yml b/test/data/mail/mail096.yml new file mode 100644 index 000000000..76efee540 --- /dev/null +++ b/test/data/mail/mail096.yml @@ -0,0 +1,12 @@ +--- !ruby/hash:ActiveSupport::HashWithIndifferentAccess +from: '"Name R. John" ' +from_email: user.name@example.com +from_display_name: Name R. John +to: To This Person +subject: Subject of message +body: 'Message text + + ' +content_type: text/plain +attachments: [] +message_id: "" diff --git a/test/data/mail/mail097.box b/test/data/mail/mail097.box new file mode 100644 index 000000000..c853cbda2 --- /dev/null +++ b/test/data/mail/mail097.box @@ -0,0 +1,25 @@ +Return-Path: +Delivered-To: user@example.com +Received: from host.example.com + by host.example.com with LMTP id kFSRC5u/I1tJHBAAz53O+w + for ; Fri, 15 Jun 2018 09:31:07 -0400 +Return-path: +Envelope-to: user@example.com +Delivery-date: Fri, 15 Jun 2018 09:31:07 -0400 +Received: from mail-do1ram03ok0780.emails.users.example.com ([0.0.0.0]:15241 helo=do1ram03ok0780.emails.users.example.com) + by host.example.com with esmtps (TLSv1.2:ECDHE-RSA-AES256-SHA384:256) + (Exim 4.91) + (envelope-from ) + id 1dFool-1004vt-2z + for user@example.com; Fri, 15 Jun 2018 09:31:07 -0400 +From: "Name R. John" +To: To This Person +Subject: Subject of message +Thread-Topic: Subject of message +Thread-Index: AdQDSn2ZjObO2qLmRLWd8iIbgua/6gBYoT0g +Sender: "Name R. John" +Date: Fri, 15 Jun 2018 13:30:23 +0000 +Accept-Language: en-US +Content-Language: en-US + +Message text diff --git a/test/data/mail/mail097.yml b/test/data/mail/mail097.yml new file mode 100644 index 000000000..33945384b --- /dev/null +++ b/test/data/mail/mail097.yml @@ -0,0 +1,12 @@ +--- !ruby/hash:ActiveSupport::HashWithIndifferentAccess +from: '"Name R. John" ' +from_email: user.name@example.com +from_display_name: Name R. John +to: To This Person +subject: Subject of message +body: 'Message text + + ' +content_type: text/plain +attachments: [] +message_id: ""