import re from typing import Optional from fastapi import APIRouter, Depends, HTTPException, Response from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy.future import select from app.auth.jwt import create_access_token, create_refresh_token from app.models.integrations import UserIntegration from app.models.profile import Profile from app.models.user import User from app.schemas.user import UserCreate, UserRead from app.utils.db import get_async_session from app.utils.hash_cfg import hash_password from app.utils.logger_cfg import logger router = APIRouter(tags=["auth"]) @router.post("/register", response_model=UserRead) async def register_user( user: UserCreate, response: Response, session: AsyncSession = Depends(get_async_session), ): logger.debug("Register request received") email: Optional[str] = user.email.strip() if user.email else None logger.debug("Normalized email value: {}", email) logger.info( "Registration attempt | username={} email={}", user.username, email ) if not ( re.search(r"[A-Za-z]", user.password) and re.search(r"\d", user.password) and re.search(r"[^\w\s]", user.password) ): logger.warning( "Registration failed | password complexity requirement not met | username={}", user.username, ) raise HTTPException( status_code=400, detail={ "field": "password", "message": "Попробуйте сочетание букв, цифр и символов.", }, ) result = await session.execute( select(User).where(User.username == user.username) ) if result.scalars().first(): logger.warning( "Registration failed | username already exists | username={}", user.username, ) raise HTTPException( status_code=400, detail={"field": "username", "message": "Никнейм уже занят."}, ) if email: result = await session.execute(select(User).where(User.email == email)) if result.scalars().first(): logger.warning( "Registration failed | email already exists | email={}", email ) raise HTTPException( status_code=400, detail={"field": "email", "message": "Адрес уже занят."}, ) hashed_password = hash_password(user.password) new_user = User( username=user.username, email=email, password=hashed_password, profile=Profile(), integrations=UserIntegration(), ) session.add(new_user) await session.commit() await session.refresh(new_user, ["profile", "integrations"]) logger.success( "User successfully registered | id={} username={} email={}", new_user.id, new_user.username, new_user.email, ) access_token = create_access_token( {"sub": str(new_user.id), "token_version": new_user.token_version} ) refresh_token = create_refresh_token( {"sub": str(new_user.id), "token_version": new_user.token_version} ) response.set_cookie( key="access_token", value=access_token, httponly=True, secure=False, samesite="lax", max_age=60 * 60, ) response.set_cookie( key="refresh_token", value=refresh_token, httponly=True, secure=False, samesite="lax", max_age=30 * 24 * 60 * 60, ) return new_user