- Replace hardcoded JWT secret with randomly generated key persisted to file - Replace hardcoded default password with random password shown in logs - Migrate token storage from localStorage to HttpOnly SameSite=strict cookie - Add IP-based login rate limiter (5 attempts / 15 min, 429 on lockout) - Add token_version for JWT revocation on password change - Add password strength validation (min 6 chars, 3+ unique characters) - Inject decoded user payload into request.state.user in auth middleware - Add /api/auth/me and /api/auth/logout endpoints - Narrow auth middleware exception handling (JWTError only, not all Exception) - Update updated_at timestamp on password change - Remove localStorage token management from frontend (axios, router, store) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
35 lines
1.2 KiB
Python
35 lines
1.2 KiB
Python
from sqlalchemy import Column, Integer, String, Text, DateTime, Date
|
||
from app.database import Base
|
||
from app.utils.datetime import utcnow
|
||
|
||
class UserSettings(Base):
|
||
"""用户设置模型(单例,始终只有一条记录 id=1)"""
|
||
__tablename__ = "user_settings"
|
||
|
||
id = Column(Integer, primary_key=True, default=1)
|
||
|
||
# 个人信息
|
||
nickname = Column(String(50), default="爱莉希雅")
|
||
avatar = Column(Text, nullable=True)
|
||
signature = Column(String(200), nullable=True)
|
||
birthday = Column(Date, nullable=True)
|
||
email = Column(String(100), nullable=True)
|
||
|
||
# 应用信息
|
||
site_name = Column(String(50), default="爱莉希雅待办")
|
||
|
||
# 应用偏好
|
||
theme = Column(String(20), default="pink")
|
||
language = Column(String(10), default="zh-CN")
|
||
default_view = Column(String(20), default="list")
|
||
default_sort_by = Column(String(20), default="created_at")
|
||
default_sort_order = Column(String(10), default="desc")
|
||
|
||
# 认证
|
||
password_hash = Column(String(255), default="")
|
||
token_version = Column(Integer, default=0)
|
||
|
||
# 时间戳
|
||
created_at = Column(DateTime, default=utcnow)
|
||
updated_at = Column(DateTime, default=utcnow, onupdate=utcnow)
|