use axum::{Json, http::StatusCode, response::IntoResponse};
use serde_json::json;
fn get_base_url() -> String {
std::env::var("BASE_URL").unwrap_or_else(|_| "http://localhost:3000".to_string())
}
fn common_metadata_fields(base_url: &str) -> serde_json::Value {
json!({
"issuer": base_url,
"registration_endpoint": format!("{}/oauth/register", base_url),
"authorization_endpoint": format!("{}/oauth/authorize", base_url),
"token_endpoint": format!("{}/oauth/token", base_url),
"response_types_supported": ["code"],
"grant_types_supported": ["authorization_code", "refresh_token"],
"code_challenge_methods_supported": ["S256"],
"scopes_supported": [
"mcp:read",
"mcp:write",
"mcp:tools",
"mcp:resources",
"mcp:prompts"
],
"token_endpoint_auth_methods_supported": ["client_secret_post", "none", "private_key_jwt"],
"resource_indicators_supported": true,
"client_id_metadata_document_supported": true,
})
}
pub async fn authorization_server_metadata() -> impl IntoResponse {
let base_url = get_base_url();
let metadata = common_metadata_fields(&base_url);
(StatusCode::OK, Json(metadata)).into_response()
}
pub async fn openid_configuration() -> impl IntoResponse {
let base_url = get_base_url();
let mut metadata = common_metadata_fields(&base_url);
if let Some(obj) = metadata.as_object_mut() {
obj.insert(
"jwks_uri".to_string(),
json!(format!("{}/oauth/jwks", base_url)),
);
obj.insert("subject_types_supported".to_string(), json!(["public"]));
obj.insert(
"id_token_signing_alg_values_supported".to_string(),
json!(["RS256"]),
);
obj.insert(
"token_endpoint_auth_signing_alg_values_supported".to_string(),
json!(["RS256"]),
);
obj.insert(
"claims_supported".to_string(),
json!(["sub", "iss", "aud", "exp", "iat"]),
);
}
(StatusCode::OK, Json(metadata)).into_response()
}