diff --git a/lib/email/receiver.rb b/lib/email/receiver.rb index 207e418d70e..7c76c44d613 100644 --- a/lib/email/receiver.rb +++ b/lib/email/receiver.rb @@ -3,7 +3,6 @@ require "digest" module Email - class Receiver # If you add a new error, you need to # * add it to Email::Processor#handle_failure() @@ -72,8 +71,7 @@ module Email # do not create a new `IncomingEmail` record to avoid double ups. return if @incoming_email = find_existing_and_update_imap - ensure_valid_address_lists - ensure_valid_date + Email::Validator.ensure_valid!(@mail) @from_email, @from_display_name = parse_from_field @from_user = User.find_by_email(@from_email) @@ -121,22 +119,6 @@ module Email incoming_email end - def ensure_valid_address_lists - [:to, :cc, :bcc].each do |field| - addresses = @mail[field] - - if addresses&.errors.present? - @mail[field] = addresses.to_s.scan(/\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}\b/i) - end - end - end - - def ensure_valid_date - if @mail.date.nil? - raise InvalidPost, I18n.t("system_messages.email_reject_invalid_post_specified.date_invalid") - end - end - def is_blocked? return false if SiteSetting.ignore_by_title.blank? Regexp.new(SiteSetting.ignore_by_title, Regexp::IGNORECASE) =~ @mail.subject @@ -915,7 +897,13 @@ module Email end def embedded_email - @embedded_email ||= embedded_email_raw.present? ? Mail.new(embedded_email_raw) : nil + @embedded_email ||= if embedded_email_raw.present? + mail = Mail.new(embedded_email_raw) + Email::Validator.ensure_valid_address_lists!(mail) + mail + else + nil + end end def process_forwarded_email(destination, user) diff --git a/lib/email/validator.rb b/lib/email/validator.rb new file mode 100644 index 00000000000..2795055a93e --- /dev/null +++ b/lib/email/validator.rb @@ -0,0 +1,28 @@ +# frozen_string_literal: true + +module Email + class Validator + def self.ensure_valid!(mail) + Email::Validator.ensure_valid_address_lists!(mail) + Email::Validator.ensure_valid_date!(mail) + + mail + end + + def self.ensure_valid_address_lists!(mail) + [:to, :cc, :bcc].each do |field| + addresses = mail[field] + + if addresses&.errors.present? + mail[field] = addresses.to_s.scan(/\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}\b/i) + end + end + end + + def self.ensure_valid_date!(mail) + if mail.date.nil? + raise Email::Receiver::InvalidPost, I18n.t("system_messages.email_reject_invalid_post_specified.date_invalid") + end + end + end +end diff --git a/spec/components/email/receiver_spec.rb b/spec/components/email/receiver_spec.rb index 0f73e889623..a7bbd40650a 100644 --- a/spec/components/email/receiver_spec.rb +++ b/spec/components/email/receiver_spec.rb @@ -2024,4 +2024,12 @@ describe Email::Receiver do expect { receive(email_3) }.to change { Topic.count }.by(0).and change { Post.where(post_type: Post.types[:regular]).count }.by(1) end end + + it 'fixes valid addresses in embedded emails' do + Fabricate(:group, incoming_email: "group-fwd@example.com") + process(:long_embedded_email_headers) + incoming_email = IncomingEmail.find_by(message_id: "example1@mail.gmail.com") + expect(incoming_email.cc_addresses).to include("a@example.com") + expect(incoming_email.cc_addresses).to include("c@example.com") + end end diff --git a/spec/fixtures/emails/long_embedded_email_headers.eml b/spec/fixtures/emails/long_embedded_email_headers.eml new file mode 100644 index 00000000000..0442698e92c --- /dev/null +++ b/spec/fixtures/emails/long_embedded_email_headers.eml @@ -0,0 +1,21 @@ +MIME-Version: 1.0 +Date: Sat, 2 Oct 2021 21:52:36 -0400 +Message-ID: +Subject: Fwd: Test Email +From: Example Group +To: group-fwd@example.com +Cc: C , D + + +---------- Forwarded message --------- +Date: Sat, 2 Oct 2021 21:52:36 -0400 +Message-ID: +Subject: Test Email +From: User +To: Example Group +Cc: A , B < +b@example.com> + + +Hello world!