mirror of
https://github.com/discourse/discourse.git
synced 2025-05-30 00:48:05 +08:00
FEATURE: If PM email bounced for staged user then alert in whisper reply (#6648)
This commit is contained in:
@ -70,8 +70,10 @@ module Email
|
||||
return if IncomingEmail.exists?(message_id: @message_id)
|
||||
ensure_valid_address_lists
|
||||
@from_email, @from_display_name = parse_from_field(@mail)
|
||||
@from_user = User.find_by_email(@from_email)
|
||||
@incoming_email = create_incoming_email
|
||||
process_internal
|
||||
raise BouncedEmailError if is_bounce?
|
||||
rescue => e
|
||||
error = e.to_s
|
||||
error = e.class.name if error.blank?
|
||||
@ -109,14 +111,14 @@ module Email
|
||||
end
|
||||
|
||||
def process_internal
|
||||
raise BouncedEmailError if is_bounce?
|
||||
handle_bounce if is_bounce?
|
||||
raise NoSenderDetectedError if @from_email.blank?
|
||||
raise FromReplyByAddressError if is_from_reply_by_email_address?
|
||||
raise ScreenedEmailError if ScreenedEmail.should_block?(@from_email)
|
||||
|
||||
hidden_reason_id = is_spam? ? Post.hidden_reasons[:email_spam_header_found] : nil
|
||||
|
||||
user = find_user(@from_email)
|
||||
user = @from_user
|
||||
|
||||
if user.present?
|
||||
log_and_validate_user(user)
|
||||
@ -132,7 +134,7 @@ module Email
|
||||
if is_auto_generated? && !sent_to_mailinglist_mirror?
|
||||
@incoming_email.update_columns(is_auto_generated: true)
|
||||
|
||||
if SiteSetting.block_auto_generated_emails?
|
||||
if SiteSetting.block_auto_generated_emails? && !is_bounce?
|
||||
raise AutoGeneratedEmailError
|
||||
end
|
||||
end
|
||||
@ -157,17 +159,16 @@ module Email
|
||||
hidden_reason_id: hidden_reason_id,
|
||||
post: post,
|
||||
topic: post.topic,
|
||||
skip_validations: user.staged?)
|
||||
skip_validations: user.staged?,
|
||||
bounce: is_bounce?)
|
||||
else
|
||||
first_exception = nil
|
||||
|
||||
destinations.each do |destination|
|
||||
begin
|
||||
process_destination(destination, user, body, elided, hidden_reason_id)
|
||||
return process_destination(destination, user, body, elided, hidden_reason_id)
|
||||
rescue => e
|
||||
first_exception ||= e
|
||||
else
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
@ -195,16 +196,21 @@ module Email
|
||||
end
|
||||
|
||||
def is_bounce?
|
||||
return false unless @mail.bounced? || verp
|
||||
@mail.bounced? || verp
|
||||
end
|
||||
|
||||
def handle_bounce
|
||||
@incoming_email.update_columns(is_bounce: true)
|
||||
|
||||
if verp && (bounce_key = verp[/\+verp-(\h{32})@/, 1]) && (email_log = EmailLog.find_by(bounce_key: bounce_key))
|
||||
email_log.update_columns(bounced: true)
|
||||
email = email_log.user.try(:email).presence
|
||||
user = email_log.user
|
||||
email = user&.email.presence
|
||||
topic = email_log.topic
|
||||
end
|
||||
|
||||
email ||= @from_email
|
||||
user ||= @from_user
|
||||
|
||||
if @mail.error_status.present? && Array.wrap(@mail.error_status).any? { |s| s.start_with?("4.") }
|
||||
Email::Receiver.update_bounce_score(email, SiteSetting.soft_bounce_score)
|
||||
@ -212,7 +218,11 @@ module Email
|
||||
Email::Receiver.update_bounce_score(email, SiteSetting.hard_bounce_score)
|
||||
end
|
||||
|
||||
true
|
||||
return if SiteSetting.enable_whispers? &&
|
||||
user&.staged? &&
|
||||
(topic.blank? || topic.archetype == Archetype.private_message)
|
||||
|
||||
raise BouncedEmailError
|
||||
end
|
||||
|
||||
def is_from_reply_by_email_address?
|
||||
@ -444,6 +454,12 @@ module Email
|
||||
end
|
||||
|
||||
def parse_from_field(mail)
|
||||
if is_bounce?
|
||||
Array.wrap(mail.final_recipient).each do |from|
|
||||
return extract_from_address_and_name(from)
|
||||
end
|
||||
end
|
||||
|
||||
return unless mail[:from]
|
||||
|
||||
if mail[:from].errors.blank?
|
||||
@ -470,6 +486,11 @@ module Email
|
||||
end
|
||||
|
||||
def extract_from_address_and_name(value)
|
||||
if value[";"]
|
||||
from_display_name, from_address = value.split(";")
|
||||
return [from_address&.strip&.downcase, from_display_name&.strip]
|
||||
end
|
||||
|
||||
if value[/<[^>]+>/]
|
||||
from_address = value[/<([^>]+)>/, 1]
|
||||
from_display_name = value[/^([^<]+)/, 1]
|
||||
@ -492,10 +513,6 @@ module Email
|
||||
end
|
||||
end
|
||||
|
||||
def find_user(email)
|
||||
User.find_by_email(email)
|
||||
end
|
||||
|
||||
def find_or_create_user(email, display_name, raise_on_failed_create: false)
|
||||
user = nil
|
||||
|
||||
@ -582,6 +599,8 @@ module Email
|
||||
has_been_forwarded? &&
|
||||
process_forwarded_email(destination, user)
|
||||
|
||||
return if is_bounce? && destination[:type] != :reply
|
||||
|
||||
case destination[:type]
|
||||
when :group
|
||||
group = destination[:obj]
|
||||
@ -616,7 +635,8 @@ module Email
|
||||
hidden_reason_id: hidden_reason_id,
|
||||
post: post,
|
||||
topic: post&.topic,
|
||||
skip_validations: user.staged?)
|
||||
skip_validations: user.staged?,
|
||||
bounce: is_bounce?)
|
||||
end
|
||||
end
|
||||
|
||||
@ -852,6 +872,8 @@ module Email
|
||||
|
||||
def create_reply(options = {})
|
||||
raise TopicNotFoundError if options[:topic].nil? || options[:topic].trashed?
|
||||
raise BouncedEmailError if options[:bounce] && options[:topic].archetype != Archetype.private_message
|
||||
|
||||
options[:post] = nil if options[:post]&.trashed?
|
||||
enable_email_pm_setting(options[:user]) if options[:topic].archetype == Archetype.private_message
|
||||
|
||||
@ -985,6 +1007,13 @@ module Email
|
||||
end
|
||||
|
||||
user = options.delete(:user)
|
||||
|
||||
if options[:bounce]
|
||||
options[:raw] = I18n.t("system_messages.email_bounced", email: user.email, raw: options[:raw])
|
||||
user = Discourse.system_user
|
||||
options[:post_type] = Post.types[:whisper]
|
||||
end
|
||||
|
||||
result = NewPostManager.new(user, options).perform
|
||||
|
||||
errors = result.errors.full_messages
|
||||
|
Reference in New Issue
Block a user