from typing import Optional from sqlalchemy.ext.asyncio import AsyncSession from src.core.security import create_access_token, create_refresh_token, verify_token from src.domain.schemas import Token from src.repository.user_repository import UserRepository class AuthService: def __init__(self, db: AsyncSession): self.db = db self.user_repo = UserRepository(db) async def authenticate_user(self, username: str, password: str) -> Optional[Token]: user = await self.user_repo.authenticate(username, password) if not user or not user.is_active: return None access_token = create_access_token(data={"sub": user.username}) refresh_token = create_refresh_token(data={"sub": user.username}) return Token( access_token=access_token, refresh_token=refresh_token, token_type="bearer", ) async def authenticate_user_via_email(self, email: str) -> Optional[Token]: user = await self.user_repo.authenticate_via_email(email) if not user or not user.is_active: return None access_token = create_access_token(data={"sub": user.email}) refresh_token = create_refresh_token(data={"sub": user.email}) return Token( access_token=access_token, refresh_token=refresh_token, token_type="bearer", ) async def refresh_token(self, refresh_token: str) -> Optional[Token]: payload = verify_token(refresh_token) if payload is None: return None username: str | None = payload.get("sub") if username is None: return None user = await self.user_repo.get_by_username(username) if not user: return None access_token = create_access_token(data={"sub": user.username}) new_refresh_token = create_refresh_token(data={"sub": user.username}) return Token( access_token=access_token, refresh_token=new_refresh_token, token_type="bearer", )