A better Rust ATProto crate
at main 2.3 kB view raw
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}