Browse Source

Handle on-click unsubcribe

Son NK 5 years ago
parent
commit
da6441b4b8

+ 66 - 5
email_handler.py

@@ -52,6 +52,7 @@ from app.config import (
     URL,
     ALIAS_DOMAINS,
     POSTFIX_SUBMISSION_TLS,
+    UNSUBSCRIBER,
 )
 from app.email_utils import (
     send_email,
@@ -459,11 +460,15 @@ def handle_forward(envelope, smtp: SMTP, msg: Message, rcpt_to: str) -> (bool, s
             add_or_replace_header(msg, "To", to_header.strip())
 
         # add List-Unsubscribe header
-        unsubscribe_link = f"{URL}/dashboard/unsubscribe/{alias.id}"
-        add_or_replace_header(msg, "List-Unsubscribe", f"<{unsubscribe_link}>")
-        add_or_replace_header(
-            msg, "List-Unsubscribe-Post", "List-Unsubscribe=One-Click"
-        )
+        if UNSUBSCRIBER:
+            unsubscribe_link = f"mailto:{UNSUBSCRIBER}?subject={alias.id}="
+            add_or_replace_header(msg, "List-Unsubscribe", f"<{unsubscribe_link}>")
+        else:
+            unsubscribe_link = f"{URL}/dashboard/unsubscribe/{alias.id}"
+            add_or_replace_header(msg, "List-Unsubscribe", f"<{unsubscribe_link}>")
+            add_or_replace_header(
+                msg, "List-Unsubscribe-Post", "List-Unsubscribe=One-Click"
+            )
 
         add_dkim_signature(msg, EMAIL_DOMAIN)
 
@@ -743,6 +748,54 @@ def handle_bounce(
         )
 
 
+def handle_unsubscribe(envelope):
+    message_data = envelope.content.decode("utf8", errors="replace")
+    msg = Parser(policy=SMTPUTF8).parsestr(message_data)
+
+    # format: alias_id:
+    subject = msg["Subject"]
+    try:
+        alias_id = int(subject[:-1])
+        alias = Alias.get(alias_id)
+    except Exception:
+        LOG.warning("Cannot parse alias from subject %s", msg["Subject"])
+        return "550 SL ignored"
+
+    if not alias:
+        LOG.warning("No such alias %s", alias_id)
+        return "550 SL ignored"
+
+    # This sender cannot unsubscribe
+    if alias.mailbox_email() != envelope.mail_from:
+        LOG.d("%s cannot disable alias %s", envelope.mail_from, alias)
+        return "550 SL ignored"
+
+    # Sender is owner of this alias
+    alias.enabled = False
+    db.session.commit()
+    user = alias.user
+
+    enable_alias_url = URL + f"/dashboard/?highlight_alias_id={alias.id}"
+    send_email(
+        envelope.mail_from,
+        f"Alias {alias.email} has been disabled successfully",
+        render(
+            "transactional/unsubscribe-disable-alias.txt",
+            user=user,
+            alias=alias.email,
+            enable_alias_url=enable_alias_url,
+        ),
+        render(
+            "transactional/unsubscribe-disable-alias.html",
+            user=user,
+            alias=alias.email,
+            enable_alias_url=enable_alias_url,
+        ),
+    )
+
+    return "250 Unsubscribe request accepted"
+
+
 class MailHandler:
     async def handle_DATA(self, server, session, envelope):
         LOG.debug(
@@ -757,6 +810,14 @@ class MailHandler:
         else:
             smtp = SMTP(POSTFIX_SERVER, 25)
 
+        # unsubscribe request
+        if UNSUBSCRIBER and envelope.rcpt_tos == [UNSUBSCRIBER]:
+            LOG.d("Handle unsubscribe request from %s", envelope.mail_from)
+            app = new_app()
+
+            with app.app_context():
+                return handle_unsubscribe(envelope)
+
         # result of all deliveries
         # each element is a couple of whether the delivery is successful and the smtp status
         res: [(bool, str)] = []

+ 11 - 0
templates/emails/transactional/unsubscribe-disable-alias.html

@@ -0,0 +1,11 @@
+{% extends "base.html" %}
+
+{% block content %}
+  {{ render_text("Hi " + user.name) }}
+  {{ render_text("Your alias <b>"+ alias +"</b> has been disabled successfully.") }}
+  {{ render_text("If this is a mistake, you can re-enable the alias on the dashboard.") }}
+  {{ render_button("Enable Alias", enable_alias_url) }}
+  {{ render_text('Thanks, <br />SimpleLogin Team.') }}
+  {{ raw_url(enable_alias_url) }}
+{% endblock %}
+

+ 12 - 0
templates/emails/transactional/unsubscribe-disable-alias.txt

@@ -0,0 +1,12 @@
+Hi {{user.name}}
+
+Your alias {{alias}} has been disabled successfully.
+
+If this is a mistake, you can re-enable the alias on the dashboard via
+
+{{ enable_alias_url }}
+
+Please let us know if you have any question.
+
+Best,
+SimpleLogin team.