use axum::{ Json, Router, extract::{Request, State}, middleware::{self, Next}, response::{IntoResponse, Response}, routing::method_routing::{get, post}, }; use const_str::concat; use http::StatusCode; use serde_json::json; pub(crate) use server_metadata::*; mod register_client; mod server_metadata; mod token; const BASE_PATH: &str = concat!(conduwuit_core::ROUTE_PREFIX, "/oauth2/"); const AUTH_CODE_PATH: &str = "grant/authorization_code"; const JWKS_URI_PATH: &str = "client/keys.json"; const CLIENT_REGISTER_PATH: &str = "client/register"; const TOKEN_REVOKE_PATH: &str = "client/revoke"; const TOKEN_PATH: &str = "grant/token"; const ACCOUNT_MANAGEMENT_PATH: &str = concat!(conduwuit_core::ROUTE_PREFIX, "/account/deeplink"); pub(crate) fn router(state: crate::State) -> Router { Router::new() .nest(BASE_PATH, oauth_router()) .route( "/.well-known/openid-configuration", get( // TODO(unspecced): used by old versions of the matrix-js-sdk async |State(services): State| { Json(authorization_server_metadata(&services).await) }, ), ) .layer(middleware::from_fn_with_state( state, async |State(state): State, request: Request, next: Next| -> Response { if state.config.oauth.compatibility_mode.oauth_available() { next.run(request).await } else { (StatusCode::NOT_FOUND, "OAuth is unavailable on this server").into_response() } }, )) } fn oauth_router() -> Router { Router::new() .route(concat!("/", CLIENT_REGISTER_PATH), post(register_client::register_client_route)) // TODO(unspecced): used by old versions of the matrix-js-sdk .route(concat!("/", JWKS_URI_PATH), get(async || Json(json!({"keys": []})))) .route(concat!("/", TOKEN_PATH), post(token::token_route)) .route(concat!("/", TOKEN_REVOKE_PATH), post(token::revoke_token_route)) }