Add comprehensive backend features and mobile UI improvements
Backend: - Add 2FA authentication with TOTP support - Add API keys management system - Add audit logging for security events - Add file upload/management system - Add notifications system with preferences - Add session management - Add webhooks integration - Add analytics endpoints - Add export functionality - Add password policy enforcement - Add new database migrations for core tables Frontend: - Add module position system (top/bottom sidebar sections) - Add search and notifications module configuration tabs - Add mobile logo replacing hamburger menu - Center page title absolutely when no tabs present - Align sidebar footer toggles with navigation items - Add lighter icon color in dark theme for mobile - Add API keys management page - Add notifications page with context - Add admin analytics and audit logs pages 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -27,6 +27,11 @@ class User(Base):
|
||||
# null means inherit from global settings (all enabled by default)
|
||||
_permissions = Column("permissions", Text, nullable=True)
|
||||
|
||||
# 2FA fields
|
||||
totp_secret = Column(String(32), nullable=True) # Base32 encoded TOTP secret
|
||||
totp_enabled = Column(Boolean, default=False, nullable=False)
|
||||
totp_backup_codes = Column(Text, nullable=True) # JSON array of backup codes
|
||||
|
||||
created_at = Column(DateTime, server_default=func.now(), nullable=False)
|
||||
updated_at = Column(DateTime, server_default=func.now(), onupdate=func.now(), nullable=False)
|
||||
last_login = Column(DateTime, nullable=True)
|
||||
@@ -49,5 +54,23 @@ class User(Base):
|
||||
else:
|
||||
self._permissions = json.dumps(value)
|
||||
|
||||
@property
|
||||
def backup_codes(self) -> list:
|
||||
"""Get backup codes as a list."""
|
||||
if self.totp_backup_codes:
|
||||
try:
|
||||
return json.loads(self.totp_backup_codes)
|
||||
except json.JSONDecodeError:
|
||||
return []
|
||||
return []
|
||||
|
||||
@backup_codes.setter
|
||||
def backup_codes(self, value: list):
|
||||
"""Set backup codes from a list."""
|
||||
if value is None:
|
||||
self.totp_backup_codes = None
|
||||
else:
|
||||
self.totp_backup_codes = json.dumps(value)
|
||||
|
||||
def __repr__(self):
|
||||
return f"<User(id={self.id}, username='{self.username}', email='{self.email}')>"
|
||||
|
||||
Reference in New Issue
Block a user