2026-02-01 13:57:30 +00:00

60 lines
1.9 KiB
Python

from fastapi import APIRouter, HTTPException
from app.models import PasswordResetConfirm, PasswordResetRequest
from app.services.auth_service import (
consume_password_reset_otp,
create_password_reset_otp,
get_user_by_username,
update_user_password,
)
from app.services.email_service import send_email
router = APIRouter(prefix="/api/password-reset")
@router.post("/request")
def request_reset(payload: PasswordResetRequest):
email = payload.email.strip()
if not email:
raise HTTPException(status_code=400, detail="Email is required")
user = get_user_by_username(email)
if not user:
return {"ok": True}
otp = create_password_reset_otp(email)
body = (
"Hi,\n\n"
"We received a request to reset your Quantfortune password.\n\n"
f"Your OTP code is: {otp}\n"
"This code is valid for 10 minutes.\n\n"
"If you did not request this, you can ignore this email.\n\n"
"Quantfortune Support"
)
try:
ok = send_email(email, "Quantfortune Password Reset OTP", body)
except Exception as exc:
raise HTTPException(status_code=500, detail=f"Email send failed: {exc}") from exc
if not ok:
raise HTTPException(status_code=500, detail="Email send failed: SMTP not configured")
return {"ok": True}
@router.post("/confirm")
def confirm_reset(payload: PasswordResetConfirm):
email = payload.email.strip()
otp = payload.otp.strip()
new_password = payload.new_password
if not email or not otp or not new_password:
raise HTTPException(status_code=400, detail="Email, OTP, and new password are required")
user = get_user_by_username(email)
if not user:
raise HTTPException(status_code=400, detail="Invalid OTP or email")
if not consume_password_reset_otp(email, otp):
raise HTTPException(status_code=400, detail="Invalid or expired OTP")
update_user_password(user["id"], new_password)
return {"ok": True}