diff --git a/app/email_utils.py b/app/email_utils.py
index e40a5e14..916aecda 100644
--- a/app/email_utils.py
+++ b/app/email_utils.py
@@ -106,15 +106,15 @@ def render(template_name, **kwargs) -> str:
def send_welcome_email(user):
- to_email, unsubscribe_link, via_email = user.get_communication_email()
- if not to_email:
+ comm_alias, unsubscribe_link, via_email = user.get_communication_email()
+ if not comm_alias:
return
# whether this email is sent to an alias
- alias = to_email if to_email != user.email else None
+ alias = comm_alias.email if comm_alias.email != user.email else None
send_email(
- to_email,
+ comm_alias.email,
f"Welcome to SimpleLogin",
render("com/welcome.txt", user=user, alias=alias),
render("com/welcome.html", user=user, alias=alias),
diff --git a/app/models.py b/app/models.py
index bf475e3f..059ceef4 100644
--- a/app/models.py
+++ b/app/models.py
@@ -928,7 +928,7 @@ class User(Base, ModelMixin, UserMixin, PasswordOracle):
def two_factor_authentication_enabled(self) -> bool:
return self.enable_otp or self.fido_enabled()
- def get_communication_email(self) -> (Optional[str], str, bool):
+ def get_communication_email(self) -> (Optional[Alias], str, bool):
"""
Return
- the email that user uses to receive email communication. None if user unsubscribes from newsletter
@@ -942,10 +942,10 @@ class User(Base, ModelMixin, UserMixin, PasswordOracle):
unsub = UnsubscribeEncoder.encode(
UnsubscribeAction.DisableAlias, alias.id
)
- return alias.email, unsub.link, unsub.via_email
+ return alias, unsub.link, unsub.via_email
# alias disabled -> user doesn't want to receive newsletter
else:
- return None, None, False
+ return None, "", False
else:
# do not handle http POST unsubscribe
if config.UNSUBSCRIBER:
@@ -958,7 +958,7 @@ class User(Base, ModelMixin, UserMixin, PasswordOracle):
True,
)
- return None, None, False
+ return None, "", False
def available_sl_domains(self) -> [str]:
"""
diff --git a/app/newsletter_utils.py b/app/newsletter_utils.py
index 34887bf7..79e1057f 100644
--- a/app/newsletter_utils.py
+++ b/app/newsletter_utils.py
@@ -4,6 +4,7 @@ from jinja2 import Environment, FileSystemLoader
from app.config import ROOT_DIR, URL
from app.email_utils import send_email
+from app.handler.unsubscribe_encoder import UnsubscribeEncoder, UnsubscribeAction
from app.log import LOG
from app.models import NewsletterUser
@@ -16,12 +17,18 @@ def send_newsletter_to_user(newsletter, user) -> (bool, str):
html_template = env.from_string(newsletter.html)
text_template = env.from_string(newsletter.plain_text)
- to_email, unsubscribe_link, via_email = user.get_communication_email()
- if not to_email:
+ comm_alias, unsubscribe_link, via_email = user.get_communication_email()
+ if not comm_alias:
return False, f"{user} not subscribed to newsletter"
+ unsubscribe_oneclick = unsubscribe_link
+ if via_email:
+ unsubscribe_oneclick = UnsubscribeEncoder.encode(
+ UnsubscribeAction.DisableAlias, comm_alias.id
+ )
+
send_email(
- to_email,
+ comm_alias.email,
newsletter.subject,
text_template.render(
user=user,
@@ -30,9 +37,10 @@ def send_newsletter_to_user(newsletter, user) -> (bool, str):
html_template.render(
user=user,
URL=URL,
- unsubscribe_link=unsubscribe_link,
+ unsubscribe_oneclick=unsubscribe_oneclick,
),
unsubscribe_link=unsubscribe_link,
+ unsubscribe_via_email=via_email,
)
NewsletterUser.create(newsletter_id=newsletter.id, user_id=user.id, commit=True)
diff --git a/job_runner.py b/job_runner.py
index 34c89706..81aa6203 100644
--- a/job_runner.py
+++ b/job_runner.py
@@ -22,15 +22,21 @@ from server import create_light_app
def onboarding_send_from_alias(user):
- to_email, unsubscribe_link, via_email = user.get_communication_email()
- if not to_email:
+ comm_alias, unsubscribe_link, via_email = user.get_communication_email()
+ if not comm_alias.email:
return
send_email(
- to_email,
+ comm_alias.email,
"SimpleLogin Tip: Send emails from your alias",
- render("com/onboarding/send-from-alias.txt.j2", user=user, to_email=to_email),
- render("com/onboarding/send-from-alias.html", user=user, to_email=to_email),
+ render(
+ "com/onboarding/send-from-alias.txt.j2",
+ user=user,
+ to_email=comm_alias.email,
+ ),
+ render(
+ "com/onboarding/send-from-alias.html", user=user, to_email=comm_alias.email
+ ),
unsubscribe_link,
via_email,
retries=3,
@@ -39,15 +45,15 @@ def onboarding_send_from_alias(user):
def onboarding_pgp(user):
- to_email, unsubscribe_link, via_email = user.get_communication_email()
- if not to_email:
+ comm_alias, unsubscribe_link, via_email = user.get_communication_email()
+ if not comm_alias:
return
send_email(
- to_email,
+ comm_alias.email,
"SimpleLogin Tip: Secure your emails with PGP",
- render("com/onboarding/pgp.txt", user=user, to_email=to_email),
- render("com/onboarding/pgp.html", user=user, to_email=to_email),
+ render("com/onboarding/pgp.txt", user=user, to_email=comm_alias.email),
+ render("com/onboarding/pgp.html", user=user, to_email=comm_alias.email),
unsubscribe_link,
via_email,
retries=3,
@@ -56,15 +62,21 @@ def onboarding_pgp(user):
def onboarding_browser_extension(user):
- to_email, unsubscribe_link, via_email = user.get_communication_email()
- if not to_email:
+ comm_alias, unsubscribe_link, via_email = user.get_communication_email()
+ if not comm_alias:
return
send_email(
- to_email,
+ comm_alias.email,
"SimpleLogin Tip: Chrome/Firefox/Safari extensions and Android/iOS apps",
- render("com/onboarding/browser-extension.txt", user=user, to_email=to_email),
- render("com/onboarding/browser-extension.html", user=user, to_email=to_email),
+ render(
+ "com/onboarding/browser-extension.txt", user=user, to_email=comm_alias.email
+ ),
+ render(
+ "com/onboarding/browser-extension.html",
+ user=user,
+ to_email=comm_alias.email,
+ ),
unsubscribe_link,
via_email,
retries=3,
@@ -73,15 +85,15 @@ def onboarding_browser_extension(user):
def onboarding_mailbox(user):
- to_email, unsubscribe_link, via_email = user.get_communication_email()
- if not to_email:
+ comm_alias, unsubscribe_link, via_email = user.get_communication_email()
+ if not comm_alias:
return
send_email(
- to_email,
+ comm_alias.email,
"SimpleLogin Tip: Multiple mailboxes",
- render("com/onboarding/mailbox.txt", user=user, to_email=to_email),
- render("com/onboarding/mailbox.html", user=user, to_email=to_email),
+ render("com/onboarding/mailbox.txt", user=user, to_email=comm_alias.email),
+ render("com/onboarding/mailbox.html", user=user, to_email=comm_alias.email),
unsubscribe_link,
via_email,
retries=3,
@@ -90,19 +102,23 @@ def onboarding_mailbox(user):
def welcome_proton(user):
- to_email, _, _ = user.get_communication_email()
- if not to_email:
+ comm_alias, _, _ = user.get_communication_email()
+ if not comm_alias:
return
send_email(
- to_email,
+ comm_alias.email,
"Welcome to SimpleLogin, an email masking service provided by Proton",
render(
"com/onboarding/welcome-proton-user.txt.jinja2",
user=user,
- to_email=to_email,
+ to_email=comm_alias.email,
+ ),
+ render(
+ "com/onboarding/welcome-proton-user.html",
+ user=user,
+ to_email=comm_alias.email,
),
- render("com/onboarding/welcome-proton-user.html", user=user, to_email=to_email),
retries=3,
ignore_smtp_error=True,
)
diff --git a/server.py b/server.py
index 8c16975b..afa8fce1 100644
--- a/server.py
+++ b/server.py
@@ -841,8 +841,8 @@ def register_custom_commands(app):
LOG.i(f"User {user_id} was maybe deleted in the meantime")
continue
- to_email, unsubscribe_link, via_email = user.get_communication_email()
- if not to_email:
+ comm_alias, unsubscribe_link, via_email = user.get_communication_email()
+ if not comm_alias.email:
continue
sent, error_msg = send_newsletter_to_user(newsletter, user)
diff --git a/templates/emails/base.html b/templates/emails/base.html
index d1b242a5..5ae5af94 100644
--- a/templates/emails/base.html
+++ b/templates/emails/base.html
@@ -591,6 +591,16 @@
{% block footer %}{% endblock %}