File size: 4,300 Bytes
adb1c6b
 
 
 
 
1a3a466
adb1c6b
 
 
1a3a466
 
adb1c6b
 
 
 
 
 
 
1a3a466
adb1c6b
 
 
 
1a3a466
adb1c6b
 
 
 
 
1a3a466
adb1c6b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1a3a466
adb1c6b
 
 
 
1a3a466
adb1c6b
 
 
 
 
1a3a466
adb1c6b
 
1a3a466
adb1c6b
 
1a3a466
adb1c6b
 
 
 
1a3a466
adb1c6b
 
 
 
 
 
 
 
 
 
1a3a466
adb1c6b
 
 
 
 
 
1a3a466
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
from app.services.merchant_services import (
    generate_login_otp_service,
    login_service,
    refresh_token_service,
    logout_service,
    get_user_details_service,
)
from fastapi.security import OAuth2PasswordRequestForm
from fastapi import APIRouter, HTTPException, Query, Depends, status, Body
from app.models.merchant import LoginOtpRequest, RefreshTokenRequest, MerchantDetailsResponse
from app.utils.auth_utils import verify_token
import logging

# Initialize router and logger
router = APIRouter(prefix="/merchant")
logger = logging.getLogger(__name__)

@router.post("/login/otp")
async def generate_login_otp(payload: LoginOtpRequest):
    """
    Generate and send login OTP to the provided email or mobile number.

    Args:
        payload (GenerateLoginOtpRequest): The request payload containing the identifier.

    Returns:
        dict: Confirmation message indicating OTP has been sent.
    """
    try:
        result = await generate_login_otp_service(payload.identifier)
        return result
    except HTTPException as e:
        logger.error("Failed to generate login OTP: %s", e.detail)
        raise e
    except Exception as e:
        logger.error("Unexpected error while generating login OTP: %s", e)
        raise HTTPException(status_code=500, detail="Failed to generate login OTP") from e


@router.post("/login")
async def login(user: OAuth2PasswordRequestForm = Depends()):
    """
    Login using email/mobile and OTP.

    Args:
        user (OAuth2PasswordRequestForm): Contains username (email/mobile) and password (OTP).

    Returns:
        dict: Access and refresh tokens.
    """
    try:
        result = await login_service(user.username, user.password)
        return result
    except HTTPException as e:
        logger.error("Login failed: %s", e.detail)
        raise e
    except Exception as e:
        logger.error("Unexpected error during login: %s", e)
        raise HTTPException(status_code=500, detail="Login failed") from e


@router.post("/token/refresh")
async def refresh_token(payload: RefreshTokenRequest):
    """
    Refresh access and refresh tokens.

    Args:
        payload (RefreshTokenRequest): The request payload containing the identifier and refresh token.

    Returns:
        dict: New access and refresh tokens.
    """
    try:
        result = await refresh_token_service(payload.identifier, payload.refresh_token)
        return result
    except HTTPException as e:
        logger.error("Failed to refresh token for identifier %s: %s", payload.identifier, e.detail)
        raise e
    except Exception as e:
        logger.error("Unexpected error while refreshing token for identifier %s: %s", payload.identifier, e)
        raise HTTPException(status_code=500, detail="Failed to refresh token") from e


@router.post("/logout")
async def logout(payload: LoginOtpRequest):
    """
    Logout the user by invalidating access and refresh tokens.

    Args:
        identifier (str): Email or mobile number.

    Returns:
        dict: Confirmation message.
    """
    try:
        result = await logout_service(payload.identifier)
        return result
    except HTTPException as e:
        logger.error("Failed to logout: %s", e.detail)
        raise e
    except Exception as e:
        logger.error("Unexpected error during logout: %s", e)
        raise HTTPException(status_code=500, detail="Failed to logout") from e

@router.get("/user/details", response_model=MerchantDetailsResponse, dependencies=[Depends(verify_token)])
async def get_user_details(identifier: str = Query(..., description="Email or Mobile number")):
    """
    Get user details using the identifier (email or mobile).

    Args:
        identifier (str): Email or mobile number.

    Returns:
        MerchantDetailsResponse: User details from the database.
    """
    try:
        result = await get_user_details_service(identifier)
        return result
    except HTTPException as e:
        logger.error("Failed to retrieve user details for identifier %s: %s", identifier, e.detail)
        raise e
    except Exception as e:
        logger.error("Unexpected error while retrieving user details for identifier %s: %s", identifier, e)
        raise HTTPException(status_code=500, detail="Failed to retrieve user details") from e