FIX: Correct the forwarded by user small post for group inbox (#14252)

When 2ac9fd9dff5a2a9210e2b1b765e1a324bbb4f421 was done, this
affected the small post that is created when forwarding an email
into the group inbox. Instead of using the name and the email of
the user who forwarded the email, it used the original from email
and name to create the small post. So instead of something like
"Discourse Team forwarded the above email" we ended up with
"John Smith forwarded the above email" which is incorrect.

This fixes the issue by creating a staged user for the forwarding
email address (if such a user does not yet exist) and uses that
for the "forwarded" small post instead.
This commit is contained in:
Martin Brennan
2021-09-06 15:02:13 +10:00
committed by GitHub
parent 1937474e84
commit 7b392cee50
3 changed files with 94 additions and 24 deletions

View File

@ -589,12 +589,8 @@ module Email
# which we can extract from embedded_email_raw.
if has_been_forwarded?
if mail[:from].to_s =~ group_incoming_emails_regex && embedded_email[:from].errors.blank?
embedded_email[:from].each do |address_field|
from_address = address_field.address
from_display_name = address_field.display_name&.to_s
next if !from_address&.include?("@")
return [from_address&.downcase, from_display_name&.strip]
end
from_address, from_display_name = extract_from_fields_from_header(embedded_email, :from)
return [from_address, from_display_name] if from_address
end
end
@ -604,23 +600,16 @@ module Email
# header in more cases.
if mail['X-Original-From'].present?
if mail[:reply_to] && mail[:reply_to].errors.blank?
mail[:reply_to].each do |address_field|
from_address = address_field.address
from_display_name = address_field.display_name&.to_s
next if address_field.to_s != mail['X-Original-From'].to_s
next if !from_address&.include?("@")
return [from_address&.downcase, from_display_name&.strip]
end
from_address, from_display_name = extract_from_fields_from_header(
mail, :reply_to, comparison_headers: ['X-Original-From']
)
return [from_address, from_display_name] if from_address
end
end
if mail[:from].errors.blank?
mail[:from].each do |address_field|
from_address = address_field.address
from_display_name = address_field.display_name&.to_s
next if !from_address&.include?("@")
return [from_address&.downcase, from_display_name&.strip]
end
from_address, from_display_name = extract_from_fields_from_header(mail, :from)
return [from_address, from_display_name] if from_address
end
return extract_from_address_and_name(mail.from) if mail.from.is_a? String
@ -637,6 +626,24 @@ module Email
nil
end
def extract_from_fields_from_header(mail_object, header, comparison_headers: [])
mail_object[header].each do |address_field|
from_address = address_field.address
from_display_name = address_field.display_name&.to_s
comparison_failed = false
comparison_headers.each do |comparison_header|
comparison_failed = true if address_field.to_s != mail_object[comparison_header].to_s
end
next if comparison_failed
next if !from_address&.include?("@")
return [from_address&.downcase, from_display_name&.strip]
end
[nil, nil]
end
def extract_from_address_and_name(value)
if value[";"]
from_display_name, from_address = value.split(";")
@ -948,6 +955,10 @@ module Email
embedded = Mail.new(embedded_email_raw)
email, display_name = parse_from_field(embedded)
if forwarded_by_address && forwarded_by_name
forwarded_by_user = stage_sender_user(forwarded_by_address, forwarded_by_name)
end
return false if email.blank? || !email["@"]
post = forwarded_email_create_topic(destination: destination,
@ -974,13 +985,28 @@ module Email
post_type: post_type,
skip_validations: user.staged?)
else
post.topic.add_small_action(user, "forwarded")
if forwarded_by_user
post.topic.topic_allowed_users.find_or_create_by!(user_id: forwarded_by_user.id)
end
post.topic.add_small_action(forwarded_by_user || user, "forwarded")
end
end
true
end
def forwarded_by_sender
@forwarded_by_sender ||= extract_from_fields_from_header(@mail, :from)
end
def forwarded_by_address
@forwarded_by_address ||= forwarded_by_sender&.first
end
def forwarded_by_name
@forwarded_by_name ||= forwarded_by_sender&.first
end
def forwarded_email_quote_forwarded(destination, user)
embedded = embedded_email_raw
raw = <<~EOF
@ -1367,7 +1393,11 @@ module Email
end
def stage_from_user
@from_user ||= find_or_create_user!(@from_email, @from_display_name).tap do |u|
@from_user ||= stage_sender_user(@from_email, @from_display_name)
end
def stage_sender_user(email, display_name)
find_or_create_user!(email, display_name).tap do |u|
log_and_validate_user(u)
end
end