mirror of
https://github.com/discourse/discourse.git
synced 2024-11-22 20:36:39 +08:00
FIX: Parse address lists in embedded emails (#14514)
Same fix is applied to emails immediately after being parsed because long headers are sometimes in an invalid format.
This commit is contained in:
parent
20e70d0ac5
commit
f58ab2283d
|
@ -3,7 +3,6 @@
|
||||||
require "digest"
|
require "digest"
|
||||||
|
|
||||||
module Email
|
module Email
|
||||||
|
|
||||||
class Receiver
|
class Receiver
|
||||||
# If you add a new error, you need to
|
# If you add a new error, you need to
|
||||||
# * add it to Email::Processor#handle_failure()
|
# * add it to Email::Processor#handle_failure()
|
||||||
|
@ -72,8 +71,7 @@ module Email
|
||||||
# do not create a new `IncomingEmail` record to avoid double ups.
|
# do not create a new `IncomingEmail` record to avoid double ups.
|
||||||
return if @incoming_email = find_existing_and_update_imap
|
return if @incoming_email = find_existing_and_update_imap
|
||||||
|
|
||||||
ensure_valid_address_lists
|
Email::Validator.ensure_valid!(@mail)
|
||||||
ensure_valid_date
|
|
||||||
|
|
||||||
@from_email, @from_display_name = parse_from_field
|
@from_email, @from_display_name = parse_from_field
|
||||||
@from_user = User.find_by_email(@from_email)
|
@from_user = User.find_by_email(@from_email)
|
||||||
|
@ -121,22 +119,6 @@ module Email
|
||||||
incoming_email
|
incoming_email
|
||||||
end
|
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?
|
def is_blocked?
|
||||||
return false if SiteSetting.ignore_by_title.blank?
|
return false if SiteSetting.ignore_by_title.blank?
|
||||||
Regexp.new(SiteSetting.ignore_by_title, Regexp::IGNORECASE) =~ @mail.subject
|
Regexp.new(SiteSetting.ignore_by_title, Regexp::IGNORECASE) =~ @mail.subject
|
||||||
|
@ -915,7 +897,13 @@ module Email
|
||||||
end
|
end
|
||||||
|
|
||||||
def embedded_email
|
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
|
end
|
||||||
|
|
||||||
def process_forwarded_email(destination, user)
|
def process_forwarded_email(destination, user)
|
||||||
|
|
28
lib/email/validator.rb
Normal file
28
lib/email/validator.rb
Normal file
|
@ -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
|
|
@ -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)
|
expect { receive(email_3) }.to change { Topic.count }.by(0).and change { Post.where(post_type: Post.types[:regular]).count }.by(1)
|
||||||
end
|
end
|
||||||
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
|
end
|
||||||
|
|
21
spec/fixtures/emails/long_embedded_email_headers.eml
vendored
Normal file
21
spec/fixtures/emails/long_embedded_email_headers.eml
vendored
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
MIME-Version: 1.0
|
||||||
|
Date: Sat, 2 Oct 2021 21:52:36 -0400
|
||||||
|
Message-ID: <example1@mail.gmail.com>
|
||||||
|
Subject: Fwd: Test Email
|
||||||
|
From: Example Group <group@example.com>
|
||||||
|
To: group-fwd@example.com
|
||||||
|
Cc: C <c@example.com>, D <d@
|
||||||
|
example.com>
|
||||||
|
|
||||||
|
|
||||||
|
---------- Forwarded message ---------
|
||||||
|
Date: Sat, 2 Oct 2021 21:52:36 -0400
|
||||||
|
Message-ID: <example2@mail.gmail.com>
|
||||||
|
Subject: Test Email
|
||||||
|
From: User <user@example.com>
|
||||||
|
To: Example Group <group@example.com>
|
||||||
|
Cc: A <a@example.com>, B <
|
||||||
|
b@example.com>
|
||||||
|
|
||||||
|
|
||||||
|
Hello world!
|
Loading…
Reference in New Issue
Block a user