use crate::common::config::env_loader;
use axum::{extract::Request, http::StatusCode, middleware::Next, response::Response};
use fancy_log::{LogLevel, log};
pub async fn require_access_token(req: Request, next: Next) -> Result<Response, StatusCode> {
let expected_token = env_loader::get_env("ACCESS_TOKEN", String::new());
if expected_token.is_empty() {
log(
LogLevel::Error,
"✗ BUG: Auth middleware called but ACCESS_TOKEN not set",
);
return Err(StatusCode::INTERNAL_SERVER_ERROR);
}
let auth_header = req
.headers()
.get("Authorization")
.and_then(|v| v.to_str().ok());
match auth_header {
Some(token) if token == format!("Bearer {expected_token}") => {
Ok(next.run(req).await)
}
Some(_) => {
log(
LogLevel::Warn,
"⚠ Unauthorized API access attempt (invalid token)",
);
Err(StatusCode::UNAUTHORIZED)
}
None => {
log(
LogLevel::Warn,
"⚠ Unauthorized API access attempt (missing Authorization header)",
);
Err(StatusCode::UNAUTHORIZED)
}
}
}
pub fn validate_access_token() -> Result<Option<String>, String> {
let token = env_loader::get_env("ACCESS_TOKEN", String::new());
if token.is_empty() {
return Ok(None);
}
let len = token.len();
if len < 16 {
return Err(format!(
"ACCESS_TOKEN too short ({len} chars, requires 16-128 chars)"
));
}
if len > 128 {
return Err(format!(
"ACCESS_TOKEN too long ({len} chars, requires 16-128 chars)"
));
}
Ok(Some(token))
}