add POST /api/mailboxes: create a new mailbox

This commit is contained in:
Son NK 2020-05-23 16:09:06 +02:00
parent 96502c677d
commit 722bff319e
5 changed files with 132 additions and 23 deletions

View File

@ -1161,6 +1161,23 @@ List of mailboxes. Each mailbox has id, email field.
}
```
#### POST /api/mailboxes
Create a new mailbox
Input:
- `Authentication` header that contains the api key
- email: the new mailbox address
Output:
- 201 along with the following response if new mailbox is created successfully. User is going to receive a verification email.
- id: integer
- email: the mailbox email address
- verified: boolean.
- default: whether is the default mailbox. User cannot delete the default mailbox
- 400 with error message otherwise. The error message can be displayed to user.
### Contact endpoints
#### DELETE /api/contacts/:contact_id

View File

@ -7,4 +7,5 @@ from .views import (
auth_mfa,
alias,
apple,
mailbox,
)

58
app/api/views/mailbox.py Normal file
View File

@ -0,0 +1,58 @@
from flask import g
from flask import jsonify
from flask import request
from flask_cors import cross_origin
from app.api.base import api_bp, require_api_auth
from app.dashboard.views.mailbox import send_verification_email
from app.email_utils import (
mailbox_already_used,
email_domain_can_be_used_as_mailbox,
)
from app.extensions import db
from app.models import Mailbox
@api_bp.route("/mailboxes", methods=["POST"])
@cross_origin()
@require_api_auth
def create_mailbox():
"""
Create a new mailbox. User needs to verify the mailbox via an activation email.
Input:
email: in body
Output:
the new mailbox
- id
- email
- verified
"""
user = g.user
mailbox_email = request.get_json().get("email").lower().strip()
if mailbox_already_used(mailbox_email, user):
return jsonify(error=f"{mailbox_email} already used"), 400
elif not email_domain_can_be_used_as_mailbox(mailbox_email):
return (
jsonify(
error=f"{mailbox_email} cannot be used. Please note a mailbox cannot "
f"be a disposable email address"
),
400,
)
else:
new_mailbox = Mailbox.create(email=mailbox_email, user_id=user.id)
db.session.commit()
send_verification_email(user, new_mailbox)
return (
jsonify(
id=new_mailbox.id,
email=new_mailbox.email,
verified=new_mailbox.verified,
default=user.default_mailbox_id == new_mailbox.id,
),
201,
)

View File

@ -94,29 +94,7 @@ def mailbox_route():
)
db.session.commit()
s = Signer(MAILBOX_SECRET)
mailbox_id_signed = s.sign(str(new_mailbox.id)).decode()
verification_url = (
URL
+ "/dashboard/mailbox_verify"
+ f"?mailbox_id={mailbox_id_signed}"
)
send_email(
mailbox_email,
f"Please confirm your email {mailbox_email}",
render(
"transactional/verify-mailbox.txt",
user=current_user,
link=verification_url,
mailbox_email=mailbox_email,
),
render(
"transactional/verify-mailbox.html",
user=current_user,
link=verification_url,
mailbox_email=mailbox_email,
),
)
send_verification_email(current_user, new_mailbox)
flash(
f"You are going to receive an email to confirm {mailbox_email}.",
@ -138,6 +116,30 @@ def mailbox_route():
)
def send_verification_email(user, mailbox):
s = Signer(MAILBOX_SECRET)
mailbox_id_signed = s.sign(str(mailbox.id)).decode()
verification_url = (
URL + "/dashboard/mailbox_verify" + f"?mailbox_id={mailbox_id_signed}"
)
send_email(
mailbox.email,
f"Please confirm your email {mailbox.email}",
render(
"transactional/verify-mailbox.txt",
user=user,
link=verification_url,
mailbox_email=mailbox.email,
),
render(
"transactional/verify-mailbox.html",
user=user,
link=verification_url,
mailbox_email=mailbox.email,
),
)
@dashboard_bp.route("/mailbox_verify")
def mailbox_verify():
s = Signer(MAILBOX_SECRET)

31
tests/api/test_mailbox.py Normal file
View File

@ -0,0 +1,31 @@
from flask import url_for
from flask import url_for
from app.extensions import db
from app.models import User, ApiKey, Mailbox
def test_create_mailbox(flask_client):
user = User.create(
email="a@b.c", password="password", name="Test User", activated=True
)
db.session.commit()
# create api_key
api_key = ApiKey.create(user.id, "for test")
db.session.commit()
r = flask_client.post(
url_for("api.create_mailbox"),
headers={"Authentication": api_key.code},
json={"email": "mailbox@gmail.com"},
)
assert r.status_code == 201
assert r.json["email"] == "mailbox@gmail.com"
assert r.json["verified"] is False
assert r.json["id"] > 0
assert r.json["default"] is False