FEATURE: clearer error message when receiving a reply to an old notification

This commit is contained in:
Régis Hanol 2018-05-09 18:51:01 +02:00
parent deaf3682e9
commit 86eb3528ec
5 changed files with 45 additions and 5 deletions

View File

@ -2438,6 +2438,14 @@ en:
None of the destination email addresses are recognized, or the Message-ID header in the email has been modified. Please make sure that you are sending to the correct email address provided by staff.
email_reject_old_destination:
title: "Email Reject Old Destination"
subject_template: "[%{email_prefix}] Email issue -- You are trying to reply to an old notification"
text_body_template: |
We're sorry, but your email message to %{destination} (titled %{former_title}) didn't work.
For security reasons we only accept replies to original notifications for 90 days. Please [visit the topic](%{short_url}) to continue the conversation.
email_reject_topic_not_found:
title: "Email Reject Topic Not Found"
subject_template: "[%{email_prefix}] Email issue -- Topic Not Found"

View File

@ -55,6 +55,7 @@ module Email
when ActiveRecord::Rollback then :email_reject_invalid_post
when Email::Receiver::InvalidPostAction then :email_reject_invalid_post_action
when Discourse::InvalidAccess then :email_reject_invalid_access
when Email::Receiver::OldDestinationError then :email_reject_old_destination
else :email_reject_unrecognized_error
end
@ -75,6 +76,10 @@ module Email
Rails.logger.error(msg)
end
if message_template == :email_reject_old_destination
template_args[:short_url] = e.message
end
if message_template
# inform the user about the rejection
message = Mail::Message.new(mail_string)

View File

@ -33,6 +33,7 @@ module Email
class InvalidPostAction < ProcessingError; end
class UnsubscribeNotAllowed < ProcessingError; end
class EmailNotAllowed < ProcessingError; end
class OldDestinationError < ProcessingError; end
attr_reader :incoming_email
attr_reader :raw_email
@ -42,8 +43,7 @@ module Email
COMMON_ENCODINGS ||= [-"utf-8", -"windows-1252", -"iso-8859-1"]
def self.formats
@formats ||= Enum.new(plaintext: 1,
markdown: 2)
@formats ||= Enum.new(plaintext: 1, markdown: 2)
end
def initialize(mail_string, opts = {})
@ -163,7 +163,15 @@ module Email
end
end
raise first_exception || BadDestinationAddress
raise first_exception if first_exception
if post = find_related_post(force: true)
if Guardian.new(user).can_see_post?(post) && post.created_at < 90.days.ago
raise OldDestinationError.new("#{Discourse.base_url}/p/#{post.id}")
end
end
raise BadDestinationAddress
end
end
@ -728,8 +736,8 @@ module Email
@category_email_in_regex ||= Regexp.union Category.pluck(:email_in).select(&:present?).map { |e| e.split("|") }.flatten.uniq
end
def find_related_post
return if SiteSetting.find_related_post_with_key && !sent_to_mailinglist_mirror?
def find_related_post(force: false)
return if !force && SiteSetting.find_related_post_with_key && !sent_to_mailinglist_mirror?
message_ids = Email::Receiver.extract_reply_message_ids(@mail, max_message_id_count: 5)
return if message_ids.empty?

View File

@ -78,6 +78,13 @@ describe Email::Receiver do
expect { process(:bad_destinations) }.to raise_error(Email::Receiver::BadDestinationAddress)
end
it "raises an OldDestinationError when notification is too old" do
topic = Fabricate(:topic, id: 424242)
post = Fabricate(:post, topic: topic, id: 123456, created_at: 1.year.ago)
expect { process(:old_destination) }.to raise_error(Email::Receiver::OldDestinationError)
end
it "raises a BouncerEmailError when email is a bounced email" do
expect { process(:bounced_email) }.to raise_error(Email::Receiver::BouncedEmailError)
expect(IncomingEmail.last.is_bounce).to eq(true)

View File

@ -0,0 +1,12 @@
Return-Path: <staged@bar.com>
From: Foo Bar <staged@bar.com>
To: wat@bar.com
Cc: foofoo@bar.com
Date: Fri, 15 Jan 2018 00:12:43 +0100
Message-ID: <999@foo.bar.mail>
In-Reply-To: <topic/424242/123456@test.localhost>
Mime-Version: 1.0
Content-Type: text/plain
Content-Transfer-Encoding: 7bit
Lorem ipsum dolor sit amet, consectetur adipiscing elit.