FIX: Conform EmailLog#bounce_error_code to RFC (#16010)
This commit makes sure that the email log's bounce_error_code conforms to the SMTP error code RFC on save, so that it is always in the format X.X.X or XXX without any additional string details. Also included is a migration to fix this issue for past records.
This commit is contained in:
parent
189df5ef43
commit
01ef1d08fc
|
@ -14,6 +14,9 @@ class EmailLog < ActiveRecord::Base
|
|||
signup_after_approval
|
||||
}
|
||||
|
||||
# cf. https://www.iana.org/assignments/smtp-enhanced-status-codes/smtp-enhanced-status-codes.xhtml
|
||||
SMTP_ERROR_CODE_REGEXP = Regexp.new(/\d\.\d\.\d|\d\d\d/).freeze
|
||||
|
||||
belongs_to :user
|
||||
belongs_to :post
|
||||
belongs_to :smtp_group, class_name: 'Group'
|
||||
|
@ -34,6 +37,13 @@ class EmailLog < ActiveRecord::Base
|
|||
SQL
|
||||
end
|
||||
|
||||
before_save do
|
||||
if self.bounce_error_code.present?
|
||||
match = SMTP_ERROR_CODE_REGEXP.match(self.bounce_error_code)
|
||||
self.bounce_error_code = match.present? ? match[0] : nil
|
||||
end
|
||||
end
|
||||
|
||||
after_create do
|
||||
# Update last_emailed_at if the user_id is present and email was sent
|
||||
User.where(id: user_id).update_all("last_emailed_at = CURRENT_TIMESTAMP") if user_id.present?
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
# frozen_string_literal: true
|
||||
#
|
||||
class ConformBounceErrorCode < ActiveRecord::Migration[6.1]
|
||||
def up
|
||||
DB.exec(<<~SQL, regexp: '\d\.\d\.\d|\d\d\d')
|
||||
UPDATE email_logs
|
||||
SET bounce_error_code = (
|
||||
SELECT array_to_string(
|
||||
regexp_matches(bounce_error_code, :regexp),
|
||||
''
|
||||
)
|
||||
) WHERE bounce_error_code IS NOT NULL;
|
||||
SQL
|
||||
end
|
||||
|
||||
def down
|
||||
raise ActiveRecord::IrreversibleMigration
|
||||
end
|
||||
end
|
|
@ -161,4 +161,21 @@ describe EmailLog do
|
|||
expect(EmailLog.addressed_to_user(user).count).to eq(0)
|
||||
end
|
||||
end
|
||||
|
||||
describe "bounce_error_code fix before update" do
|
||||
fab!(:email_log) { Fabricate(:email_log) }
|
||||
|
||||
it "makes sure the bounce_error_code is in the format X.X.X or XXX" do
|
||||
email_log.update!(bounce_error_code: "5.1.1")
|
||||
expect(email_log.reload.bounce_error_code).to eq("5.1.1")
|
||||
email_log.update!(bounce_error_code: "5.0.0 (permanent failure)")
|
||||
expect(email_log.reload.bounce_error_code).to eq("5.0.0")
|
||||
email_log.update!(bounce_error_code: "422")
|
||||
expect(email_log.reload.bounce_error_code).to eq("422")
|
||||
email_log.update!(bounce_error_code: "5.2")
|
||||
expect(email_log.reload.bounce_error_code).to eq(nil)
|
||||
email_log.update!(bounce_error_code: "blah")
|
||||
expect(email_log.reload.bounce_error_code).to eq(nil)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue