cortex-memory 0.3.1

Self-organizing graph memory for AI agents. Single binary, zero dependencies.
Documentation
use axum::{
    extract::Request,
    http::StatusCode,
    middleware::Next,
    response::{IntoResponse, Json, Response},
};

use super::JsonResponse;

/// Bearer token auth middleware. Skips `/health` and (by default) `/metrics`.
/// Short-circuits if auth is disabled.
pub async fn check(
    req: Request,
    next: Next,
    auth_enabled: bool,
    token: Option<String>,
    metrics_require_auth: bool,
) -> Response {
    if !auth_enabled {
        return next.run(req).await;
    }

    let path = req.uri().path();
    if path == "/health" {
        return next.run(req).await;
    }
    if path == "/metrics" && !metrics_require_auth {
        return next.run(req).await;
    }

    let expected = match token.as_deref() {
        Some(t) => t,
        None => {
            return (
                StatusCode::INTERNAL_SERVER_ERROR,
                Json(JsonResponse::<()>::err(
                    "Auth enabled but no token configured",
                )),
            )
                .into_response();
        }
    };

    match req.headers().get("authorization") {
        Some(value) => {
            let value = value.to_str().unwrap_or("");
            if value.starts_with("Bearer ") && &value[7..] == expected {
                next.run(req).await
            } else {
                (
                    StatusCode::UNAUTHORIZED,
                    Json(JsonResponse::<()>::err("Invalid token")),
                )
                    .into_response()
            }
        }
        None => (
            StatusCode::UNAUTHORIZED,
            Json(JsonResponse::<()>::err("Missing Authorization header")),
        )
            .into_response(),
    }
}