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="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 %}
<option value="{{ mailbox }}">
{{ mailbox }}
<option value="{{ mailbox.id }}" {% if mailbox.id == current_user.default_mailbox_id %}
selected {% endif %}>
{{ mailbox.email }}
</option>
{% endfor %}
</select>
<div class="small-text">
The mailbox that owns this alias.
The mailbox(es) that owns this alias.
</div>
</div>
</div>
@ -81,7 +82,7 @@
<div class="row">
<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>
</form>
@ -89,3 +90,20 @@
{% 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.extensions import db
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
signer = TimestampSigner(CUSTOM_ALIAS_SECRET)
@ -54,20 +54,30 @@ def custom_alias():
# List of (is_custom_domain, alias-suffix, time-signed alias-suffix)
suffixes = available_suffixes(current_user)
mailboxes = [mb.email for mb in current_user.mailboxes()]
mailboxes = current_user.mailboxes()
if request.method == "POST":
alias_prefix = request.form.get("prefix")
signed_suffix = request.form.get("suffix")
mailbox_email = request.form.get("mailbox")
mailbox_ids = request.form.getlist("mailboxes")
alias_note = request.form.get("note")
# check if mailbox is not tempered with
if mailbox_email != current_user.email:
mailbox = Mailbox.get_by(email=mailbox_email, user_id=current_user.id)
if not mailbox or mailbox.user_id != current_user.id:
mailboxes = []
for mailbox_id in mailbox_ids:
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")
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
try:
@ -91,14 +101,20 @@ def custom_alias():
"warning",
)
else:
mailbox = Mailbox.get_by(email=mailbox_email, user_id=current_user.id)
alias = Alias.create(
user_id=current_user.id,
email=full_alias,
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
if alias_suffix.startswith("@"):

View file

@ -7,7 +7,7 @@ from app.dashboard.views.custom_alias import (
available_suffixes,
)
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 tests.utils import login
@ -20,15 +20,50 @@ def test_add_alias_success(flask_client):
suffix = f".{word}@{EMAIL_DOMAIN}"
suffix = signer.sign(suffix).decode()
# create with a single mailbox
r = flask_client.post(
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,
)
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 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):
"""make sure user unverified mailbox is not shown to user"""