diff --git a/src/auth/routes.py b/src/auth/routes.py index 716505c..9fec563 100644 --- a/src/auth/routes.py +++ b/src/auth/routes.py @@ -47,3 +47,15 @@ def signup(): return _redirect_with_error("/inscription", "email_send_failed", email) return redirect("/connexion?pending_verification=1") + + +@auth_bp.route("/verify-email", methods=["GET"]) +def verify_email(): + token = request.args.get("token") or "" + if not token: + return redirect("/verification-email?error=invalid_token") + user_id = tokens.consume_verification_token(token) + if user_id is None: + return redirect("/verification-email?error=invalid_token") + db.set_email_verified(user_id) + return redirect("/connexion?verified=1") diff --git a/tests/auth/test_verify_email.py b/tests/auth/test_verify_email.py new file mode 100644 index 0000000..f7feb00 --- /dev/null +++ b/tests/auth/test_verify_email.py @@ -0,0 +1,31 @@ +from src.auth import db, tokens + + +def test_verify_email_valid_token_marks_user_verified(client, users_db_path): + db.init_schema() + uid = db.create_user("a@b.c", "hash") + token = tokens.create_verification_token(uid) + + resp = client.get(f"/auth/verify-email?token={token}") + assert resp.status_code == 302 + assert "/connexion?verified=1" in resp.headers["Location"] + assert db.get_user_by_id(uid)["email_verified"] == 1 + + +def test_verify_email_invalid_token(client): + resp = client.get("/auth/verify-email?token=invalide") + assert "error=invalid_token" in resp.headers["Location"] + + +def test_verify_email_missing_token(client): + resp = client.get("/auth/verify-email") + assert "error=invalid_token" in resp.headers["Location"] + + +def test_verify_email_single_use(client, users_db_path): + db.init_schema() + uid = db.create_user("a@b.c", "h") + token = tokens.create_verification_token(uid) + client.get(f"/auth/verify-email?token={token}") + resp = client.get(f"/auth/verify-email?token={token}") + assert "error=invalid_token" in resp.headers["Location"]