use std::sync::Arc;
use axum::extract::State;
use axum::http::HeaderMap;
use axum::routing::get;
use axum::{Json, Router};
use cf_access::Validator;
use serde_json::{json, Value};
use tokio::net::TcpListener;
#[tokio::main]
async fn main() {
#[cfg(feature = "env")]
let validator = Validator::from_env().unwrap();
#[cfg(not(feature = "env"))]
let validator = Validator::new("team_name", "audience");
let app = Router::new()
.route("/", get(handler))
.with_state(Arc::new(validator));
let port = 3000;
let listener = TcpListener::bind(format!("0.0.0.0:{port}")).await.unwrap();
println!("Listening on port {port}");
axum::serve(listener, app).await.unwrap();
}
async fn handler(validator: State<Arc<Validator>>, headers: HeaderMap) -> Json<Value> {
let Some(jwt) = headers.get("cf-access-jwt-assertion") else {
return Json(json!({ "error": "JWT not found" }));
};
let Ok(jwt) = jwt.to_str() else {
return Json(json!({ "error": "JWT is invalid" }));
};
match validator.validate(jwt).await {
Ok(token) => Json(json!({ "result": token, "jwt": jwt })),
Err(error) => Json(json!({ "error": error.to_string() })),
}
}