From 78ef1cb8d439e8f3e3d8abae8d7c0703595377ae Mon Sep 17 00:00:00 2001 From: Son NK Date: Sat, 22 Feb 2020 20:57:19 +0700 Subject: [PATCH] notify user when emails sent to alias are bounced. --- email_handler.py | 84 ++++++++++++++++--- .../automatic-disable-alias.html | 16 ++++ .../transactional/automatic-disable-alias.txt | 13 +++ .../emails/transactional/bounced-email.html | 21 +++++ .../emails/transactional/bounced-email.txt | 21 +++++ 5 files changed, 145 insertions(+), 10 deletions(-) create mode 100644 templates/emails/transactional/automatic-disable-alias.html create mode 100644 templates/emails/transactional/automatic-disable-alias.txt create mode 100644 templates/emails/transactional/bounced-email.html create mode 100644 templates/emails/transactional/bounced-email.txt diff --git a/email_handler.py b/email_handler.py index a60e1279..b3ac65fe 100644 --- a/email_handler.py +++ b/email_handler.py @@ -336,6 +336,7 @@ def handle_reply(envelope, smtp: SMTP, msg: Message, rcpt_to: str) -> str: return "550 alias unknown by SimpleLogin" gen_email = forward_email.gen_email + user = gen_email.user if gen_email.mailbox_id: mailbox_email = gen_email.mailbox.email else: @@ -352,17 +353,9 @@ def handle_reply(envelope, smtp: SMTP, msg: Message, rcpt_to: str) -> str: gen_email.user, msg["From"], ) - # send the bounce email payload to admin - msg.replace_header("From", SUPPORT_EMAIL) - msg.replace_header("To", ADMIN_EMAIL) - add_dkim_signature(msg, get_email_domain_part(SUPPORT_EMAIL)) - smtp.sendmail( - SUPPORT_EMAIL, - ADMIN_EMAIL, - msg.as_string().encode(), - envelope.mail_options, - envelope.rcpt_options, + handle_bounce( + alias, envelope, forward_email, gen_email, msg, smtp, user, mailbox_email ) return "550 ignored" @@ -460,6 +453,77 @@ def handle_reply(envelope, smtp: SMTP, msg: Message, rcpt_to: str) -> str: return "250 Message accepted for delivery" +def handle_bounce( + alias, envelope, forward_email, gen_email, msg, smtp, user, mailbox_email +): + ForwardEmailLog.create(forward_id=forward_email.id, bounced=True) + db.session.commit() + + nb_bounced = ForwardEmailLog.filter_by( + forward_id=forward_email.id, bounced=True + ).count() + disable_alias_link = f"{URL}/dashboard/unsubscribe/{gen_email.id}" + + # inform user if this is the first bounced email + if nb_bounced == 1: + LOG.d( + "Inform user %s about bounced email sent by %s to alias %s", + user, + forward_email.website_from, + alias, + ) + send_email( + mailbox_email, + f"Email from {forward_email.website_from} to {alias} cannot be delivered to your inbox", + render( + "transactional/bounced-email.txt", + name=user.name, + alias=alias, + website_from=forward_email.website_from, + website_email=forward_email.website_email, + disable_alias_link=disable_alias_link, + ), + render( + "transactional/bounced-email.html", + name=user.name, + alias=alias, + website_from=forward_email.website_from, + website_email=forward_email.website_email, + disable_alias_link=disable_alias_link, + ), + bounced_email=msg, + ) + # disable the alias the second time email is bounced + elif nb_bounced >= 2: + LOG.d( + "Bounce happens again with alias %s from %s. Disable alias now ", + alias, + forward_email.website_from, + ) + gen_email.enabled = False + db.session.commit() + + send_email( + mailbox_email, + f"Alias {alias} has been disabled due to second undelivered email from {forward_email.website_from}", + render( + "transactional/automatic-disable-alias.txt", + name=user.name, + alias=alias, + website_from=forward_email.website_from, + website_email=forward_email.website_email, + ), + render( + "transactional/automatic-disable-alias.html", + name=user.name, + alias=alias, + website_from=forward_email.website_from, + website_email=forward_email.website_email, + ), + bounced_email=msg, + ) + + class MailHandler: async def handle_DATA(self, server, session, envelope): LOG.debug(">>> New message <<<") diff --git a/templates/emails/transactional/automatic-disable-alias.html b/templates/emails/transactional/automatic-disable-alias.html new file mode 100644 index 00000000..d3ff7a50 --- /dev/null +++ b/templates/emails/transactional/automatic-disable-alias.html @@ -0,0 +1,16 @@ +{% extends "base.html" %} + +{% block content %} + {{ render_text("Hi " + name) }} + {{ render_text("There are at least 2 emails sent to your alias " + alias + " from " + website_email + + " that have been refused (or bounced) by your email provider.") }} + + {{ render_text("This is usually due to the email being considered as spam by your email provider. + The email is included at the end of this message so you can take a look at its content.") }} + + {{ render_text('As security measure, we have disabled the alias ' + alias) }} + + {{ render_text('Please let us know if you have any question.') }} + + {{ render_text('Thanks,
SimpleLogin Team.') }} +{% endblock %} diff --git a/templates/emails/transactional/automatic-disable-alias.txt b/templates/emails/transactional/automatic-disable-alias.txt new file mode 100644 index 00000000..5de9afc7 --- /dev/null +++ b/templates/emails/transactional/automatic-disable-alias.txt @@ -0,0 +1,13 @@ +Hi {{name}} + +There are at least 2 emails sent to your alias {{alias}} from {{website_from}} that have been refused (or bounced) by your email provider. + +This is usually due to the email being considered as spam by your email provider. +The email is included at the end of this message so you can take a look at its content. + +As security measure, we have disabled the alias {{alias}}. + +Please let us know if you have any question. + +Best, +SimpleLogin team. diff --git a/templates/emails/transactional/bounced-email.html b/templates/emails/transactional/bounced-email.html new file mode 100644 index 00000000..e1e3361e --- /dev/null +++ b/templates/emails/transactional/bounced-email.html @@ -0,0 +1,21 @@ +{% extends "base.html" %} + +{% block content %} + {{ render_text("Hi " + name) }} + {{ render_text("An email sent to your alias " + alias + " from " + website_email + " was refused (or bounced) by your email provider.") }} + + {{ render_text("This is usually due to the email being considered as spam by your email provider. The email is included at the end of this message so you can take a look at its content.") }} + + {{ render_text('To avoid spams forwarded by SimpleLogin server, please consider the following options:') }} + + {{ render_text('1. If the email is not spam at all, it means your email provider has wrongly classified it as spam. In this case you can create a filter to whitelist it. The filter could be based on the sender, email subject, etc. As how to create the filter differs for each email provider, please check with your email provider on how to whitelist an email. Let us know if you need help to setup the filter by replying to this email.') }} + + {{ render_text('2. If this email is indeed spam, it means your alias ' + alias + ' is now in the hands of a spammer. In this case, you should disable or delete the alias immediately. Or, do nothing and we\'ll automatically disable this alias the second time the email is refused. Don\'t worry, we\'ll send you another email when that happens.') }} + + {{ render_button("Disable alias", disable_alias_link) }} + + {{ render_text('Please let us know if you have any question.') }} + + {{ render_text('Thanks,
SimpleLogin Team.') }} + {{ raw_url(disable_alias_link) }} +{% endblock %} diff --git a/templates/emails/transactional/bounced-email.txt b/templates/emails/transactional/bounced-email.txt new file mode 100644 index 00000000..0fd0c688 --- /dev/null +++ b/templates/emails/transactional/bounced-email.txt @@ -0,0 +1,21 @@ +Hi {{name}} + +An email sent to your alias {{alias}} from {{website_from}} was refused (or bounced) by your email provider. + +This is usually due to the email being considered as spam by your email provider. +The email is included at the end of this message so you can take a look at its content. + +To avoid spams forwarded by SimpleLogin server, please consider the following options: + +1. If the email is not spam at all, it means your email provider has wrongly classified it as spam. In this case you can create a "filter" to whitelist it. The filter could be based on the sender, email subject, etc. As how to create the filter differs for each email provider, please check with your email provider on how to whitelist an email. Let us know if you need help to setup the filter by replying to this email. + +2. If this email is spam, it means your alias {{alias}} is now in the hands of a spammer. In this case, you should disable or delete the alias immediately. Or, do nothing and we'll automatically disable this alias the second time the email is refused. Don't worry, we'll send you another email when that happens. You can disable the alias using this link: + +{{disable_alias_link}} + +Please let us know if you have any question. + +Best, +SimpleLogin team. +--------------------------------------------------------------------- +Below if the email that was refused: \ No newline at end of file