add POST /api/mailboxes: create a new mailbox
This commit is contained in:
parent
96502c677d
commit
722bff319e
17
README.md
17
README.md
|
@ -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
|
### Contact endpoints
|
||||||
|
|
||||||
#### DELETE /api/contacts/:contact_id
|
#### DELETE /api/contacts/:contact_id
|
||||||
|
|
|
@ -7,4 +7,5 @@ from .views import (
|
||||||
auth_mfa,
|
auth_mfa,
|
||||||
alias,
|
alias,
|
||||||
apple,
|
apple,
|
||||||
|
mailbox,
|
||||||
)
|
)
|
||||||
|
|
58
app/api/views/mailbox.py
Normal file
58
app/api/views/mailbox.py
Normal 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,
|
||||||
|
)
|
|
@ -94,29 +94,7 @@ def mailbox_route():
|
||||||
)
|
)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
|
||||||
s = Signer(MAILBOX_SECRET)
|
send_verification_email(current_user, new_mailbox)
|
||||||
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,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
|
|
||||||
flash(
|
flash(
|
||||||
f"You are going to receive an email to confirm {mailbox_email}.",
|
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")
|
@dashboard_bp.route("/mailbox_verify")
|
||||||
def mailbox_verify():
|
def mailbox_verify():
|
||||||
s = Signer(MAILBOX_SECRET)
|
s = Signer(MAILBOX_SECRET)
|
||||||
|
|
31
tests/api/test_mailbox.py
Normal file
31
tests/api/test_mailbox.py
Normal 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
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue