from fastapi import APIRouter, Depends, HTTPException, status from sqlalchemy.orm import Session, selectinload from app.database import get_db from app.models.user import User from app.models.user_profile import UserProfile from app.schemas.user import LoginRequest, LoginResponse, UserCreate, UserResponse from app.security import create_access_token, hash_password, verify_password router = APIRouter(prefix="/auth", tags=["auth"]) @router.post("/login", response_model=LoginResponse) def login(data: LoginRequest, db: Session = Depends(get_db)): user = db.query(User).options(selectinload(User.profile)).filter( (User.email == data.login) | (User.username == data.login), User.deleted_at.is_(None), ).first() if not user or not verify_password(data.password, user.password): raise HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail={"message": "Kredensial autentikasi tidak ada atau tidak valid."}, ) if user.email_verified_at is None: raise HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail={"message": "Email belum diverifikasi. Silakan verifikasi email terlebih dahulu."}, ) access_token = create_access_token({"sub": user.id}) return LoginResponse( access_token=access_token, user=user, ) @router.post("/register", response_model=UserResponse, status_code=status.HTTP_201_CREATED) def register(data: UserCreate, db: Session = Depends(get_db)): existing = db.query(User).filter( (User.email == data.email) | (User.username == data.username) ).first() if existing: raise HTTPException( status_code=status.HTTP_409_CONFLICT, detail={"message": "Email atau username sudah terdaftar."}, ) user = User( email=data.email, username=data.username, password=hash_password(data.password), ) db.add(user) db.flush() try: profile = UserProfile( user_id=user.id, full_name=data.full_name, phone=data.phone, timezone=data.timezone, ) db.add(profile) db.commit() except: db.rollback() raise db.refresh(user) return user