Self-hosted, federated location sharing app and server that prioritizes user privacy and security
end-to-end-encryption location-sharing privacy self-hosted federated
at auth 2.2 kB view raw
1use std::{collections::HashMap, sync::Arc}; 2 3use axum::{Router, routing::post}; 4use nanoid::nanoid; 5use std::collections::HashSet; 6use tokio::sync::Mutex; 7use tower_http::cors::CorsLayer; 8use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt}; 9 10mod auth; 11mod handlers; 12mod log; 13mod types; 14 15use handlers::*; 16use types::*; 17 18use crate::auth::auth_test; 19use crate::log::log_req_res_bodies; 20 21#[tokio::main] 22async fn main() { 23 tracing_subscriber::registry() 24 .with( 25 tracing_subscriber::EnvFilter::try_from_default_env() 26 .unwrap_or_else(|_| "info,tower_http=info,axum=info".into()), 27 ) 28 .with(tracing_subscriber::fmt::layer()) 29 .init(); 30 31 // TODO: should this be inside an Arc? 32 let state = AppState { 33 users: Arc::new(Mutex::new(Vec::new())), 34 signup_keys: Arc::new(Mutex::new(HashSet::new())), 35 friend_requests: Arc::new(Mutex::new(HashSet::new())), 36 links: Arc::new(Mutex::new(HashSet::new())), 37 positions: Arc::new(Mutex::new(HashMap::new())), 38 admin_id: Arc::new(Mutex::new(None)), 39 ring_buffer_cap: 5, 40 }; 41 42 // Until we have disk saves, always generate a admin signup key since there will be no admin set at launch 43 let admin_signup_key = nanoid!(5); 44 println!("Admin signup key: {admin_signup_key}"); 45 println!("http://127.0.0.1:3000"); 46 state.signup_keys.lock().await.insert(admin_signup_key); 47 48 // build our application with a route 49 let app = Router::new() 50 .route("/", post(|| async { "You just sent a POST to /" })) // for testing 51 .route("/create-account", post(create_user)) 52 .route("/generate-signup-key", post(generate_signup_key)) 53 .route("/request-friend-request", post(request_friend_request)) 54 .route( 55 "/is-friend-request-accepted", 56 post(is_friend_request_accepted), 57 ) 58 .route("/send-pings", post(send_pings)) 59 .route("/get-pings", post(get_pings)) 60 .with_state(state.clone()) 61 .layer(axum::middleware::from_fn_with_state(state, auth_test)) 62 .layer(axum::middleware::from_fn(log_req_res_bodies)) 63 .layer(CorsLayer::permissive()); 64 65 let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap(); 66 axum::serve(listener, app).await.unwrap(); 67} 68 69// TODO: potential security risk of returning error messages directly to the user. nice for debugging tho :p