//! HTTP handlers for authentication. Business rules live in `AuthService`.
use axum::Json;
use axum::extract::State;
use axum::http::StatusCode;
use crate::base::auth::AuthUser;
use crate::base::error::AppResult;
use crate::modules::auth::dto::auth::{LoginRequest, MeResponse, RegisterRequest, TokenResponse};
use crate::modules::auth::services::auth_service::AuthService;
/// `POST /auth/register` → 201 with a bearer token.
pub async fn register(
State(service): State<AuthService>,
Json(input): Json<RegisterRequest>,
) -> AppResult<(StatusCode, Json<TokenResponse>)> {
let session = service.register(input).await?;
Ok((StatusCode::CREATED, Json(session.into())))
}
/// `POST /auth/login` → a new bearer token.
pub async fn login(
State(service): State<AuthService>,
Json(input): Json<LoginRequest>,
) -> AppResult<Json<TokenResponse>> {
Ok(Json(service.login(input).await?.into()))
}
/// `POST /auth/logout` → revokes the token used for this request.
pub async fn logout(user: AuthUser, State(service): State<AuthService>) -> AppResult<StatusCode> {
service.logout(user.token_hash()).await?;
Ok(StatusCode::NO_CONTENT)
}
/// `GET /auth/me` → the authenticated user and their roles.
pub async fn me(user: AuthUser) -> Json<MeResponse> {
Json(MeResponse {
id: user.id,
name: user.name,
email: user.email,
roles: user.roles,
})
}