diff --git a/app/api/views/new_custom_alias.py b/app/api/views/new_custom_alias.py index 7d93dd88..af88fbf9 100644 --- a/app/api/views/new_custom_alias.py +++ b/app/api/views/new_custom_alias.py @@ -1,6 +1,6 @@ from typing import Optional -from email_validator import validate_email +from email_validator import validate_email, EmailNotValidError from flask import g from flask import jsonify, request from itsdangerous import SignatureExpired @@ -213,7 +213,16 @@ def new_custom_alias_v3(): LOG.d("full alias already used %s", full_alias) return jsonify(error=f"alias {full_alias} already exists"), 409 - custom_domain = get_custom_domain(full_alias) + if ".." in full_alias: + return ( + jsonify(error="2 consecutive dot signs aren't allowed in an email address"), + 400, + ) + + try: + custom_domain = get_custom_domain(full_alias) + except EmailNotValidError: + return jsonify(error="invalid email alias"), 400 alias = Alias.create( user_id=user.id, diff --git a/tests/api/test_new_custom_alias.py b/tests/api/test_new_custom_alias.py index cdefa135..9254857b 100644 --- a/tests/api/test_new_custom_alias.py +++ b/tests/api/test_new_custom_alias.py @@ -269,3 +269,25 @@ def test_too_many_requests(flask_client): # last request assert r.status_code == 429 assert r.json == {"error": "Rate limit exceeded"} + + +def test_invalid_alias_2_consecutive_dots(flask_client): + user = login(flask_client) + + word = random_word() + suffix = f".{word}@{EMAIL_DOMAIN}" + signed_suffix = signer.sign(suffix).decode() + + r = flask_client.post( + "/api/v3/alias/custom/new", + json={ + "alias_prefix": "prefix.", # with the trailing dot, the alias will have 2 consecutive dots + "signed_suffix": signed_suffix, + "mailbox_ids": [user.default_mailbox_id], + }, + ) + + assert r.status_code == 400 + assert r.json == { + "error": "2 consecutive dot signs aren't allowed in an email address" + }