Improve the frontend modals
This commit is contained in:
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user