use axum::{
extract::{Request, State},
http::{header, StatusCode},
middleware::Next,
response::Response,
Json,
};
use serde_json::json;
use crate::{state::AppState, util::constant_time_eq};
const BEARER_PREFIX: &str = "Bearer ";
pub async fn require_api_key(
State(state): State<AppState>,
request: Request,
next: Next,
) -> Result<Response, (StatusCode, Json<serde_json::Value>)> {
let provided_key = request
.headers()
.get(header::AUTHORIZATION)
.and_then(|header_value| header_value.to_str().ok())
.and_then(|header_str| header_str.strip_prefix(BEARER_PREFIX));
let authorised = provided_key
.map(|key| constant_time_eq(key.as_bytes(), state.config.server.api_key.as_bytes()))
.unwrap_or(false);
if authorised {
Ok(next.run(request).await)
} else {
Err((
StatusCode::UNAUTHORIZED,
Json(json!({ "error": "missing or invalid API key" })),
))
}
}