use axum::{ extract::FromRequestParts, http::{request::Parts, StatusCode}, }; use std::sync::Arc; use uuid::Uuid; use super::jwt::{verify_token, Claims}; use crate::config::Config; pub struct AuthUser { pub user_id: Uuid, pub username: String, } impl FromRequestParts for AuthUser where S: Send + Sync, { type Rejection = (StatusCode, &'static str); async fn from_request_parts(parts: &mut Parts, _state: &S) -> Result { let auth_header = parts .headers .get("Authorization") .and_then(|value| value.to_str().ok()) .ok_or((StatusCode::UNAUTHORIZED, "Missing authorization header"))?; let token = auth_header.strip_prefix("Bearer ").ok_or(( StatusCode::UNAUTHORIZED, "Invalid authorization header format", ))?; let secret = parts .extensions .get::>() .map(|c| c.jwt_secret.clone()) .or_else(|| std::env::var("JWT_SECRET").ok()) .unwrap_or_else(|| "dev-secret-change-in-production".to_string()); let claims: Claims = verify_token(token, &secret) .map_err(|_| (StatusCode::UNAUTHORIZED, "Invalid token"))?; Ok(AuthUser { user_id: claims.sub, username: claims.username, }) } }