this repo has no description
at main 2.8 kB view raw
1use crate::state::AppState; 2use axum::{Json, extract::State, http::StatusCode, response::IntoResponse}; 3use serde_json::json; 4use tracing::error; 5 6fn get_available_comms_channels() -> Vec<&'static str> { 7 let mut channels = vec!["email"]; 8 if std::env::var("DISCORD_WEBHOOK_URL").is_ok() { 9 channels.push("discord"); 10 } 11 if std::env::var("TELEGRAM_BOT_TOKEN").is_ok() { 12 channels.push("telegram"); 13 } 14 if std::env::var("SIGNAL_CLI_PATH").is_ok() && std::env::var("SIGNAL_SENDER_NUMBER").is_ok() { 15 channels.push("signal"); 16 } 17 channels 18} 19 20pub async fn robots_txt() -> impl IntoResponse { 21 ( 22 StatusCode::OK, 23 [("content-type", "text/plain")], 24 "# Hello!\n\n# Crawling the public API is allowed\nUser-agent: *\nAllow: /\n", 25 ) 26} 27pub fn is_self_hosted_did_web_enabled() -> bool { 28 std::env::var("ENABLE_SELF_HOSTED_DID_WEB") 29 .map(|v| v != "false" && v != "0") 30 .unwrap_or(true) 31} 32 33pub async fn describe_server() -> impl IntoResponse { 34 let pds_hostname = std::env::var("PDS_HOSTNAME").unwrap_or_else(|_| "localhost".to_string()); 35 let domains_str = 36 std::env::var("AVAILABLE_USER_DOMAINS").unwrap_or_else(|_| pds_hostname.clone()); 37 let domains: Vec<&str> = domains_str.split(',').map(|s| s.trim()).collect(); 38 let invite_code_required = std::env::var("INVITE_CODE_REQUIRED") 39 .map(|v| v == "true" || v == "1") 40 .unwrap_or(false); 41 let privacy_policy = std::env::var("PRIVACY_POLICY_URL").ok(); 42 let terms_of_service = std::env::var("TERMS_OF_SERVICE_URL").ok(); 43 let contact_email = std::env::var("CONTACT_EMAIL").ok(); 44 let mut links = serde_json::Map::new(); 45 if let Some(pp) = privacy_policy { 46 links.insert("privacyPolicy".to_string(), json!(pp)); 47 } 48 if let Some(tos) = terms_of_service { 49 links.insert("termsOfService".to_string(), json!(tos)); 50 } 51 let mut contact = serde_json::Map::new(); 52 if let Some(email) = contact_email { 53 contact.insert("email".to_string(), json!(email)); 54 } 55 Json(json!({ 56 "availableUserDomains": domains, 57 "inviteCodeRequired": invite_code_required, 58 "did": format!("did:web:{}", pds_hostname), 59 "links": links, 60 "contact": contact, 61 "version": env!("CARGO_PKG_VERSION"), 62 "availableCommsChannels": get_available_comms_channels(), 63 "selfHostedDidWebEnabled": is_self_hosted_did_web_enabled() 64 })) 65} 66pub async fn health(State(state): State<AppState>) -> impl IntoResponse { 67 match sqlx::query!("SELECT 1 as one").fetch_one(&state.db).await { 68 Ok(_) => (StatusCode::OK, "OK"), 69 Err(e) => { 70 error!("Health check failed: {:?}", e); 71 (StatusCode::SERVICE_UNAVAILABLE, "Service Unavailable") 72 } 73 } 74}