Notify another mailbox about an email sent by a mailbox to a reverse alias (#1381)

* Notify another mailbox about an email sent by a mailbox to a reverse alias

* keep reverse alias in CC and To header

* use alias as From to hint that the email is sent from the alias

* keep original subject, improve wording

* only add DKIM if custom domain has DKIM enabled
This commit is contained in:
Son Nguyen Kim 2022-10-30 19:59:42 +01:00 committed by GitHub
parent 6d8fba0320
commit 36d1626972
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 44 additions and 2 deletions

View file

@ -934,7 +934,8 @@ def decode_text(text: str, encoding: EmailEncoding = EmailEncoding.NO) -> str:
def add_header(msg: Message, text_header, html_header=None) -> Message:
if not html_header:
html_header = text_header
html_header = text_header.replace("\n", "<br>")
content_type = msg.get_content_type().lower()
if content_type == "text/plain":
encoding = get_encoding(msg)
@ -942,7 +943,7 @@ def add_header(msg: Message, text_header, html_header=None) -> Message:
if type(payload) is str:
clone_msg = copy(msg)
new_payload = f"""{text_header}
---
------------------------------
{decode_text(payload, encoding)}"""
clone_msg.set_payload(encode_text(new_payload, encoding))
return clone_msg

View file

@ -1128,6 +1128,9 @@ def handle_reply(envelope, msg: Message, rcpt_to: str) -> (bool, str):
+ headers.MIME_HEADERS,
)
orig_to = msg[headers.TO]
orig_cc = msg[headers.CC]
# replace the reverse-alias by the contact email in the email body
# as this is usually included when replying
if user.replace_reverse_alias:
@ -1254,6 +1257,12 @@ def handle_reply(envelope, msg: Message, rcpt_to: str) -> (bool, str):
envelope.rcpt_options,
is_forward=False,
)
# if alias belongs to several mailboxes, notify other mailboxes about this email
other_mailboxes = [mb for mb in alias.mailboxes if mb.email != mailbox.email]
for mb in other_mailboxes:
notify_mailbox(alias, mailbox, mb, msg, orig_to, orig_cc, alias_domain)
except Exception:
LOG.w("Cannot send email from %s to %s", alias, contact)
EmailLog.delete(email_log.id, commit=True)
@ -1280,6 +1289,38 @@ def handle_reply(envelope, msg: Message, rcpt_to: str) -> (bool, str):
return True, status.E200
def notify_mailbox(
alias, mailbox, other_mb: Mailbox, msg, orig_to, orig_cc, alias_domain
):
"""Notify another mailbox about an email sent by a mailbox to a reverse alias"""
LOG.d(
f"notify {other_mb.email} about email sent "
f"from {mailbox.email} on behalf of {alias.email} to {msg[headers.TO]}"
)
notif = add_header(
msg,
f"""**** Don't forget to remove this section if you reply to this email ****
Email sent on behalf of alias {alias.email} using mailbox {mailbox.email}""",
)
# use alias as From to hint that the email is sent from the alias
add_or_replace_header(notif, headers.FROM, alias.email)
# keep the reverse alias in CC and To header so user can reply more easily
add_or_replace_header(notif, headers.TO, orig_to)
add_or_replace_header(notif, headers.CC, orig_cc)
# add DKIM as the email is sent from alias
if should_add_dkim_signature(alias_domain):
add_dkim_signature(msg, alias_domain)
# this notif is considered transactional email
transaction = TransactionalEmail.create(email=other_mb.email, commit=True)
sl_sendmail(
generate_verp_email(VerpType.transactional, transaction.id),
other_mb.email,
notif,
)
def replace_original_message_id(alias: Alias, email_log: EmailLog, msg: Message):
"""
Replace original Message-ID by SL-Message-ID during the reply phase