feat(auth): require verified email for approval

This commit is contained in:
2026-05-06 20:57:54 +08:00
parent f2554c7e56
commit 6afc5817a7
26 changed files with 944 additions and 28 deletions
+6
View File
@@ -5,6 +5,9 @@ from backend.schemas.user import (
UserResponse,
UserWithToken,
TokenStatus,
UserEmailUpdate,
UserEmailVerify,
AdminApprovalResponse,
)
from backend.schemas.auth import (
QRCodeRequest,
@@ -49,6 +52,9 @@ __all__ = [
"UserResponse",
"UserWithToken",
"TokenStatus",
"UserEmailUpdate",
"UserEmailVerify",
"AdminApprovalResponse",
"QRCodeRequest",
"QRCodeResponse",
"QRCodeStatusResponse",
+6
View File
@@ -13,6 +13,12 @@ class EmailNotificationSettingsBase(BaseModel):
smtp_use_ssl: bool = Field(True, description="是否使用 SMTP SSL")
notify_token_expiring: bool = Field(True, description="是否通知 Token 即将过期")
notify_check_in_success: bool = Field(True, description="是否通知打卡成功")
require_admin_approval_for_registration: bool = Field(
True, description="新注册是否需要管理员审批"
)
warn_unverified_email_before_approval: bool = Field(
True, description="审批未验证邮箱用户时是否警告"
)
@field_validator("smtp_server", "smtp_sender_email", mode="before")
@classmethod
+25
View File
@@ -29,6 +29,7 @@ class UserUpdate(BaseModel):
None, min_length=6, description="新密码(可选,留空表示不修改)"
)
reset_password: Optional[bool] = Field(False, description="是否清空密码")
allow_unverified_email: bool = Field(False, description="是否允许审批未验证邮箱用户")
class UserUpdateProfile(BaseModel):
@@ -42,6 +43,28 @@ class UserUpdateProfile(BaseModel):
new_password: Optional[str] = Field(None, min_length=6, description="新密码")
class UserEmailUpdate(BaseModel):
"""用户设置邮箱并请求验证码 Schema"""
email: EmailStr = Field(..., description="邮箱地址")
class UserEmailVerify(BaseModel):
"""用户邮箱验证码校验 Schema"""
code: str = Field(..., min_length=4, max_length=12, description="邮箱验证码")
class AdminApprovalResponse(BaseModel):
"""管理员审批响应 Schema"""
success: bool
message: str
user_id: Optional[int] = None
requires_override: bool = False
warning_code: Optional[str] = None
class UserResponse(BaseModel):
"""用户响应 Schema"""
@@ -53,6 +76,8 @@ class UserResponse(BaseModel):
is_approved: bool
jwt_exp: str
email: Optional[EmailStr] = None
email_verified: bool = False
email_verified_at: Optional[datetime] = None
has_password: bool = False # 是否已设置密码
created_at: datetime
updated_at: Optional[datetime] = None