From ffc621596a1b2a67f60dec4d204b0de28c0cba9c Mon Sep 17 00:00:00 2001 From: Son Date: Wed, 5 Jan 2022 15:21:54 +0100 Subject: [PATCH] fix is_automatic_out_of_office: only use "Auto-Submitted" header --- app/email/headers.py | 7 ++++--- app/email/status.py | 2 +- app/models.py | 1 + email_handler.py | 18 +++++++++++------- tests/test_email_handler.py | 6 +++--- 5 files changed, 20 insertions(+), 14 deletions(-) diff --git a/app/email/headers.py b/app/email/headers.py index bb13d3d3..3b5be9e8 100644 --- a/app/email/headers.py +++ b/app/email/headers.py @@ -43,6 +43,7 @@ MIME_HEADERS = [ # convert to lowercase to facilitate header look up MIME_HEADERS = [h.lower() for h in MIME_HEADERS] -# if any of these headers are present, that means automatic out of office email -AUTO_REPLY1 = "X-Autoreply" -AUTO_REPLY2 = "Auto-Submitted" + +# according to https://datatracker.ietf.org/doc/html/rfc3834#section-3.1.7, this header should be set to "auto-replied" +# however on hotmail, this is set to "auto-generated" +AUTO_SUBMITTED = "Auto-Submitted" diff --git a/app/email/status.py b/app/email/status.py index d2c461b8..a86cb972 100644 --- a/app/email/status.py +++ b/app/email/status.py @@ -5,7 +5,7 @@ E202 = "250 Unsubscribe request accepted" E203 = "250 SL E203 email can't be sent from a reverse-alias" E204 = "250 SL E204 ignore" E205 = "250 SL E205 bounce handled" -# out of office status +# out-of-office status E206 = "250 SL E206 Out of office" # if mail_from is a IgnoreBounceSender, no need to send back a bounce report diff --git a/app/models.py b/app/models.py index 2f6288e1..0812b91b 100644 --- a/app/models.py +++ b/app/models.py @@ -1666,6 +1666,7 @@ class EmailLog(Base, ModelMixin): forward = orm.relationship(Contact) contact = orm.relationship(Contact, backref="email_logs") + alias = orm.relationship(Alias) mailbox = orm.relationship("Mailbox", lazy="joined", foreign_keys=[mailbox_id]) user = orm.relationship(User) diff --git a/email_handler.py b/email_handler.py index 80a04e6b..4b424128 100644 --- a/email_handler.py +++ b/email_handler.py @@ -1752,15 +1752,19 @@ def handle_spam( def is_automatic_out_of_office(msg: Message) -> bool: - if msg[headers.AUTO_REPLY1] is not None: - LOG.d( - "out-of-office email %s:%s", headers.AUTO_REPLY1, msg[headers.AUTO_REPLY1] - ) - return True + """ + Return whether an email is out-of-office + For info, out-of-office is sent to the envelope mail_from and not the From: header + More info on https://datatracker.ietf.org/doc/html/rfc3834#section-4 and https://support.google.com/mail/thread/21246740/my-auto-reply-filter-isn-t-replying-to-original-sender-address?hl=en&msgid=21261237 + """ + if msg[headers.AUTO_SUBMITTED] is None: + return False - if msg[headers.AUTO_REPLY2] is not None: + if msg[headers.AUTO_SUBMITTED].lower() in ("auto-replied", "auto-generated"): LOG.d( - "out-of-office email %s:%s", headers.AUTO_REPLY2, msg[headers.AUTO_REPLY2] + "out-of-office email %s:%s", + headers.AUTO_SUBMITTED, + msg[headers.AUTO_SUBMITTED], ) return True diff --git a/tests/test_email_handler.py b/tests/test_email_handler.py index f6bf8af0..bea243ba 100644 --- a/tests/test_email_handler.py +++ b/tests/test_email_handler.py @@ -53,11 +53,11 @@ def test_is_automatic_out_of_office(): msg = EmailMessage() assert not is_automatic_out_of_office(msg) - msg[headers.AUTO_REPLY1] = "yes" + msg[headers.AUTO_SUBMITTED] = "auto-replied" assert is_automatic_out_of_office(msg) - del msg[headers.AUTO_REPLY1] + del msg[headers.AUTO_SUBMITTED] assert not is_automatic_out_of_office(msg) - msg[headers.AUTO_REPLY2] = "auto-replied" + msg[headers.AUTO_SUBMITTED] = "auto-generated" assert is_automatic_out_of_office(msg)