1//! Helper for serving did:web DID documents
2//!
3//! did:web DIDs resolve to HTTPS endpoints serving DID documents. This module
4//! provides a router that serves your service's DID document at `/.well-known/did.json`.
5//!
6//! # Example
7//!
8//! ```no_run
9//! use axum::Router;
10//! use jacquard_axum::did_web::did_web_router;
11//! use jacquard_common::types::did_doc::DidDocument;
12//!
13//! #[tokio::main]
14//! async fn main() {
15//! // Your DID document (typically loaded from config or generated)
16//! let did_doc: DidDocument = serde_json::from_str(r#"{
17//! "id": "did:web:feedgen.example.com",
18//! "verificationMethod": [{
19//! "id": "did:web:feedgen.example.com#atproto",
20//! "type": "Multikey",
21//! "controller": "did:web:feedgen.example.com",
22//! "publicKeyMultibase": "zQ3sh..."
23//! }]
24//! }"#).unwrap();
25//!
26//! let app = Router::new()
27//! .merge(did_web_router(did_doc));
28//!
29//! let listener = tokio::net::TcpListener::bind("0.0.0.0:443")
30//! .await
31//! .unwrap();
32//! axum::serve(listener, app).await.unwrap();
33//! }
34//! ```
35
36use axum::{
37 Json, Router,
38 http::{HeaderValue, StatusCode, header},
39 response::IntoResponse,
40 routing::get,
41};
42use jacquard_common::types::did_doc::DidDocument;
43
44/// Create a router that serves a DID document at `/.well-known/did.json`
45///
46/// Returns a Router that can be merged into your main application router.
47/// The DID document is cloned on each request.
48///
49/// # Example
50///
51/// ```no_run
52/// use axum::Router;
53/// use jacquard_axum::did_web::did_web_router;
54/// use jacquard_common::types::did_doc::DidDocument;
55///
56/// # async fn example(did_doc: DidDocument<'static>) {
57/// let app = Router::new()
58/// .merge(did_web_router(did_doc));
59/// # }
60/// ```
61pub fn did_web_router(did_doc: DidDocument<'static>) -> Router {
62 Router::new().route(
63 "/.well-known/did.json",
64 get(move || async move {
65 (
66 StatusCode::OK,
67 [(
68 header::CONTENT_TYPE,
69 HeaderValue::from_static("application/did+json"),
70 )],
71 Json(did_doc.clone()),
72 )
73 .into_response()
74 }),
75 )
76}