Clear project — starting fresh from spec

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Dianaka123
2026-02-24 14:36:47 +03:00
parent 6fe452d4dc
commit 9eb68695e9
91 changed files with 310 additions and 13106 deletions

View File

@@ -1,77 +0,0 @@
from fastapi import APIRouter, Depends, HTTPException, status
from sqlalchemy.ext.asyncio import AsyncSession
from app.crud import crud_refresh_token, crud_user
from app.database import get_db
from app.dependencies import get_current_user
from app.models.user import User
from app.schemas.auth import LoginRequest, RefreshRequest, RegisterRequest, TokenResponse, UserOut
from app.services.auth_service import (
create_access_token,
create_refresh_token,
hash_token,
verify_password,
)
router = APIRouter(prefix="/auth", tags=["auth"])
@router.post("/register", response_model=TokenResponse, status_code=status.HTTP_201_CREATED)
async def register(body: RegisterRequest, db: AsyncSession = Depends(get_db)):
if await crud_user.get_by_email(db, body.email):
raise HTTPException(
status_code=status.HTTP_409_CONFLICT, detail="Email already registered"
)
user = await crud_user.create(
db,
email=body.email,
password=body.password,
full_name=body.full_name,
phone=body.phone,
)
return await _issue_tokens(db, user)
@router.post("/login", response_model=TokenResponse)
async def login(body: LoginRequest, db: AsyncSession = Depends(get_db)):
user = await crud_user.get_by_email(db, body.email)
if not user or not verify_password(body.password, user.hashed_password):
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid credentials"
)
return await _issue_tokens(db, user)
@router.post("/refresh", response_model=TokenResponse)
async def refresh(body: RefreshRequest, db: AsyncSession = Depends(get_db)):
hashed = hash_token(body.refresh_token)
rt = await crud_refresh_token.get_by_hash(db, hashed)
if not rt or not crud_refresh_token.is_valid(rt):
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid or expired refresh token"
)
await crud_refresh_token.revoke(db, rt)
user = await crud_user.get(db, rt.user_id)
if not user:
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED)
return await _issue_tokens(db, user)
@router.post("/logout", status_code=status.HTTP_204_NO_CONTENT)
async def logout(body: RefreshRequest, db: AsyncSession = Depends(get_db)):
hashed = hash_token(body.refresh_token)
rt = await crud_refresh_token.get_by_hash(db, hashed)
if rt:
await crud_refresh_token.revoke(db, rt)
@router.get("/me", response_model=UserOut)
async def me(user: User = Depends(get_current_user)):
return user
async def _issue_tokens(db: AsyncSession, user: User) -> TokenResponse:
access = create_access_token(str(user.id), user.role, user.status)
raw_rt, hashed_rt, expires_at = create_refresh_token()
await crud_refresh_token.create(db, user.id, hashed_rt, expires_at)
return TokenResponse(access_token=access, refresh_token=raw_rt)