| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108 |
- """
- Authentication endpoints: register, login, refresh, logout.
- """
- from typing import Annotated
- from fastapi import APIRouter, Depends
- from fastapi.security import OAuth2PasswordRequestForm
- from sqlalchemy.ext.asyncio import AsyncSession
- from app.api.deps import get_current_user
- from app.core.database import get_db
- from app.models.user import User
- from app.schemas.auth import (
- AuthResponse,
- LogoutRequest,
- RefreshRequest,
- RegisterRequest,
- UserInfo,
- )
- from app.services import auth_service
- router = APIRouter(prefix="/auth", tags=["Authentication"])
- @router.post("/register", status_code=201)
- async def register(
- data: RegisterRequest,
- db: Annotated[AsyncSession, Depends(get_db)],
- ):
- """
- Register new user with organization.
- Creates organization (status=pending) and user (role=owner).
- Admin must activate the organization before user can access products.
- """
- return await auth_service.register_user(
- db=db,
- email=data.email,
- password=data.password,
- full_name=data.full_name,
- phone=data.phone,
- organization_name=data.organization_name,
- )
- @router.post("/login", response_model=AuthResponse)
- async def login(
- form_data: Annotated[OAuth2PasswordRequestForm, Depends()],
- db: Annotated[AsyncSession, Depends(get_db)],
- ):
- """
- Authenticate user and return JWT tokens.
- Returns:
- - access_token: Short-lived token for API access (15 min)
- - refresh_token: Long-lived token for refreshing access token (30 days)
- - user: User information
- - organization: Organization information (if applicable)
- """
- return await auth_service.login_user(
- db=db,
- email=form_data.username,
- password=form_data.password,
- )
- @router.post("/refresh", response_model=AuthResponse)
- async def refresh(
- data: RefreshRequest,
- db: Annotated[AsyncSession, Depends(get_db)],
- ):
- """
- Refresh access token using refresh token.
- Returns new access_token and refresh_token.
- Old refresh_token is revoked.
- """
- return await auth_service.refresh_access_token(
- db=db,
- refresh_token_str=data.refresh_token,
- )
- @router.post("/logout")
- async def logout(
- data: LogoutRequest,
- db: Annotated[AsyncSession, Depends(get_db)],
- ):
- """
- Logout user by revoking refresh token.
- """
- return await auth_service.logout_user(
- db=db,
- refresh_token_str=data.refresh_token,
- )
- @router.get("/me", response_model=UserInfo)
- async def get_me(
- current_user: Annotated[User, Depends(get_current_user)],
- ):
- """
- Get current user information.
- Requires: Valid access token in Authorization header.
- """
- return UserInfo.model_validate(current_user)
|