File size: 3,227 Bytes
cccf200
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
"""
Authentication API endpoints (register, login, logout).
"""
from fastapi import APIRouter, Depends, HTTPException, status, Request, Header
from sqlmodel import Session, select
from src.db.session import get_session
from src.models.user import UserCreate, UserLogin, UserResponse, User
from src.services.user_service import UserService
from src.core.security import create_access_token
from src.middleware.auth import get_current_user
from pydantic import BaseModel

router = APIRouter(prefix="/auth", tags=["auth"])


class TokenResponse(BaseModel):
    """Response model for token exchange."""
    access_token: str
    token_type: str
    user: dict


@router.post("/exchange-token", response_model=TokenResponse)
async def exchange_token(
    request: Request,
    session: Session = Depends(get_session),
    x_user_email: str = Header(None, alias="X-User-Email"),
    x_user_name: str = Header(None, alias="X-User-Name"),
    x_user_id: str = Header(None, alias="X-User-Id")
):
    """
    Exchange Better Auth session for JWT token.
    Called by frontend after Better Auth login.
    
    Better Auth should provide user info in headers:
    - X-User-Email: User's email
    - X-User-Name: User's name
    - X-User-Id: Better Auth user ID
    """
    # Try to get user info from headers first
    user_email = x_user_email
    user_name = x_user_name
    better_auth_id = x_user_id
    
    # If not in headers, try to get from Better Auth session cookie
    if not user_email:
        # Get Better Auth session from cookies
        session_cookie = request.cookies.get('better-auth.session_token')
        
        if not session_cookie:
            raise HTTPException(
                status_code=401, 
                detail="No session found. Please login first."
            )
        
        # In a real implementation, you would verify the session with Better Auth
        # For now, we'll require the headers to be sent from frontend
        raise HTTPException(
            status_code=400,
            detail="User information headers required (X-User-Email, X-User-Name)"
        )
    
    # Get or create user in backend DB
    query = select(User).where(User.email == user_email)
    user = session.exec(query).first()
    
    if not user:
        # Create new user from Better Auth data
        user = User(
            email=user_email,
            name=user_name or user_email.split('@')[0],
            is_active=True
        )
        session.add(user)
        session.commit()
        session.refresh(user)
    
    # Generate JWT token
    access_token = create_access_token(data={"sub": user.id})
    
    return TokenResponse(
        access_token=access_token,
        token_type="bearer",
        user={
            "id": user.id,
            "email": user.email,
            "name": user.name if hasattr(user, 'name') else user.email.split('@')[0] # Fallback if 'name' isn't set
        }
    )


@router.get("/verify-token")
async def verify_token(
    current_user: User = Depends(lambda: None)  # Will add proper dependency later
):
    """
    Verify JWT token is valid.
    Returns current user info.
    """
    return {"status": "valid", "message": "Token verification endpoint"}