do do not use the ra+ prefix for reverse alias

This commit is contained in:
Son 2021-10-25 14:33:42 +02:00
parent befec56a86
commit 8680c0a739
4 changed files with 17 additions and 25 deletions

View File

@ -1004,10 +1004,6 @@ def generate_reply_email(contact_email: str, user: User) -> str:
include_sender_in_reverse_alias = user.include_sender_in_reverse_alias include_sender_in_reverse_alias = user.include_sender_in_reverse_alias
if include_sender_in_reverse_alias and contact_email: if include_sender_in_reverse_alias and contact_email:
# control char: 4 chars (ra+, +)
# random suffix: max 10 chars
# maximum: 64
# make sure contact_email can be ascii-encoded # make sure contact_email can be ascii-encoded
contact_email = convert_to_id(contact_email) contact_email = convert_to_id(contact_email)
contact_email = sanitize_email(contact_email) contact_email = sanitize_email(contact_email)
@ -1020,11 +1016,15 @@ def generate_reply_email(contact_email: str, user: User) -> str:
if include_sender_in_reverse_alias and contact_email: if include_sender_in_reverse_alias and contact_email:
random_length = random.randint(5, 10) random_length = random.randint(5, 10)
reply_email = ( reply_email = (
f"ra+{contact_email}+{random_string(random_length)}@{EMAIL_DOMAIN}" # do not use the ra+ anymore
# f"ra+{contact_email}+{random_string(random_length)}@{EMAIL_DOMAIN}"
f"{contact_email}_{random_string(random_length)}@{EMAIL_DOMAIN}"
) )
else: else:
random_length = random.randint(20, 50) random_length = random.randint(20, 50)
reply_email = f"ra+{random_string(random_length)}@{EMAIL_DOMAIN}" # do not use the ra+ anymore
# reply_email = f"ra+{random_string(random_length)}@{EMAIL_DOMAIN}"
reply_email = f"{random_string(random_length)}@{EMAIL_DOMAIN}"
if not Contact.get_by(reply_email=reply_email): if not Contact.get_by(reply_email=reply_email):
return reply_email return reply_email
@ -1033,6 +1033,10 @@ def generate_reply_email(contact_email: str, user: User) -> str:
def is_reverse_alias(address: str) -> bool: def is_reverse_alias(address: str) -> bool:
# to take into account the new reverse-alias that doesn't start with "ra+"
if Contact.get_by(reply_email=address):
return True
return address.endswith(f"@{EMAIL_DOMAIN}") and ( return address.endswith(f"@{EMAIL_DOMAIN}") and (
address.startswith("reply+") or address.startswith("ra+") address.startswith("reply+") or address.startswith("ra+")
) )

View File

@ -1477,7 +1477,7 @@ class Contact(Base, ModelMixin):
# when user clicks on "reply", they will reply to this address. # when user clicks on "reply", they will reply to this address.
# This address allows to hide user personal email # This address allows to hide user personal email
# this reply email is created every time a website sends an email to user # this reply email is created every time a website sends an email to user
# it has the prefix "reply+" or "ra+" to distinguish with other email # it used to have the prefix "reply+" or "ra+"
reply_email = sa.Column(sa.String(512), nullable=False, index=True) reply_email = sa.Column(sa.String(512), nullable=False, index=True)
# whether a contact is created via CC # whether a contact is created via CC
@ -1509,7 +1509,7 @@ class Contact(Base, ModelMixin):
"""return the email address with name. """return the email address with name.
to use when user wants to send an email from the alias to use when user wants to send an email from the alias
Return Return
"First Last | email at example.com" <ra+random_string@SL> "First Last | email at example.com" <reverse-alias@SL>
""" """
# Prefer using contact name if possible # Prefer using contact name if possible

View File

@ -1012,7 +1012,7 @@ def handle_reply(envelope, msg: Message, rcpt_to: str) -> (bool, str):
+ headers.MIME_HEADERS, + headers.MIME_HEADERS,
) )
# replace the reverse-alias (i.e. "ra+string@simplelogin.co") by the contact email in the email body # replace the reverse-alias by the contact email in the email body
# as this is usually included when replying # as this is usually included when replying
if user.replace_reverse_alias: if user.replace_reverse_alias:
LOG.d("Replace reverse-alias %s by contact email %s", reply_email, contact) LOG.d("Replace reverse-alias %s by contact email %s", reply_email, contact)
@ -1372,7 +1372,6 @@ def handle_hotmail_complaint(msg: Message) -> bool:
if not to_header: if not to_header:
LOG.e("cannot find the alias") LOG.e("cannot find the alias")
return False return False
try: try:
_, alias_address = parse_full_address(get_header_unicode(to_header)) _, alias_address = parse_full_address(get_header_unicode(to_header))
except ValueError: except ValueError:
@ -2005,8 +2004,7 @@ def handle(envelope: Envelope) -> str:
else: else:
copy_msg = msg copy_msg = msg
# Reply case # Reply case: the recipient is a reverse alias. Usually starts with "reply+" or "ra+"
# recipient starts with "reply+" or "ra+" (ra=reverse-alias) prefix
if is_reverse_alias(rcpt_to): if is_reverse_alias(rcpt_to):
LOG.d( LOG.d(
"Reply phase %s(%s) -> %s", mail_from, copy_msg[headers.FROM], rcpt_to "Reply phase %s(%s) -> %s", mail_from, copy_msg[headers.FROM], rcpt_to

View File

@ -490,14 +490,9 @@ def test_generate_reply_email(flask_client):
activated=True, activated=True,
) )
reply_email = generate_reply_email("test@example.org", user) reply_email = generate_reply_email("test@example.org", user)
# return something like
# ra+<random>@sl.local
assert reply_email.endswith(EMAIL_DOMAIN) assert reply_email.endswith(EMAIL_DOMAIN)
reply_email = generate_reply_email("", user) reply_email = generate_reply_email("", user)
# return something like
# ra+qdrcxzppngmvtajklnhqvvuyyzgkyityrzjwikk@sl.local
assert reply_email.startswith("ra+")
assert reply_email.endswith(EMAIL_DOMAIN) assert reply_email.endswith(EMAIL_DOMAIN)
@ -511,23 +506,18 @@ def test_generate_reply_email_include_sender_in_reverse_alias(flask_client):
include_sender_in_reverse_alias=True, include_sender_in_reverse_alias=True,
) )
reply_email = generate_reply_email("test@example.org", user) reply_email = generate_reply_email("test@example.org", user)
# return something like assert reply_email.startswith("test.at.example.org")
# ra+test.at.example.org+gjbnnddll@sl.local
assert reply_email.startswith("ra+test.at.example.org+")
assert reply_email.endswith(EMAIL_DOMAIN) assert reply_email.endswith(EMAIL_DOMAIN)
reply_email = generate_reply_email("", user) reply_email = generate_reply_email("", user)
# return something like
# ra+qdrcxzppngmvtajklnhqvvuyyzgkyityrzjwikk@sl.local
assert reply_email.startswith("ra+")
assert reply_email.endswith(EMAIL_DOMAIN) assert reply_email.endswith(EMAIL_DOMAIN)
reply_email = generate_reply_email("👌汉字@example.org", user) reply_email = generate_reply_email("👌汉字@example.org", user)
assert reply_email.startswith("ra+yizi.at.example.org+") assert reply_email.startswith("yizi.at.example.org")
# make sure reply_email only contain lowercase # make sure reply_email only contain lowercase
reply_email = generate_reply_email("TEST@example.org", user) reply_email = generate_reply_email("TEST@example.org", user)
assert reply_email.startswith("ra+test.at.example.org") assert reply_email.startswith("test.at.example.org")
def test_normalize_reply_email(flask_client): def test_normalize_reply_email(flask_client):