diff --git a/app/email_utils.py b/app/email_utils.py index 1da44afa..8958b61c 100644 --- a/app/email_utils.py +++ b/app/email_utils.py @@ -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 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 contact_email = convert_to_id(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: random_length = random.randint(5, 10) 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: 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): return reply_email @@ -1033,6 +1033,10 @@ def generate_reply_email(contact_email: str, user: User) -> str: 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 ( address.startswith("reply+") or address.startswith("ra+") ) diff --git a/app/models.py b/app/models.py index f8d58e37..70d1ea9d 100644 --- a/app/models.py +++ b/app/models.py @@ -1477,7 +1477,7 @@ class Contact(Base, ModelMixin): # when user clicks on "reply", they will reply to this address. # This address allows to hide user personal email # 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) # whether a contact is created via CC @@ -1509,7 +1509,7 @@ class Contact(Base, ModelMixin): """return the email address with name. to use when user wants to send an email from the alias Return - "First Last | email at example.com" + "First Last | email at example.com" """ # Prefer using contact name if possible diff --git a/email_handler.py b/email_handler.py index 3ec9edd8..eda3ea38 100644 --- a/email_handler.py +++ b/email_handler.py @@ -1012,7 +1012,7 @@ def handle_reply(envelope, msg: Message, rcpt_to: str) -> (bool, str): + 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 if user.replace_reverse_alias: 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: LOG.e("cannot find the alias") return False - try: _, alias_address = parse_full_address(get_header_unicode(to_header)) except ValueError: @@ -2005,8 +2004,7 @@ def handle(envelope: Envelope) -> str: else: copy_msg = msg - # Reply case - # recipient starts with "reply+" or "ra+" (ra=reverse-alias) prefix + # Reply case: the recipient is a reverse alias. Usually starts with "reply+" or "ra+" if is_reverse_alias(rcpt_to): LOG.d( "Reply phase %s(%s) -> %s", mail_from, copy_msg[headers.FROM], rcpt_to diff --git a/tests/test_email_utils.py b/tests/test_email_utils.py index 8c9a4c8b..89709c96 100644 --- a/tests/test_email_utils.py +++ b/tests/test_email_utils.py @@ -490,14 +490,9 @@ def test_generate_reply_email(flask_client): activated=True, ) reply_email = generate_reply_email("test@example.org", user) - # return something like - # ra+@sl.local assert reply_email.endswith(EMAIL_DOMAIN) reply_email = generate_reply_email("", user) - # return something like - # ra+qdrcxzppngmvtajklnhqvvuyyzgkyityrzjwikk@sl.local - assert reply_email.startswith("ra+") 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, ) reply_email = generate_reply_email("test@example.org", user) - # return something like - # ra+test.at.example.org+gjbnnddll@sl.local - assert reply_email.startswith("ra+test.at.example.org+") + assert reply_email.startswith("test.at.example.org") assert reply_email.endswith(EMAIL_DOMAIN) reply_email = generate_reply_email("", user) - # return something like - # ra+qdrcxzppngmvtajklnhqvvuyyzgkyityrzjwikk@sl.local - assert reply_email.startswith("ra+") assert reply_email.endswith(EMAIL_DOMAIN) 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 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):