from typing import Annotated from fastapi import APIRouter, Depends from sqlalchemy.orm import Session from app.core.database import get_db from app.core.dependencies import get_current_user from app.core.security import create_access_token from app.modules.auth import service from app.modules.auth.models import User from app.modules.auth.schemas import ( AuthStatus, DeviceKeyCreate, DeviceKeyCreated, DeviceKeyRead, LoginRequest, SetupRequest, TokenResponse, UserRead, UserUpdate, ) router = APIRouter(prefix="/auth", tags=["auth"]) DbDep = Annotated[Session, Depends(get_db)] UserDep = Annotated[User, Depends(get_current_user)] def _token_response(user: User) -> TokenResponse: return TokenResponse( access_token=create_access_token(user.id), user=UserRead.model_validate(user), ) @router.get("/status", response_model=AuthStatus) def auth_status(db: DbDep) -> AuthStatus: required = service.setup_required(db) return AuthStatus(setup_required=required, needs_setup=required) @router.post("/setup", response_model=TokenResponse, status_code=201) def setup(payload: SetupRequest, db: DbDep) -> TokenResponse: user = service.create_first_user(db, payload) return _token_response(user) @router.post("/login", response_model=TokenResponse) def login(payload: LoginRequest, db: DbDep) -> TokenResponse: user = service.authenticate(db, payload.email, payload.password) return _token_response(user) @router.get("/me", response_model=UserRead) def me(user: UserDep) -> User: return user @router.patch("/me", response_model=UserRead) def update_me(payload: UserUpdate, db: DbDep, user: UserDep) -> User: return service.update_me(db, user, payload) @router.get("/device-keys", response_model=list[DeviceKeyRead]) def list_device_keys(db: DbDep, user: UserDep) -> list[DeviceKeyRead]: return service.list_device_keys(db, user.id) @router.post("/device-keys", response_model=DeviceKeyCreated, status_code=201) def create_device_key( payload: DeviceKeyCreate, db: DbDep, user: UserDep ) -> DeviceKeyCreated: key, plaintext = service.create_device_key(db, user.id, payload) read = DeviceKeyRead.model_validate(key) return DeviceKeyCreated(**read.model_dump(), key=plaintext) @router.delete("/device-keys/{key_id}", status_code=204) def revoke_device_key(key_id: int, db: DbDep, user: UserDep) -> None: service.revoke_device_key(db, user.id, key_id)