forked from xiaohei/taiji-AI-PAD
备份
This commit is contained in:
@@ -29,11 +29,13 @@ from app.schemas import (
|
||||
SuccessResponse,
|
||||
TokenResponse,
|
||||
PasswordChangeRequest,
|
||||
ForgotPasswordRequest,
|
||||
ResetPasswordRequest,
|
||||
APIKeyInfo,
|
||||
RegenerateAPIKeyResponse,
|
||||
UserCreate,
|
||||
)
|
||||
from app.email_verification import verify_code, send_and_store_verification_code, check_rate_limit
|
||||
from app.email_verification import verify_code, send_and_store_verification_code, check_rate_limit, send_password_reset_code
|
||||
from app.agent_manager_client import get_agent_manager_client, AgentManagerError
|
||||
from app.litellm_client import get_litellm_client, LiteLLMClientError
|
||||
from config import settings
|
||||
@@ -904,3 +906,112 @@ async def register(req: UserCreate, db: AsyncSession = Depends(get_db)):
|
||||
message="注册成功"
|
||||
)
|
||||
|
||||
|
||||
@router.post("/forgot-password/send-code", response_model=SuccessResponse)
|
||||
async def forgot_password_send_code(
|
||||
req: ForgotPasswordRequest,
|
||||
db: AsyncSession = Depends(get_db)
|
||||
):
|
||||
"""
|
||||
忘记密码 - 发送验证码
|
||||
|
||||
向用户注册邮箱发送密码重置验证码。
|
||||
|
||||
频率限制:同一邮箱60秒内只能发送一次
|
||||
|
||||
请求体:
|
||||
{
|
||||
"email": "user@example.com"
|
||||
}
|
||||
|
||||
响应:
|
||||
- 成功:返回验证码已发送的消息
|
||||
- 失败:邮箱不存在、发送频率限制等
|
||||
"""
|
||||
# 1. 检查发送频率限制
|
||||
can_send, remaining_seconds = await check_rate_limit(req.email)
|
||||
if not can_send:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_429_TOO_MANY_REQUESTS,
|
||||
detail=f"请等待{remaining_seconds}秒后再重新发送验证码"
|
||||
)
|
||||
|
||||
# 2. 检查邮箱是否存在(必须是已注册用户)
|
||||
result = await db.execute(select(User).where(User.email == req.email))
|
||||
user = result.scalar_one_or_none()
|
||||
|
||||
if not user:
|
||||
# 为了安全,不直接告知邮箱不存在,但记录日志
|
||||
logger.warning("忘记密码请求:邮箱不存在", email=req.email)
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
detail="该邮箱未注册"
|
||||
)
|
||||
|
||||
# 3. 发送密码重置验证码(使用专门的密码重置邮件模板)
|
||||
code = await send_password_reset_code(req.email)
|
||||
if not code:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
||||
detail="验证码发送失败,请稍后重试"
|
||||
)
|
||||
|
||||
logger.info("忘记密码验证码已发送", email=req.email, user_id=str(user.id))
|
||||
|
||||
return SuccessResponse(
|
||||
message="验证码已发送到您的邮箱,请查收"
|
||||
)
|
||||
|
||||
|
||||
@router.post("/forgot-password/reset", response_model=SuccessResponse)
|
||||
async def forgot_password_reset(
|
||||
req: ResetPasswordRequest,
|
||||
db: AsyncSession = Depends(get_db)
|
||||
):
|
||||
"""
|
||||
忘记密码 - 重置密码
|
||||
|
||||
验证邮箱验证码并重置密码。
|
||||
|
||||
请求体:
|
||||
{
|
||||
"email": "user@example.com",
|
||||
"verification_code": "123456",
|
||||
"new_password": "newPassword123"
|
||||
}
|
||||
|
||||
响应:
|
||||
- 成功:密码重置成功
|
||||
- 失败:验证码错误、邮箱不存在等
|
||||
"""
|
||||
# 1. 检查邮箱是否存在
|
||||
result = await db.execute(select(User).where(User.email == req.email))
|
||||
user = result.scalar_one_or_none()
|
||||
|
||||
if not user:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
detail="该邮箱未注册"
|
||||
)
|
||||
|
||||
# 2. 验证验证码
|
||||
is_valid = await verify_code(req.email, req.verification_code)
|
||||
if not is_valid:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_400_BAD_REQUEST,
|
||||
detail="验证码错误或已过期"
|
||||
)
|
||||
|
||||
# 3. 更新密码
|
||||
new_hash = get_password_hash(req.new_password)
|
||||
user.password_hash = new_hash
|
||||
user.hashed_password = new_hash # 兼容旧字段
|
||||
|
||||
await db.commit()
|
||||
|
||||
logger.info("密码重置成功", email=req.email, user_id=str(user.id))
|
||||
|
||||
return SuccessResponse(
|
||||
message="密码重置成功,请使用新密码登录"
|
||||
)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user