diff --git a/README.md b/README.md index 7c7b2113..e12f8cb1 100644 --- a/README.md +++ b/README.md @@ -813,6 +813,15 @@ Input: Output: - 200: user is going to receive an email that contains the activation code. +#### POST /api/auth/forgot_password + +Input: +- email + +Output: +- 200: user is going to receive an email to reset the password +- 400 if error (email not found) + #### GET /api/aliases Get user aliases. diff --git a/app/api/views/auth_login.py b/app/api/views/auth_login.py index c750a6fb..876047f9 100644 --- a/app/api/views/auth_login.py +++ b/app/api/views/auth_login.py @@ -10,6 +10,7 @@ from itsdangerous import Signer from app import email_utils from app.api.base import api_bp from app.config import FLASK_SECRET, DISABLE_REGISTRATION +from app.dashboard.views.setting import send_reset_password_email from app.email_utils import ( can_be_used_as_personal_email, email_already_used, @@ -316,3 +317,31 @@ def auth_payload(user, device) -> dict: ret["api_key"] = api_key.code return ret + + +@api_bp.route("/auth/forgot_password", methods=["POST"]) +@cross_origin() +def forgot_password(): + """ + User forgot password + Input: + email + Output: + 200 and a reset password email is sent to user + 400 if email not exist + + """ + data = request.get_json() + if not data: + return jsonify(error="request body cannot be empty"), 400 + + email = data.get("email") + + user = User.get_by(email=email) + + if not user: + return jsonify(error="Error"), 400 + + send_reset_password_email(user) + + return jsonify(reset_sent=True) diff --git a/tests/api/test_auth_login.py b/tests/api/test_auth_login.py index 558b671e..9b0a6dd4 100644 --- a/tests/api/test_auth_login.py +++ b/tests/api/test_auth_login.py @@ -200,3 +200,19 @@ def test_auth_reactivate_success(flask_client): assert act_code assert len(act_code.code) == 6 assert act_code.tries == 3 + + +def test_auth_login_forgot_password(flask_client): + User.create(email="a@b.c", password="password", name="Test User", activated=True) + db.session.commit() + + r = flask_client.post(url_for("api.forgot_password"), json={"email": "a@b.c"},) + + assert r.status_code == 200 + + # No such email + r = flask_client.post( + url_for("api.forgot_password"), json={"email": "not-exist@b.c"}, + ) + + assert r.status_code == 400