diff options
| author | l3wdfut4pwr <l3wdfut4pwr@gmail.com> | 2026-04-27 13:45:09 +0300 |
|---|---|---|
| committer | l3wdfut4pwr <l3wdfut4pwr@gmail.com> | 2026-04-27 13:45:09 +0300 |
| commit | 4848a9e9394b283022085a6305d00f94b11cd703 (patch) | |
| tree | d7ba45885f110e8ded4af20bc98b9f88f75b1f4a /app/routes/auth/register.py | |
| parent | f1842be3bfabe7850d33662da2da377676144c48 (diff) | |
add username change and logout
Diffstat (limited to 'app/routes/auth/register.py')
| -rw-r--r-- | app/routes/auth/register.py | 119 |
1 files changed, 119 insertions, 0 deletions
diff --git a/app/routes/auth/register.py b/app/routes/auth/register.py new file mode 100644 index 0000000..f0b36ed --- /dev/null +++ b/app/routes/auth/register.py @@ -0,0 +1,119 @@ +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 |
