Support multiple mailboxes in custom alias page

This commit is contained in:
Son NK 2020-05-03 16:50:39 +02:00
parent b375f87d2c
commit e52f2ca6de
3 changed files with 86 additions and 17 deletions

View file

@ -56,15 +56,16 @@
<div class="row mb-2"> <div class="row mb-2">
<div class="col p-1"> <div class="col p-1">
<select class="form-control" name="mailbox"> <select class="form-control custom-select selectpicker" id="mailboxes" multiple name="mailboxes">
{% for mailbox in mailboxes %} {% for mailbox in mailboxes %}
<option value="{{ mailbox }}"> <option value="{{ mailbox.id }}" {% if mailbox.id == current_user.default_mailbox_id %}
{{ mailbox }} selected {% endif %}>
{{ mailbox.email }}
</option> </option>
{% endfor %} {% endfor %}
</select> </select>
<div class="small-text"> <div class="small-text">
The mailbox that owns this alias. The mailbox(es) that owns this alias.
</div> </div>
</div> </div>
</div> </div>
@ -81,7 +82,7 @@
<div class="row"> <div class="row">
<div class="col p-1"> <div class="col p-1">
<button class="btn btn-primary mt-1">Create</button> <span id="submit" class="btn btn-primary mt-1">Create</span>
</div> </div>
</div> </div>
</form> </form>
@ -89,3 +90,20 @@
{% endblock %} {% endblock %}
{% block script %}
<script>
$("#submit").on("click", async function () {
let that = $(this);
let mailbox_ids = $(`#mailboxes`).val();
if (mailbox_ids.length == 0) {
toastr.error("You must select at least a mailbox", "Error");
return;
}
that.closest("form").submit();
})
</script>
{% endblock %}

View file

@ -11,7 +11,7 @@ from app.dashboard.base import dashboard_bp
from app.email_utils import email_belongs_to_alias_domains from app.email_utils import email_belongs_to_alias_domains
from app.extensions import db from app.extensions import db
from app.log import LOG from app.log import LOG
from app.models import Alias, CustomDomain, DeletedAlias, Mailbox, User from app.models import Alias, CustomDomain, DeletedAlias, Mailbox, User, AliasMailbox
from app.utils import convert_to_id, random_word, word_exist from app.utils import convert_to_id, random_word, word_exist
signer = TimestampSigner(CUSTOM_ALIAS_SECRET) signer = TimestampSigner(CUSTOM_ALIAS_SECRET)
@ -54,20 +54,30 @@ def custom_alias():
# List of (is_custom_domain, alias-suffix, time-signed alias-suffix) # List of (is_custom_domain, alias-suffix, time-signed alias-suffix)
suffixes = available_suffixes(current_user) suffixes = available_suffixes(current_user)
mailboxes = [mb.email for mb in current_user.mailboxes()] mailboxes = current_user.mailboxes()
if request.method == "POST": if request.method == "POST":
alias_prefix = request.form.get("prefix") alias_prefix = request.form.get("prefix")
signed_suffix = request.form.get("suffix") signed_suffix = request.form.get("suffix")
mailbox_email = request.form.get("mailbox") mailbox_ids = request.form.getlist("mailboxes")
alias_note = request.form.get("note") alias_note = request.form.get("note")
# check if mailbox is not tempered with # check if mailbox is not tempered with
if mailbox_email != current_user.email: mailboxes = []
mailbox = Mailbox.get_by(email=mailbox_email, user_id=current_user.id) for mailbox_id in mailbox_ids:
if not mailbox or mailbox.user_id != current_user.id: mailbox = Mailbox.get(mailbox_id)
if (
not mailbox
or mailbox.user_id != current_user.id
or not mailbox.verified
):
flash("Something went wrong, please retry", "warning") flash("Something went wrong, please retry", "warning")
return redirect(url_for("dashboard.custom_alias")) return redirect(url_for("dashboard.custom_alias"))
mailboxes.append(mailbox)
if not mailboxes:
flash("At least one mailbox must be selected", "error")
return redirect(url_for("dashboard.custom_alias"))
# hypothesis: user will click on the button in the 600 secs # hypothesis: user will click on the button in the 600 secs
try: try:
@ -91,14 +101,20 @@ def custom_alias():
"warning", "warning",
) )
else: else:
mailbox = Mailbox.get_by(email=mailbox_email, user_id=current_user.id)
alias = Alias.create( alias = Alias.create(
user_id=current_user.id, user_id=current_user.id,
email=full_alias, email=full_alias,
note=alias_note, note=alias_note,
mailbox_id=mailbox.id, mailbox_id=mailboxes[0].id,
) )
db.session.flush()
for i in range(1, len(mailboxes)):
AliasMailbox.create(
user_id=alias.user_id,
alias_id=alias.id,
mailbox_id=mailboxes[i].id,
)
# get the custom_domain_id if alias is created with a custom domain # get the custom_domain_id if alias is created with a custom domain
if alias_suffix.startswith("@"): if alias_suffix.startswith("@"):

View file

@ -7,7 +7,7 @@ from app.dashboard.views.custom_alias import (
available_suffixes, available_suffixes,
) )
from app.extensions import db from app.extensions import db
from app.models import Mailbox, CustomDomain from app.models import Mailbox, CustomDomain, Alias
from app.utils import random_word from app.utils import random_word
from tests.utils import login from tests.utils import login
@ -20,15 +20,50 @@ def test_add_alias_success(flask_client):
suffix = f".{word}@{EMAIL_DOMAIN}" suffix = f".{word}@{EMAIL_DOMAIN}"
suffix = signer.sign(suffix).decode() suffix = signer.sign(suffix).decode()
# create with a single mailbox
r = flask_client.post( r = flask_client.post(
url_for("dashboard.custom_alias"), url_for("dashboard.custom_alias"),
data={"prefix": "prefix", "suffix": suffix, "mailbox": user.email,}, data={
"prefix": "prefix",
"suffix": suffix,
"mailboxes": [user.default_mailbox_id],
},
follow_redirects=True, follow_redirects=True,
) )
assert r.status_code == 200 assert r.status_code == 200
assert f"Alias prefix.{word}@{EMAIL_DOMAIN} has been created" in str(r.data) assert f"Alias prefix.{word}@{EMAIL_DOMAIN} has been created" in str(r.data)
alias = Alias.query.order_by(Alias.created_at.desc()).first()
assert not alias._mailboxes
def test_add_alias_multiple_mailboxes(flask_client):
user = login(flask_client)
db.session.commit()
word = random_word()
suffix = f".{word}@{EMAIL_DOMAIN}"
suffix = signer.sign(suffix).decode()
# create with a multiple mailboxes
mb1 = Mailbox.create(user_id=user.id, email="m1@example.com", verified=True)
db.session.commit()
r = flask_client.post(
url_for("dashboard.custom_alias"),
data={
"prefix": "prefix",
"suffix": suffix,
"mailboxes": [user.default_mailbox_id, mb1.id],
},
follow_redirects=True,
)
assert r.status_code == 200
assert f"Alias prefix.{word}@{EMAIL_DOMAIN} has been created" in str(r.data)
alias = Alias.query.order_by(Alias.created_at.desc()).first()
assert alias._mailboxes
def test_not_show_unverified_mailbox(flask_client): def test_not_show_unverified_mailbox(flask_client):
"""make sure user unverified mailbox is not shown to user""" """make sure user unverified mailbox is not shown to user"""