diff --git a/app/email_utils.py b/app/email_utils.py index ea992936..8e7b6cf0 100644 --- a/app/email_utils.py +++ b/app/email_utils.py @@ -1392,7 +1392,7 @@ def parse_full_address(full_address) -> (str, str): if full_address is None: raise ValueError - # address.parse can also parse an URL and return UrlAddress + # address.parse can also parse a URL and return UrlAddress if type(full_address) is not EmailAddress: raise ValueError diff --git a/app/models.py b/app/models.py index 87e6a612..da43fcd3 100644 --- a/app/models.py +++ b/app/models.py @@ -1242,6 +1242,18 @@ class Alias(Base, ModelMixin): return ret + def authorized_addresses(self) -> [str]: + """return addresses that can send on behalf of this alias, i.e. can send emails to this alias's reverse-aliases + Including its mailboxes and their authorized addresses + """ + mailboxes = self.mailboxes + ret = [mb.email for mb in mailboxes] + for mailbox in mailboxes: + for aa in mailbox.authorized_addresses: + ret.append(aa.email) + + return ret + def mailbox_support_pgp(self) -> bool: """return True of one of the mailboxes support PGP""" for mb in self.mailboxes: diff --git a/email_handler.py b/email_handler.py index bc645231..3bcdc06d 100644 --- a/email_handler.py +++ b/email_handler.py @@ -493,7 +493,7 @@ def sign_msg(msg: Message) -> Message: return container -def handle_email_sent_to_ourself(alias, mailbox, msg: Message, user): +def handle_email_sent_to_ourself(alias, from_addr: str, msg: Message, user): # store the refused email random_name = str(uuid.uuid4()) full_report_path = f"refused-emails/cycle-{random_name}.eml" @@ -509,18 +509,18 @@ def handle_email_sent_to_ourself(alias, mailbox, msg: Message, user): send_email_at_most_times( user, ALERT_SEND_EMAIL_CYCLE, - mailbox.email, - f"Email sent to {alias.email} from its own mailbox {mailbox.email}", + from_addr, + f"Email sent to {alias.email} from its own mailbox {from_addr}", render( "transactional/cycle-email.txt.jinja2", alias=alias, - mailbox=mailbox, + from_addr=from_addr, refused_email_url=refused_email_url, ), render( "transactional/cycle-email.html", alias=alias, - mailbox=mailbox, + from_addr=from_addr, refused_email_url=refused_email_url, ), ) @@ -558,11 +558,11 @@ def handle_forward(envelope, msg: Message, rcpt_to: str) -> List[Tuple[bool, str # check if email is sent from alias's owning mailbox(es) mail_from = envelope.mail_from - for mb in alias.mailboxes: + for addr in alias.authorized_addresses(): # email sent from a mailbox to its alias - if mb.email == mail_from: - LOG.i("cycle email sent from %s to %s", mb, alias) - handle_email_sent_to_ourself(alias, mb, msg, user) + if addr == mail_from: + LOG.i("cycle email sent from %s to %s", addr, alias) + handle_email_sent_to_ourself(alias, addr, msg, user) return [(True, status.E209)] from_header = get_header_unicode(msg[headers.FROM]) diff --git a/templates/emails/transactional/cycle-email.html b/templates/emails/transactional/cycle-email.html index 0995540b..7c705cf8 100644 --- a/templates/emails/transactional/cycle-email.html +++ b/templates/emails/transactional/cycle-email.html @@ -4,7 +4,7 @@ {% call text() %}

An email was sent to your alias {{ alias.email }} from its own mailbox - {{ mailbox.email }}. + {{ from_addr }}.

{% endcall %} diff --git a/templates/emails/transactional/cycle-email.txt.jinja2 b/templates/emails/transactional/cycle-email.txt.jinja2 index 615e73ca..27c526fa 100644 --- a/templates/emails/transactional/cycle-email.txt.jinja2 +++ b/templates/emails/transactional/cycle-email.txt.jinja2 @@ -1,4 +1,4 @@ -An email was sent to your alias {{ alias.email }} from its own mailbox {{ mailbox.email }}. +An email was sent to your alias {{ alias.email }} from its own mailbox {{ from_addr }}. SimpleLogin doesn't send this email back to your mailbox as it would be refused or hidden anyway by your email service.