diff --git a/app/config.py b/app/config.py index 881dbba0..558f7c24 100644 --- a/app/config.py +++ b/app/config.py @@ -267,6 +267,7 @@ JOB_DELETE_ACCOUNT = "delete-account" JOB_DELETE_MAILBOX = "delete-mailbox" JOB_DELETE_DOMAIN = "delete-domain" JOB_SEND_USER_REPORT = "send-user-report" +JOB_SEND_PROTON_WELCOME_1 = "proton-welcome-1" # for pagination PAGE_LIMIT = 20 diff --git a/app/models.py b/app/models.py index cd9d9352..e5237263 100644 --- a/app/models.py +++ b/app/models.py @@ -44,6 +44,7 @@ from app.config import ( ROOT_DIR, NOREPLY, PARTNER_API_TOKEN_SECRET, + JOB_SEND_PROTON_WELCOME_1, ) from app.db import Session from app.errors import ( @@ -564,6 +565,11 @@ class User(Base, ModelMixin, UserMixin, PasswordOracle): user.flags = User.FLAG_CREATED_FROM_PARTNER user.notification = False user.trial_end = None + Job.create( + name=JOB_SEND_PROTON_WELCOME_1, + payload={"user_id": user.id}, + run_at=arrow.now(), + ) Session.flush() return user diff --git a/job_runner.py b/job_runner.py index dfdf0e6b..24773e43 100644 --- a/job_runner.py +++ b/job_runner.py @@ -87,6 +87,25 @@ def onboarding_mailbox(user): ) +def welcome_proton(user): + to_email, _, _ = user.get_communication_email() + if not to_email: + return + + send_email( + to_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, + ), + render("com/onboarding/welcome-proton-user.html", user=user, to_email=to_email), + retries=3, + ignore_smtp_error=True, + ) + + if __name__ == "__main__": while True: # wrap in an app context to benefit from app setup like database cleanup, sentry integration, etc @@ -207,6 +226,12 @@ SimpleLogin team. export_job = ExportUserDataJob.create_from_job(job) if export_job: export_job.run() + elif job.name == config.JOB_SEND_PROTON_WELCOME_1: + user_id = job.payload.get("user_id") + user = User.get(user_id) + if user and user.activated: + LOG.d("send proton welcome email to user %s", user) + welcome_proton(user) else: LOG.e("Unknown job name %s", job.name) diff --git a/static/logo-sl-proton.svg b/static/logo-sl-proton.svg new file mode 100644 index 00000000..b4eb364b --- /dev/null +++ b/static/logo-sl-proton.svg @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/templates/emails/base.html b/templates/emails/base.html index 89f56a7c..af07860d 100644 --- a/templates/emails/base.html +++ b/templates/emails/base.html @@ -449,7 +449,7 @@ - + {% block logo %}{% endblock %} diff --git a/templates/emails/com/onboarding/welcome-proton-user.html b/templates/emails/com/onboarding/welcome-proton-user.html new file mode 100644 index 00000000..02ededb8 --- /dev/null +++ b/templates/emails/com/onboarding/welcome-proton-user.html @@ -0,0 +1,39 @@ +{% extends "base.html" %} + + +{% block logo %}{% endblock %} + +{% block content %} + {% call text() %} + Welcome to SimpleLogin, a service developed by Proton to protect your email address! + {% endcall %} + + {% call text() %} + This is the first email you receive via your first alias {{ to_address }} + {% endcall %} + + {% call text() %} + This alias was automatically created the first time you accessed SimpleLogin. + Emails sent to it are forwarded to your Proton mailbox. + If you want to reply to an email, just hit "Reply" and the response will come from this alias. + Your personal email address will stay hidden. + {% endcall %} + + {% call text() %} + SimpleLogin is also available on Android + and iOS so you can manage your aliases on the go. + {% endcall %} + + {% call text() %} + For any question, feedback or feature request, please join our GitHub forum. + You can also join our Reddit or follow our Twitter. + {% endcall %} + + {% call text() %} + Best,
+ SimpleLogin Team. + {% endcall %} + +{% endblock %} + + diff --git a/templates/emails/com/onboarding/welcome-proton-user.txt.jinja2 b/templates/emails/com/onboarding/welcome-proton-user.txt.jinja2 new file mode 100644 index 00000000..e44dd1db --- /dev/null +++ b/templates/emails/com/onboarding/welcome-proton-user.txt.jinja2 @@ -0,0 +1,19 @@ +Welcome to SimpleLogin, a service developed by Proton to protect your email address! + +This is the first email you receive via your first alias {{ to_address }} + +This alias was automatically created the first time you accessed SimpleLogin. +Emails sent to it are forwarded to your Proton mailbox. +If you want to reply to an email, just hit "Reply" and the response will come from this alias. +Your personal email address will stay hidden. + +SimpleLogin is also available on Android and iOS, so you can manage your aliases on the go. + +For any question, feedback or feature request, please join our GitHub forum. +You can also join our Reddit or follow our Twitter. + +Best, +SimpleLogin Team. + + + diff --git a/tests/jobs/test_send_proton_welcome.py b/tests/jobs/test_send_proton_welcome.py new file mode 100644 index 00000000..6630b252 --- /dev/null +++ b/tests/jobs/test_send_proton_welcome.py @@ -0,0 +1,14 @@ +from app.mail_sender import mail_sender +from job_runner import welcome_proton +from tests.utils import create_new_user + + +@mail_sender.store_emails_test_decorator +def test_send_welcome_proton_email(): + user = create_new_user() + welcome_proton(user) + sent_mails = mail_sender.get_stored_emails() + assert len(sent_mails) == 1 + sent_mail = sent_mails[0] + to_email, _, _ = user.get_communication_email() + sent_mail.envelope_to = to_email diff --git a/tests/models/test_user.py b/tests/models/test_user.py index 014e2a8e..98b9d85c 100644 --- a/tests/models/test_user.py +++ b/tests/models/test_user.py @@ -1,4 +1,6 @@ -from app.models import User +from app import config +from app.db import Session +from app.models import User, Job from tests.utils import create_new_user, random_email @@ -15,3 +17,7 @@ def test_create_from_partner(flask_client): ) assert user.notification is False assert user.trial_end is None + job = Session.query(Job).order_by(Job.id.desc()).first() + assert job is not None + assert job.name == config.JOB_SEND_PROTON_WELCOME_1 + assert job.payload.get("user_id") == user.id