Skip to content

Commit

Permalink
Send an email if the address is already bound to an user account (#16819
Browse files Browse the repository at this point in the history
)

Co-authored-by: Mathieu Velten <mathieu.velten@beta.gouv.fr>
Co-authored-by: Olivier D <odelcroi@gmail.com>
  • Loading branch information
3 people committed Apr 23, 2024
1 parent 074ef4d commit ae18123
Show file tree
Hide file tree
Showing 7 changed files with 70 additions and 2 deletions.
1 change: 1 addition & 0 deletions changelog.d/16819.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Send an email if the address is already bound to an user account.
12 changes: 12 additions & 0 deletions synapse/config/emailconfig.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
"invite_from_person_to_space": "[%(app)s] %(person)s has invited you to join the %(space)s space on %(app)s...",
"password_reset": "[%(server_name)s] Password reset",
"email_validation": "[%(server_name)s] Validate your email",
"email_already_in_use": "[%(server_name)s] Email already in use",
}

LEGACY_TEMPLATE_DIR_WARNING = """
Expand All @@ -76,6 +77,7 @@ class EmailSubjectConfig:
invite_from_person_to_space: str
password_reset: str
email_validation: str
email_already_in_use: str


class EmailConfig(Config):
Expand Down Expand Up @@ -180,6 +182,12 @@ def read_config(self, config: JsonDict, **kwargs: Any) -> None:
registration_template_text = email_config.get(
"registration_template_text", "registration.txt"
)
already_in_use_template_html = email_config.get(
"already_in_use_template_html", "already_in_use.html"
)
already_in_use_template_text = email_config.get(
"already_in_use_template_html", "already_in_use.txt"
)
add_threepid_template_html = email_config.get(
"add_threepid_template_html", "add_threepid.html"
)
Expand Down Expand Up @@ -215,6 +223,8 @@ def read_config(self, config: JsonDict, **kwargs: Any) -> None:
self.email_password_reset_template_text,
self.email_registration_template_html,
self.email_registration_template_text,
self.email_already_in_use_template_html,
self.email_already_in_use_template_text,
self.email_add_threepid_template_html,
self.email_add_threepid_template_text,
self.email_password_reset_template_confirmation_html,
Expand All @@ -230,6 +240,8 @@ def read_config(self, config: JsonDict, **kwargs: Any) -> None:
password_reset_template_text,
registration_template_html,
registration_template_text,
already_in_use_template_html,
already_in_use_template_text,
add_threepid_template_html,
add_threepid_template_text,
"password_reset_confirmation.html",
Expand Down
16 changes: 16 additions & 0 deletions synapse/push/mailer.py
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,22 @@ async def send_registration_mail(
template_vars,
)

emails_sent_counter.labels("already_in_use")

async def send_already_in_use_mail(self, email_address: str) -> None:
"""Send an email if the address is already bound to an user account
Args:
email_address: Email address we're sending to the "already in use" mail
"""

await self.send_email(
email_address,
self.email_subjects.email_already_in_use
% {"server_name": self.hs.config.server.server_name, "app": self.app_name},
{},
)

emails_sent_counter.labels("add_threepid")

async def send_add_threepid_mail(
Expand Down
12 changes: 12 additions & 0 deletions synapse/res/templates/already_in_use.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{% extends "_base.html" %}
{% block title %}Email already in use{% endblock %}

{% block body %}
<p>You have asked us to register this email with a new Matrix account, but this email is already registered with an existing account.</p>

<p>Please reset your password if needed.</p>

<p>If this was not you, you can safely disregard this email.</p>

<p>Thank you.</p>
{% endblock %}
10 changes: 10 additions & 0 deletions synapse/res/templates/already_in_use.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
Hello there,

You have asked us to register this email with a new Matrix account,
but this email is already registered with an existing account.

Please reset your password if needed.

If this was not you, you can safely disregard this email.

Thank you.
12 changes: 10 additions & 2 deletions synapse/rest/client/register.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,12 +86,18 @@ def __init__(self, hs: "HomeServer"):
self.config = hs.config

if self.hs.config.email.can_verify_email:
self.mailer = Mailer(
self.registration_mailer = Mailer(
hs=self.hs,
app_name=self.config.email.email_app_name,
template_html=self.config.email.email_registration_template_html,
template_text=self.config.email.email_registration_template_text,
)
self.already_in_use_mailer = Mailer(
hs=self.hs,
app_name=self.config.email.email_app_name,
template_html=self.config.email.email_already_in_use_template_html,
template_text=self.config.email.email_already_in_use_template_text,
)

async def on_POST(self, request: SynapseRequest) -> Tuple[int, JsonDict]:
if not self.hs.config.email.can_verify_email:
Expand Down Expand Up @@ -139,8 +145,10 @@ async def on_POST(self, request: SynapseRequest) -> Tuple[int, JsonDict]:
if self.hs.config.server.request_token_inhibit_3pid_errors:
# Make the client think the operation succeeded. See the rationale in the
# comments for request_token_inhibit_3pid_errors.
# Still send an email to warn the user that an account already exists.
# Also wait for some random amount of time between 100ms and 1s to make it
# look like we did something.
await self.already_in_use_mailer.send_already_in_use_mail(email)
await self.hs.get_clock().sleep(random.randint(1, 10) / 10)
return 200, {"sid": random_string(16)}

Expand All @@ -151,7 +159,7 @@ async def on_POST(self, request: SynapseRequest) -> Tuple[int, JsonDict]:
email,
client_secret,
send_attempt,
self.mailer.send_registration_mail,
self.registration_mailer.send_registration_mail,
next_link,
)

Expand Down
9 changes: 9 additions & 0 deletions tests/rest/client/test_register.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import datetime
import os
from typing import Any, Dict, List, Tuple
from unittest.mock import AsyncMock

import pkg_resources

Expand All @@ -42,6 +43,7 @@
from synapse.util import Clock

from tests import unittest
from tests.server import ThreadedMemoryReactorClock
from tests.unittest import override_config


Expand All @@ -58,6 +60,13 @@ def default_config(self) -> Dict[str, Any]:
config["allow_guest_access"] = True
return config

def make_homeserver(
self, reactor: ThreadedMemoryReactorClock, clock: Clock
) -> HomeServer:
hs = super().make_homeserver(reactor, clock)
hs.get_send_email_handler()._sendmail = AsyncMock()
return hs

def test_POST_appservice_registration_valid(self) -> None:
user_id = "@as_user_kermit:test"
as_token = "i_am_an_app_service"
Expand Down

0 comments on commit ae18123

Please sign in to comment.