File size: 5,108 Bytes
c1d7a04
b9669e1
 
 
 
 
656da92
b9669e1
c1d7a04
b9669e1
 
 
c1d7a04
5c780f1
 
c1d7a04
 
 
 
 
 
 
b9669e1
 
 
 
656da92
 
 
 
b9669e1
c1d7a04
b9669e1
 
656da92
b9669e1
 
 
 
66536b4
 
 
 
 
 
c1d7a04
66536b4
 
c1d7a04
 
66536b4
 
 
 
 
 
 
c1d7a04
66536b4
b9669e1
 
656da92
 
 
 
 
5c780f1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
656da92
c1d7a04
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5c780f1
 
 
 
 
 
 
c1d7a04
 
 
 
 
 
 
 
 
1bffbb8
66536b4
5c780f1
 
c1d7a04
 
 
 
 
 
 
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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
import uuid
from src.core.database import get_async_session
from fastapi import APIRouter, Depends, HTTPException, status
from jose import jwt, JWTError
from fastapi import APIRouter, Depends, HTTPException
from sqlmodel import Session
from sqlmodel.ext.asyncio.session import AsyncSession
from src.auth.service import (
    create_user,
    verify_email,
    login_user,
)
from src.auth.utils import get_current_user
from src.core.models import Users, Roles, UserTeamsRole
from sqlmodel import select
from src.core.config import settings
from fastapi.responses import RedirectResponse
from .schemas import SignUpRequest, LoginRequest, BaseResponse, SendVerificationRequest
from fastapi.security import OAuth2PasswordRequestForm
from src.auth.utils import create_access_token
from jose import jwt, JWTError


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


@router.post("/signup", response_model=BaseResponse)
async def signup(
    payload: SignUpRequest, session: AsyncSession = Depends(get_async_session)
):
    try:
        response = await create_user(
            session, payload.name, payload.email, payload.password
        )
        return {"code": 200, "data": response}
    except ValueError as e:
        raise HTTPException(status_code=400, detail=str(e))


# @router.post("/send-verification", response_model=BaseResponse)
# async def send_verification(
#     payload: SendVerificationRequest, session: AsyncSession = Depends(get_async_session)
# ):
#     if not payload.email:
#         raise HTTPException(status_code=400, detail="Email is required")

#     response = await send_verification_link(session, payload.email)
#     return {"code": 200, "data": response}


# @router.get("/verify-email", response_model=BaseResponse)
# async def verify_email_route(
#     token: str, session: AsyncSession = Depends(get_async_session)
# ):
#     response = await verify_email(session, token)
#     access_token = response["access_token"]
#     redirect_url = f"yuvabe://verified?token={access_token}"

#     return RedirectResponse(url=redirect_url)


@router.post("/login", response_model=BaseResponse)
async def login(
    payload: LoginRequest, session: AsyncSession = Depends(get_async_session)
):
    response = await login_user(session, payload.email, payload.password)

    user_id = response["user"]["id"]

    # 🔥 Fetch User Role
    result = await session.exec(
        select(Roles)
        .join(UserTeamsRole, UserTeamsRole.role_id == Roles.id)
        .where(UserTeamsRole.user_id == uuid.UUID(user_id))
    )

    role_obj = result.first()
    role_name = role_obj.name if role_obj else "Member"

    response["user"]["role"] = (role_name or "member").lower()

    return {"code": 200, "data": response}


@router.post("/refresh", response_model=BaseResponse)
async def refresh_token(request: dict):
    """Generate new access token using refresh token"""
    refresh_token = request.get("refresh_token")
    if not refresh_token:
        raise HTTPException(status_code=400, detail="Refresh token is required")

    try:
        payload = jwt.decode(
            refresh_token, settings.SECRET_KEY, algorithms=[settings.JWT_ALGORITHM]
        )
        if payload.get("type") != "refresh":
            raise HTTPException(status_code=400, detail="Invalid refresh token")

        user_data = {
            "sub": payload["sub"],
            "name": payload.get("name"),
            "email": payload.get("email"),
        }
        new_access_token = create_access_token(data=user_data)
        return {"code": 200, "data": {"access_token": new_access_token}}

    except JWTError:
        raise HTTPException(status_code=401, detail="Invalid or expired refresh token")


@router.get("/home", response_model=BaseResponse)
async def get_home(
    user_id: str = Depends(get_current_user),
    session: AsyncSession = Depends(get_async_session),
):
    """
    Protected home endpoint. Requires a valid access token (Bearer).
    """
    user = await session.get(Users, uuid.UUID(user_id))
    if not user:
        raise HTTPException(status_code=404, detail="User not found")

    role_join = await session.exec(
        select(Roles.name)
        .join(UserTeamsRole, UserTeamsRole.role_id == Roles.id)
        .where(UserTeamsRole.user_id == uuid.UUID(user_id))
    )
    user_role = role_join.first() or "Member"

    # Example payload — replace with your real app data
    return {
        "code": 200,
        "data": {
            "message": f"Welcome to Home, {user.user_name}!",
            "user": {
                "id": str(user.id),
                "name": user.user_name,
                "email": user.email_id,
                "is_verified": user.is_verified,
                "dob": user.dob.isoformat() if user.dob else None,
                "profile_picture": user.profile_picture,
                "role": user_role.lower(),
            },
            "home_data": {
                "announcements": ["Welcome!", "New protocol released"],
                "timestamp": user.created_at.isoformat() if user.created_at else None,
            },
        },
    }