Improve the frontend modals

This commit is contained in:
Urtzi Alfaro
2025-10-27 16:33:26 +01:00
parent 61376b7a9f
commit 858d985c92
143 changed files with 9289 additions and 2306 deletions

View File

@@ -5,6 +5,8 @@ Business logic for login, register, token refresh, password reset, and email ver
from fastapi import APIRouter, Depends, HTTPException, status, Request
from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
from sqlalchemy.ext.asyncio import AsyncSession
from typing import Dict, Any
import structlog
from app.schemas.auth import (
@@ -12,16 +14,17 @@ from app.schemas.auth import (
PasswordChange, PasswordReset, UserResponse
)
from app.services.auth_service import EnhancedAuthService
from app.models.users import User
from app.core.database import get_db
from shared.database.base import create_database_manager
from shared.monitoring.decorators import track_execution_time
from shared.monitoring.metrics import get_metrics_collector
from shared.routing import RouteBuilder
from shared.auth.decorators import get_current_user_dep
from app.core.config import settings
logger = structlog.get_logger()
router = APIRouter(tags=["auth-operations"])
security = HTTPBearer()
route_builder = RouteBuilder('auth')
def get_auth_service():
@@ -30,7 +33,7 @@ def get_auth_service():
return EnhancedAuthService(database_manager)
@router.post(route_builder.build_base_route("register", include_tenant_prefix=False), response_model=TokenResponse)
@router.post("/api/v1/auth/register", response_model=TokenResponse)
@track_execution_time("enhanced_registration_duration_seconds", "auth-service")
async def register(
user_data: UserRegistration,
@@ -100,7 +103,7 @@ async def register(
)
@router.post(route_builder.build_base_route("login", include_tenant_prefix=False), response_model=TokenResponse)
@router.post("/api/v1/auth/login", response_model=TokenResponse)
@track_execution_time("enhanced_login_duration_seconds", "auth-service")
async def login(
login_data: UserLogin,
@@ -164,7 +167,7 @@ async def login(
)
@router.post(route_builder.build_base_route("refresh", include_tenant_prefix=False))
@router.post("/api/v1/auth/refresh")
@track_execution_time("enhanced_token_refresh_duration_seconds", "auth-service")
async def refresh_token(
refresh_data: RefreshTokenRequest,
@@ -201,7 +204,7 @@ async def refresh_token(
)
@router.post(route_builder.build_base_route("verify", include_tenant_prefix=False))
@router.post("/api/v1/auth/verify")
@track_execution_time("enhanced_token_verify_duration_seconds", "auth-service")
async def verify_token(
credentials: HTTPAuthorizationCredentials = Depends(security),
@@ -249,7 +252,7 @@ async def verify_token(
)
@router.post(route_builder.build_base_route("logout", include_tenant_prefix=False))
@router.post("/api/v1/auth/logout")
@track_execution_time("enhanced_logout_duration_seconds", "auth-service")
async def logout(
refresh_data: RefreshTokenRequest,
@@ -295,7 +298,7 @@ async def logout(
)
@router.post(route_builder.build_base_route("change-password", include_tenant_prefix=False))
@router.post("/api/v1/auth/change-password")
async def change_password(
password_data: PasswordChange,
credentials: HTTPAuthorizationCredentials = Depends(security),
@@ -358,98 +361,116 @@ async def change_password(
)
@router.get(route_builder.build_base_route("profile", include_tenant_prefix=False), response_model=UserResponse)
@router.get("/api/v1/auth/me", response_model=UserResponse)
async def get_profile(
credentials: HTTPAuthorizationCredentials = Depends(security),
auth_service: EnhancedAuthService = Depends(get_auth_service)
current_user: Dict[str, Any] = Depends(get_current_user_dep),
db: AsyncSession = Depends(get_db)
):
"""Get user profile using repository pattern"""
"""Get user profile - works for JWT auth AND demo sessions"""
try:
if not credentials:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Authentication required"
)
# Verify token and get user_id
payload = await auth_service.verify_user_token(credentials.credentials)
user_id = payload.get("user_id")
user_id = current_user.get("user_id")
if not user_id:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Invalid token"
detail="Invalid user context"
)
# Get user profile using enhanced service
profile = await auth_service.get_user_profile(user_id)
if not profile:
# Fetch user from database
from app.repositories import UserRepository
user_repo = UserRepository(User, db)
user = await user_repo.get_by_id(user_id)
if not user:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="User profile not found"
)
return profile
return UserResponse(
id=str(user.id),
email=user.email,
full_name=user.full_name,
is_active=user.is_active,
is_verified=user.is_verified,
phone=user.phone,
language=user.language or "es",
timezone=user.timezone or "Europe/Madrid",
created_at=user.created_at,
last_login=user.last_login,
role=user.role,
tenant_id=current_user.get("tenant_id")
)
except HTTPException:
raise
except Exception as e:
logger.error("Get profile error using repository pattern", error=str(e))
logger.error("Get profile error", error=str(e))
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail="Failed to get profile"
)
@router.put(route_builder.build_base_route("profile", include_tenant_prefix=False), response_model=UserResponse)
@router.put("/api/v1/auth/me", response_model=UserResponse)
async def update_profile(
update_data: dict,
credentials: HTTPAuthorizationCredentials = Depends(security),
auth_service: EnhancedAuthService = Depends(get_auth_service)
current_user: Dict[str, Any] = Depends(get_current_user_dep),
db: AsyncSession = Depends(get_db)
):
"""Update user profile using repository pattern"""
"""Update user profile - works for JWT auth AND demo sessions"""
try:
if not credentials:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Authentication required"
)
# Verify token and get user_id
payload = await auth_service.verify_user_token(credentials.credentials)
user_id = payload.get("user_id")
user_id = current_user.get("user_id")
if not user_id:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Invalid token"
detail="Invalid user context"
)
# Update profile using enhanced service
updated_profile = await auth_service.update_user_profile(user_id, update_data)
if not updated_profile:
# Prepare update data - filter out read-only fields
from app.repositories import UserRepository
user_repo = UserRepository(User, db)
# Update user profile
updated_user = await user_repo.update(user_id, update_data)
if not updated_user:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="User not found"
)
logger.info("Profile updated using repository pattern",
logger.info("Profile updated",
user_id=user_id,
updated_fields=list(update_data.keys()))
return updated_profile
return UserResponse(
id=str(updated_user.id),
email=updated_user.email,
full_name=updated_user.full_name,
is_active=updated_user.is_active,
is_verified=updated_user.is_verified,
phone=updated_user.phone,
language=updated_user.language,
timezone=updated_user.timezone,
created_at=updated_user.created_at,
last_login=updated_user.last_login,
role=updated_user.role,
tenant_id=current_user.get("tenant_id")
)
except HTTPException:
raise
except Exception as e:
logger.error("Update profile error using repository pattern", error=str(e))
logger.error("Update profile error", error=str(e))
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail="Failed to update profile"
)
@router.post(route_builder.build_base_route("verify-email", include_tenant_prefix=False))
@router.post("/api/v1/auth/verify-email")
async def verify_email(
user_id: str,
verification_token: str,
@@ -473,7 +494,7 @@ async def verify_email(
)
@router.post(route_builder.build_base_route("reset-password", include_tenant_prefix=False))
@router.post("/api/v1/auth/reset-password")
async def reset_password(
reset_data: PasswordReset,
request: Request,
@@ -504,7 +525,7 @@ async def reset_password(
)
@router.get(route_builder.build_base_route("health", include_tenant_prefix=False))
@router.get("/api/v1/auth/health")
async def health_check():
"""Health check endpoint for enhanced auth service"""
return {