this repo has no description
1mod api; 2mod state; 3mod auth; 4mod repo; 5 6use axum::{ 7 extract::State, 8 routing::{get, post}, 9 Router, 10 Json, 11 response::IntoResponse, 12 http::StatusCode, 13}; 14use serde_json::json; 15use std::net::SocketAddr; 16use state::AppState; 17use tracing::{info, error}; 18 19#[tokio::main] 20async fn main() { 21 dotenvy::dotenv().ok(); 22 tracing_subscriber::fmt::init(); 23 24 let database_url = std::env::var("DATABASE_URL").expect("DATABASE_URL must be set"); 25 26 let pool = sqlx::postgres::PgPoolOptions::new() 27 .max_connections(5) 28 .connect(&database_url) 29 .await 30 .expect("Failed to connect to Postgres"); 31 32 sqlx::migrate!("./migrations") 33 .run(&pool) 34 .await 35 .expect("Failed to run migrations"); 36 37 let state = AppState::new(pool); 38 39 let app = Router::new() 40 .route("/health", get(health)) 41 .route("/xrpc/com.atproto.server.describeServer", get(describe_server)) 42 .route("/xrpc/com.atproto.server.createAccount", post(api::server::create_account)) 43 .route("/xrpc/com.atproto.server.createSession", post(api::server::create_session)) 44 .route("/xrpc/com.atproto.server.getSession", get(api::server::get_session)) 45 .route("/xrpc/com.atproto.server.deleteSession", post(api::server::delete_session)) 46 .route("/xrpc/com.atproto.server.refreshSession", post(api::server::refresh_session)) 47 .route("/xrpc/com.atproto.repo.createRecord", post(api::repo::create_record)) 48 .with_state(state); 49 50 let addr = SocketAddr::from(([127, 0, 0, 1], 3000)); 51 info!("listening on {}", addr); 52 let listener = tokio::net::TcpListener::bind(addr).await.unwrap(); 53 axum::serve(listener, app).await.unwrap(); 54} 55 56async fn health(State(state): State<AppState>) -> impl IntoResponse { 57 match sqlx::query("SELECT 1").execute(&state.db).await { 58 Ok(_) => (StatusCode::OK, "OK"), 59 Err(e) => { 60 error!("Health check failed: {:?}", e); 61 (StatusCode::SERVICE_UNAVAILABLE, "Service Unavailable") 62 } 63 } 64} 65 66async fn describe_server() -> impl IntoResponse { 67 let domains_str = std::env::var("AVAILABLE_USER_DOMAINS").unwrap_or_else(|_| "example.com".to_string()); 68 let domains: Vec<&str> = domains_str.split(',').map(|s| s.trim()).collect(); 69 70 Json(json!({ 71 "availableUserDomains": domains 72 })) 73}