FEATURE: new 'enable_forwarded_email' site setting
This commit is contained in:
parent
ece5442c54
commit
17f2be9f88
2
Gemfile
2
Gemfile
|
@ -66,7 +66,7 @@ gem 'aws-sdk', require: false
|
|||
gem 'excon', require: false
|
||||
gem 'unf', require: false
|
||||
|
||||
gem 'email_reply_trimmer', '0.1.4'
|
||||
gem 'email_reply_trimmer', '0.1.5'
|
||||
|
||||
# note: for image_optim to correctly work you need to follow
|
||||
# https://github.com/toy/image_optim
|
||||
|
|
|
@ -80,7 +80,7 @@ GEM
|
|||
docile (1.1.5)
|
||||
domain_name (0.5.25)
|
||||
unf (>= 0.0.5, < 1.0.0)
|
||||
email_reply_trimmer (0.1.4)
|
||||
email_reply_trimmer (0.1.5)
|
||||
ember-data-source (1.0.0.beta.16.1)
|
||||
ember-source (~> 1.8)
|
||||
ember-handlebars-template (0.7.3)
|
||||
|
@ -411,7 +411,7 @@ DEPENDENCIES
|
|||
certified
|
||||
discourse-qunit-rails
|
||||
discourse_fastimage (= 2.0.3)
|
||||
email_reply_trimmer (= 0.1.4)
|
||||
email_reply_trimmer (= 0.1.5)
|
||||
ember-rails (= 0.18.5)
|
||||
ember-source (= 1.12.2)
|
||||
excon
|
||||
|
|
|
@ -1246,6 +1246,8 @@ en:
|
|||
attachment_content_type_blacklist: "List of keywords used to blacklist attachments based on the content type."
|
||||
attachment_filename_blacklist: "List of keywords used to blacklist attachments based on the filename."
|
||||
|
||||
enable_forwarded_emails: "[BETA] Allow users to create a topic by forwarding an email in."
|
||||
|
||||
manual_polling_enabled: "Push emails using the API for email replies."
|
||||
pop3_polling_enabled: "Poll via POP3 for email replies."
|
||||
pop3_polling_ssl: "Use SSL while connecting to the POP3 server. (Recommended)"
|
||||
|
|
|
@ -670,7 +670,7 @@ email:
|
|||
attachment_filename_blacklist:
|
||||
type: list
|
||||
default: "smime.p7s|signature.asc"
|
||||
|
||||
enable_forwarded_emails: false
|
||||
|
||||
files:
|
||||
max_image_size_kb:
|
||||
|
|
|
@ -38,7 +38,7 @@ module Email
|
|||
|
||||
def process!
|
||||
return if is_blacklisted?
|
||||
@from_email, @from_display_name = parse_from_field
|
||||
@from_email, @from_display_name = parse_from_field(@mail)
|
||||
@incoming_email = find_or_create_incoming_email
|
||||
process_internal
|
||||
rescue => e
|
||||
|
@ -74,7 +74,7 @@ module Email
|
|||
raise InactiveUserError if !user.active && !user.staged
|
||||
raise BlockedUserError if user.blocked
|
||||
|
||||
body, @elided = select_body
|
||||
body, elided = select_body
|
||||
body ||= ""
|
||||
|
||||
raise NoBodyDetectedError if body.blank? && attachments.empty?
|
||||
|
@ -90,6 +90,7 @@ module Email
|
|||
elsif post = find_related_post
|
||||
create_reply(user: user,
|
||||
raw: body,
|
||||
elided: elided,
|
||||
post: post,
|
||||
topic: post.topic,
|
||||
skip_validations: user.staged?)
|
||||
|
@ -98,7 +99,7 @@ module Email
|
|||
|
||||
destinations.each do |destination|
|
||||
begin
|
||||
process_destination(destination, user, body)
|
||||
process_destination(destination, user, body, elided)
|
||||
rescue => e
|
||||
first_exception ||= e
|
||||
else
|
||||
|
@ -237,16 +238,19 @@ module Email
|
|||
reply.split(previous_replies_regex)[0]
|
||||
end
|
||||
|
||||
def parse_from_field
|
||||
if @mail[:from].errors.blank?
|
||||
address_field = @mail[:from].address_list.addresses.first
|
||||
def parse_from_field(mail)
|
||||
if mail[:from].errors.blank?
|
||||
mail[:from].address_list.addresses.each do |address_field|
|
||||
address_field.decoded
|
||||
from_address = address_field.address
|
||||
from_display_name = address_field.display_name.try(:to_s)
|
||||
else
|
||||
from_address = @mail.from[/<([^>]+)>/, 1]
|
||||
from_display_name = @mail.from[/^([^<]+)/, 1]
|
||||
return [from_address.downcase, from_display_name] if from_address["@"]
|
||||
end
|
||||
end
|
||||
|
||||
from_address = mail.from[/<([^>]+)>/, 1]
|
||||
from_display_name = mail.from[/^([^<]+)/, 1]
|
||||
|
||||
[from_address.downcase, from_display_name]
|
||||
end
|
||||
|
||||
|
@ -314,12 +318,17 @@ module Email
|
|||
end
|
||||
end
|
||||
|
||||
def process_destination(destination, user, body)
|
||||
def process_destination(destination, user, body, elided)
|
||||
return if SiteSetting.enable_forwarded_emails &&
|
||||
has_been_forwarded? &&
|
||||
process_forwarded_email(destination, user)
|
||||
|
||||
case destination[:type]
|
||||
when :group
|
||||
group = destination[:obj]
|
||||
create_topic(user: user,
|
||||
raw: body,
|
||||
elided: elided,
|
||||
title: subject,
|
||||
archetype: Archetype.private_message,
|
||||
target_group_names: [group.name],
|
||||
|
@ -347,11 +356,69 @@ module Email
|
|||
|
||||
create_reply(user: user,
|
||||
raw: body,
|
||||
elided: elided,
|
||||
post: email_log.post,
|
||||
topic: email_log.post.topic)
|
||||
end
|
||||
end
|
||||
|
||||
def has_been_forwarded?
|
||||
subject[/^[[:blank]]*(re|fwd?)[[:blank]]?:/i] && embedded_email_raw.present?
|
||||
end
|
||||
|
||||
def embedded_email_raw
|
||||
return @embedded_email_raw if @embedded_email_raw
|
||||
text = fix_charset(@mail.multipart? ? @mail.text_part : @mail)
|
||||
@embedded_email_raw, @before_embedded = EmailReplyTrimmer.extract_embedded_email(text)
|
||||
@embedded_email_raw
|
||||
end
|
||||
|
||||
def process_forwarded_email(destination, user)
|
||||
embedded = Mail.new(@embedded_email_raw)
|
||||
email, display_name = parse_from_field(embedded)
|
||||
embedded_user = find_or_create_user(email, display_name)
|
||||
raw = embedded.decoded
|
||||
title = embedded.subject.presence || subject
|
||||
|
||||
case destination[:type]
|
||||
when :group
|
||||
group = destination[:obj]
|
||||
post = create_topic(user: embedded_user,
|
||||
raw: raw,
|
||||
title: title,
|
||||
archetype: Archetype.private_message,
|
||||
target_group_names: [group.name],
|
||||
is_group_message: true,
|
||||
skip_validations: true,
|
||||
created_at: embedded.date)
|
||||
|
||||
when :category
|
||||
category = destination[:obj]
|
||||
|
||||
return false if user.staged? && !category.email_in_allow_strangers
|
||||
return false if !user.has_trust_level?(SiteSetting.email_in_min_trust)
|
||||
|
||||
post = create_topic(user: embedded_user,
|
||||
raw: raw,
|
||||
title: title,
|
||||
category: category.id,
|
||||
skip_validations: embedded_user.staged?,
|
||||
created_at: embedded.date)
|
||||
else
|
||||
return false
|
||||
end
|
||||
|
||||
if post && post.topic && @before_embedded.present?
|
||||
create_reply(user: user,
|
||||
raw: @before_embedded,
|
||||
post: post,
|
||||
topic: post.topic,
|
||||
post_type: Post.types[:whisper])
|
||||
end
|
||||
|
||||
true
|
||||
end
|
||||
|
||||
def reply_by_email_address_regex
|
||||
@reply_by_email_address_regex ||= begin
|
||||
reply_addresses = [
|
||||
|
@ -483,16 +550,17 @@ module Email
|
|||
options[:raw_email] = @raw_email
|
||||
|
||||
# ensure posts aren't created in the future
|
||||
options[:created_at] = [@mail.date, DateTime.now].min
|
||||
options[:created_at] ||= @mail.date
|
||||
options[:created_at] = DateTime.now if options[:created_at] > DateTime.now
|
||||
|
||||
is_private_message = options[:archetype] == Archetype.private_message ||
|
||||
options[:topic].try(:private_message?)
|
||||
|
||||
# only add elided part in messages
|
||||
if @elided.present? && is_private_message
|
||||
if options[:elided].present? && is_private_message
|
||||
options[:raw] << "\n\n" << "<details class='elided'>" << "\n"
|
||||
options[:raw] << "<summary title='#{I18n.t('emails.incoming.show_trimmed_content')}'>···</summary>" << "\n"
|
||||
options[:raw] << @elided << "\n"
|
||||
options[:raw] << options[:elided] << "\n"
|
||||
options[:raw] << "</details>" << "\n"
|
||||
end
|
||||
|
||||
|
@ -508,6 +576,8 @@ module Email
|
|||
add_other_addresses(result.post.topic, user)
|
||||
end
|
||||
end
|
||||
|
||||
result.post
|
||||
end
|
||||
|
||||
def add_other_addresses(topic, sender)
|
||||
|
@ -518,6 +588,7 @@ module Email
|
|||
address_field.decoded
|
||||
email = address_field.address.downcase
|
||||
display_name = address_field.display_name.try(:to_s)
|
||||
next unless email["@"]
|
||||
if should_invite?(email)
|
||||
user = find_or_create_user(email, display_name)
|
||||
if user && can_invite?(topic, user)
|
||||
|
|
Loading…
Reference in New Issue