"""Аутентификация — регистрация, логин, JWT-токены""" from fastapi import APIRouter, Depends, HTTPException from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy import select import uuid from datetime import datetime, timedelta from ...core.database import async_session_factory, User, UserRole from ...utils.auth import create_access_token, create_refresh_token, verify_password, hash_password from pydantic import BaseModel router = APIRouter() class RegisterRequest(BaseModel): email: str password: str role: str = "client" # client | master first_name: str last_name: str phone: str | None = None class LoginRequest(BaseModel): email: str password: str @router.post("/register") async def register(req: RegisterRequest, session: AsyncSession = Depends(async_session_factory)): """Регистрация пользователя.""" existing = await session.execute(select(User).where(User.email == req.email)) if existing.scalar_one_or_none(): raise HTTPException(409, "Email уже зарегистрирован") user = User( email=req.email, password_hash=hash_password(req.password), role=UserRole(req.role), first_name=req.first_name, last_name=req.last_name, phone=req.phone, ) session.add(user) await session.commit() access_token = create_access_token(str(user.id)) refresh_token = create_refresh_token(str(user.id)) return { "user_id": str(user.id), "email": user.email, "role": user.role.value, "access_token": access_token, "refresh_token": refresh_token, } @router.post("/login") async def login(req: LoginRequest, session: AsyncSession = Depends(async_session_factory)): """Логин.""" result = await session.execute(select(User).where(User.email == req.email)) user = result.scalar_one_or_none() if not user or not verify_password(req.password, user.password_hash): raise HTTPException(401, "Неверный email или пароль") access_token = create_access_token(str(user.id)) refresh_token = create_refresh_token(str(user.id)) return { "user_id": str(user.id), "email": user.email, "role": user.role.value, "access_token": access_token, "refresh_token": refresh_token, } @router.post("/refresh") async def refresh_token(req: dict, session: AsyncSession = Depends(async_session_factory)): """Обновить токен.""" from ...utils.auth import decode_refresh_token user_id = decode_refresh_token(req["refresh_token"]) access_token = create_access_token(user_id) return {"access_token": access_token} @router.get("/me") async def get_me(user=Depends(get_current_user), session: AsyncSession = Depends(async_session_factory)): """Получить данные текущего пользователя.""" user = await session.get(User, uuid.UUID(str(user.id))) return { "id": str(user.id), "email": user.email, "first_name": user.first_name, "last_name": user.last_name, "phone": user.phone, "role": user.role.value, "avatar_url": user.avatar_url, }