mod acl;
mod auth;
pub(crate) mod did_manage;
mod didcomm;
pub(crate) mod domain;
pub mod health;
mod identity;
mod passkey;
mod proxy;
mod registry;
pub mod server_info;
pub(crate) mod stats_sync;
pub mod task_consent;
mod trust_tasks;
use axum::Router;
use axum::extract::DefaultBodyLimit;
use axum::routing::{any, get, post, put};
use did_hosting_common::did_hosting_tasks::*;
use did_hosting_common::server::trust_task::TrustTaskRouter;
use crate::server::AppState;
pub const TRUST_TASKS_BODY_LIMIT_BYTES: usize = 64 * 1024;
#[allow(deprecated)]
pub fn router_without_fallback() -> Router<AppState> {
let control: Router<AppState> = TrustTaskRouter::new()
.route_with_task_permissive(
"/registry",
get(registry::list).post(registry::register),
(*TASK_REGISTRY_LIST_1_0).clone(),
)
.route_with_task_permissive(
"/registry/{instance_id}",
get(registry::get).delete(registry::deregister),
(*TASK_REGISTRY_GET_1_0).clone(),
)
.route_with_task_permissive(
"/registry/{instance_id}/health",
post(registry::health_check),
(*TASK_REGISTRY_HEALTH_1_0).clone(),
)
.route_with_task_permissive(
"/registry/{instance_id}/domains/{domain}/assign",
post(registry::assign_domain_to_server),
(*TASK_DOMAIN_ASSIGN_0_1).clone(),
)
.route_with_task_permissive(
"/registry/{instance_id}/domains/{domain}/unassign",
post(registry::unassign_domain_from_server),
(*TASK_DOMAIN_UNASSIGN_0_1).clone(),
)
.route_with_task_permissive(
"/registry/{instance_id}/domains/{domain}/purge",
post(registry::purge_domain_on_server),
(*TASK_DOMAIN_PURGE_0_1).clone(),
)
.route_with_task_permissive(
"/register-service",
post(registry::register_service),
(*TASK_SERVER_REGISTER_0_1).clone(),
)
.into_router();
let upload_routes: Router<AppState> = TrustTaskRouter::new()
.route_with_task_permissive(
"/dids/{*mnemonic}",
put(did_manage::upload_did),
(*TASK_DID_REGISTER_0_1).clone(),
)
.route_with_task_permissive(
"/witness/{*mnemonic}",
put(did_manage::upload_witness),
(*TASK_WEBVH_WITNESS_PUBLISH_0_1).clone(),
)
.route_with_task_permissive(
"/dids/register",
post(did_manage::register_did),
(*TASK_DID_REGISTER_0_1).clone(),
)
.route_with_task_permissive(
"/agent-names/update",
post(did_manage::update_agent_name),
(*TASK_AGENT_NAME_UPDATE_0_1).clone(),
)
.route_with_task_permissive(
"/agent-names/remove",
post(did_manage::remove_agent_name),
(*TASK_AGENT_NAME_REMOVE_0_1).clone(),
)
.into_router()
.layer(DefaultBodyLimit::max(10 * 1024 * 1024));
let api: Router<AppState> = TrustTaskRouter::new()
.route_with_task_permissive(
"/auth/challenge",
post(auth::challenge),
(*TASK_AUTH_CHALLENGE_0_1).clone(),
)
.route_with_task_permissive(
"/auth/",
post(auth::authenticate),
(*TASK_AUTH_AUTHENTICATE_0_1).clone(),
)
.route_with_task_permissive(
"/auth/refresh",
post(auth::refresh),
(*TASK_AUTH_REFRESH_0_1).clone(),
)
.route_with_task_permissive(
"/task-consent/request",
post(task_consent::request),
(*TASK_CONSENT_REQUEST_0_1).clone(),
)
.route_with_task_permissive(
"/auth/passkey/enroll/start",
post(passkey::enroll_start::<AppState>),
(*TASK_AUTH_PASSKEY_ENROLL_START_0_1).clone(),
)
.route_with_task_permissive(
"/auth/passkey/enroll/finish",
post(passkey::enroll_finish::<AppState>),
(*TASK_AUTH_PASSKEY_ENROLL_FINISH_0_1).clone(),
)
.route_with_tasks_permissive(
"/auth/passkey/login/start",
post(passkey::login_start::<AppState>),
(*TASK_AUTH_PASSKEY_LOGIN_START_0_2).clone(),
vec![(*TASK_AUTH_PASSKEY_LOGIN_START_0_1).clone()],
)
.route_with_tasks_permissive(
"/auth/passkey/login/finish",
post(passkey::login_finish::<AppState>),
(*TASK_AUTH_PASSKEY_LOGIN_FINISH_0_2).clone(),
vec![(*TASK_AUTH_PASSKEY_LOGIN_FINISH_0_1).clone()],
)
.route_with_tasks_permissive(
"/auth/step-up/passkey/start",
post(passkey::step_up_start::<AppState>),
(*TASK_AUTH_STEP_UP_PASSKEY_START_0_2).clone(),
vec![(*TASK_AUTH_STEP_UP_PASSKEY_START_0_1).clone()],
)
.route_with_tasks_permissive(
"/auth/step-up/passkey/finish",
post(passkey::step_up_finish::<AppState>),
(*TASK_AUTH_STEP_UP_PASSKEY_FINISH_0_2).clone(),
vec![(*TASK_AUTH_STEP_UP_PASSKEY_FINISH_0_1).clone()],
)
.route_with_tasks_permissive(
"/auth/step-up/vta/start",
post(auth::step_up_vta_start),
(*TASK_AUTH_STEP_UP_VTA_START_0_2).clone(),
vec![(*TASK_AUTH_STEP_UP_VTA_START_0_1).clone()],
)
.route_with_tasks_permissive(
"/auth/step-up/vta/finish",
post(auth::step_up_vta_finish),
(*TASK_AUTH_STEP_UP_VTA_FINISH_0_2).clone(),
vec![(*TASK_AUTH_STEP_UP_VTA_FINISH_0_1).clone()],
)
.route_with_task_permissive(
"/auth/step-up/check",
get(passkey::step_up_check),
(*TASK_AUTH_STEP_UP_CHECK_1_0).clone(),
)
.route_with_task_permissive(
"/auth/passkey/invite",
post(passkey::create_invite::<AppState>),
(*TASK_AUTH_PASSKEY_INVITE_0_1).clone(),
)
.route_with_task_permissive(
"/auth/passkey/invites",
get(passkey::list_invites::<AppState>),
(*TASK_AUTH_PASSKEY_INVITE_0_1).clone(),
)
.route_with_task_permissive(
"/auth/passkey/invite/{token}",
put(passkey::update_invite::<AppState>).delete(passkey::revoke_invite::<AppState>),
(*TASK_AUTH_PASSKEY_INVITE_0_1).clone(),
)
.route_with_task_permissive(
"/acl",
get(acl::list_acl).post(acl::create_acl),
(*TASK_ACL_LIST_1_0).clone(),
)
.route_with_task_permissive(
"/acl/{did}",
put(acl::update_acl).delete(acl::delete_acl),
(*TASK_ACL_UPDATE_1_0).clone(),
)
.route_with_task_permissive(
"/domains",
get(domain::list_domains).post(domain::create_domain_route),
(*TASK_DOMAIN_LIST_1_0).clone(),
)
.route_with_task_permissive(
"/domains/{name}",
put(domain::update_domain_route).delete(domain::delete_domain_route),
(*TASK_DOMAIN_UPDATE_0_1).clone(),
)
.route_with_task_permissive(
"/domains/{name}/disable",
post(domain::disable_domain_route),
(*TASK_DOMAIN_SET_STATE_0_1).clone(),
)
.route_with_task_permissive(
"/domains/{name}/enable",
post(domain::enable_domain_route),
(*TASK_DOMAIN_SET_STATE_0_1).clone(),
)
.route_with_task_permissive(
"/domains/{name}/set-default",
post(domain::set_default_domain_route),
(*TASK_DOMAIN_SET_DEFAULT_0_1).clone(),
)
.route_with_task_permissive(
"/me/domains",
get(domain::list_my_domains),
(*TASK_ME_DOMAINS_0_1).clone(),
)
.route_with_task_permissive(
"/dids/check",
post(did_manage::check_name),
(*TASK_DID_CHECK_NAME_0_1).clone(),
)
.route_with_task_permissive(
"/agent-names/check",
post(did_manage::check_agent_name),
(*TASK_AGENT_NAME_CHECK_0_1).clone(),
)
.route_with_task_permissive(
"/agent-names/resolve",
post(did_manage::resolve_agent_names),
(*TASK_AGENT_NAME_RESOLVE_1_0).clone(),
)
.route_with_task_permissive(
"/dids",
post(did_manage::request_uri).get(did_manage::list_dids),
(*TASK_DID_CHECK_NAME_0_1).clone(),
)
.route_with_task_permissive(
"/dids/{*mnemonic}",
get(did_manage::get_did).delete(did_manage::delete_did),
(*TASK_DID_INFO_0_1).clone(),
)
.route_with_task_permissive(
"/log/{*mnemonic}",
get(did_manage::get_did_log),
(*TASK_DID_LOG_1_0).clone(),
)
.route_with_task_permissive(
"/owner/{*mnemonic}",
put(did_manage::change_owner),
(*TASK_DID_CHANGE_OWNER_0_1).clone(),
)
.route_with_task_permissive(
"/disable/{*mnemonic}",
put(did_manage::disable_did),
(*TASK_DID_SET_STATE_0_1).clone(),
)
.route_with_task_permissive(
"/enable/{*mnemonic}",
put(did_manage::enable_did),
(*TASK_DID_SET_STATE_0_1).clone(),
)
.route_with_task_permissive(
"/rollback/{*mnemonic}",
post(did_manage::rollback_did),
(*TASK_DID_ROLLBACK_0_1).clone(),
)
.route_with_task_permissive(
"/raw/{*mnemonic}",
get(did_manage::get_raw_log),
(*TASK_DID_RAW_LOG_1_0).clone(),
)
.route_with_task_permissive(
"/stats",
get(did_manage::get_server_stats),
(*TASK_STATS_SERVER_1_0).clone(),
)
.route_with_task_permissive(
"/stats/{*mnemonic}",
get(did_manage::get_did_stats),
(*TASK_STATS_DID_1_0).clone(),
)
.route_with_task_permissive(
"/timeseries",
get(did_manage::get_server_timeseries),
(*TASK_TIMESERIES_SERVER_1_0).clone(),
)
.route_with_task_permissive(
"/timeseries/{*mnemonic}",
get(did_manage::get_did_timeseries),
(*TASK_TIMESERIES_DID_1_0).clone(),
)
.route_with_task_permissive(
"/services/overview",
get(did_manage::get_services_overview),
(*TASK_SERVICES_OVERVIEW_1_0).clone(),
)
.route_with_task_permissive(
"/config",
get(did_manage::get_config),
(*TASK_CONFIG_1_0).clone(),
)
.route_exempt(
"/trust-tasks",
post(trust_tasks::dispatch_trust_task)
.layer(DefaultBodyLimit::max(TRUST_TASKS_BODY_LIMIT_BYTES)),
)
.route_exempt("/didcomm", post(didcomm::handle))
.route_exempt("/control/stats", post(stats_sync::receive_stats))
.route_exempt(
"/proxy/server/{instance_id}/{*path}",
any(proxy::proxy_to_service),
)
.route_exempt(
"/proxy/witness/{instance_id}/{*path}",
any(proxy::proxy_to_service),
)
.into_router()
.nest("/control", control)
.route("/identity/generations", get(identity::list_generations))
.route(
"/identity/generations/{id}/retire",
post(identity::retire_generation),
)
.merge(upload_routes);
#[allow(unused_mut)]
let mut router = Router::new()
.nest("/api", api)
.route("/api/health", get(health::health))
.route("/api/server-info", get(server_info::server_info));
#[cfg(feature = "metrics")]
{
router = router.route("/metrics", get(metrics_handler));
}
router
}
pub fn router() -> Router<AppState> {
#[allow(unused_mut)]
let mut r = router_without_fallback();
#[cfg(feature = "ui")]
{
r = r.fallback(crate::frontend::static_handler);
}
r
}
#[cfg(feature = "metrics")]
async fn metrics_handler() -> (
axum::http::StatusCode,
[(&'static str, &'static str); 1],
String,
) {
(
axum::http::StatusCode::OK,
[("content-type", "text/plain; version=0.0.4")],
did_hosting_common::server::metrics::render(),
)
}