use axum::extract::State; use axum::http::HeaderMap; use crate::error::AuthError; use crate::features::AuthService; use export::auth::logout::{LogoutCmd, LogoutResp}; use export::data::{AppRequest, AppRequestData, AppResponseData}; #[utoipa::path( post, path = "/auth/logout", tag = "auth", request_body = AppRequestData, responses( (status = 200, description = "Refresh token revoked.", body = AppResponseData), (status = 401, description = "Invalid or expired refresh token.", body = super::openapi::ErrorBody), ), )] pub(crate) async fn handler( State(svc): State, headers: HeaderMap, cmd: AppRequest, ) -> Result, AuthError> { let access_token = headers .get(axum::http::header::AUTHORIZATION) .and_then(|v| v.to_str().ok()) .and_then(|v| { v.strip_prefix("Bearer ") .or_else(|| v.strip_prefix("bearer ")) }) .map(|s| s.to_string()); let resp = svc.logout(cmd.into_inner(), access_token).await?; Ok(AppResponseData::ok(resp)) }