80 lines
2.5 KiB
Rust
80 lines
2.5 KiB
Rust
|
|
use anyhow::Result;
|
||
|
|
use sqlx::postgres::PgPoolOptions;
|
||
|
|
use std::sync::Arc;
|
||
|
|
use tower_http::cors::{Any, CorsLayer};
|
||
|
|
use tower_http::services::ServeDir;
|
||
|
|
use tower_http::trace::TraceLayer;
|
||
|
|
use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};
|
||
|
|
|
||
|
|
mod api;
|
||
|
|
mod auth_middleware;
|
||
|
|
mod db;
|
||
|
|
mod presence;
|
||
|
|
mod relay;
|
||
|
|
mod signaling;
|
||
|
|
mod state;
|
||
|
|
|
||
|
|
pub use state::AppState;
|
||
|
|
|
||
|
|
#[tokio::main]
|
||
|
|
async fn main() -> Result<()> {
|
||
|
|
dotenvy::dotenv().ok();
|
||
|
|
|
||
|
|
tracing_subscriber::registry()
|
||
|
|
.with(tracing_subscriber::EnvFilter::new(
|
||
|
|
std::env::var("RUST_LOG").unwrap_or_else(|_| "funmc_server=debug,tower_http=info".into()),
|
||
|
|
))
|
||
|
|
.with(tracing_subscriber::fmt::layer())
|
||
|
|
.init();
|
||
|
|
|
||
|
|
let database_url = std::env::var("DATABASE_URL")
|
||
|
|
.unwrap_or_else(|_| "postgres://postgres:password@localhost/funmc".into());
|
||
|
|
|
||
|
|
let pool = PgPoolOptions::new()
|
||
|
|
.max_connections(10)
|
||
|
|
.connect(&database_url)
|
||
|
|
.await?;
|
||
|
|
|
||
|
|
sqlx::migrate!("./migrations").run(&pool).await?;
|
||
|
|
|
||
|
|
let jwt_secret = std::env::var("JWT_SECRET")
|
||
|
|
.unwrap_or_else(|_| "dev-secret-change-in-production".into());
|
||
|
|
|
||
|
|
let state = Arc::new(AppState::new(pool, jwt_secret.clone()));
|
||
|
|
|
||
|
|
// Start QUIC relay server in background
|
||
|
|
let jwt_for_relay = jwt_secret.clone();
|
||
|
|
tokio::spawn(async move {
|
||
|
|
if let Err(e) = relay::server::RelayServer::start(jwt_for_relay).await {
|
||
|
|
tracing::error!("QUIC relay server error: {}", e);
|
||
|
|
}
|
||
|
|
});
|
||
|
|
|
||
|
|
let cors = CorsLayer::new()
|
||
|
|
.allow_origin(Any)
|
||
|
|
.allow_methods(Any)
|
||
|
|
.allow_headers(Any);
|
||
|
|
|
||
|
|
// Admin panel static files (default to dist directory for production)
|
||
|
|
let admin_dir = std::env::var("ADMIN_PANEL_DIR").unwrap_or_else(|_| "./admin-panel/dist".into());
|
||
|
|
|
||
|
|
let app = axum::Router::new()
|
||
|
|
.nest("/api/v1", api::router(state.clone()))
|
||
|
|
.nest("/download", api::download_router())
|
||
|
|
.nest_service("/admin", ServeDir::new(&admin_dir).append_index_html_on_directories(true))
|
||
|
|
.layer(TraceLayer::new_for_http())
|
||
|
|
.layer(cors)
|
||
|
|
.with_state(state);
|
||
|
|
|
||
|
|
let addr = std::env::var("LISTEN_ADDR").unwrap_or_else(|_| "0.0.0.0:3000".into());
|
||
|
|
tracing::info!("HTTP API listening on {}", addr);
|
||
|
|
tracing::info!("Admin panel at http://{}/admin", addr);
|
||
|
|
tracing::info!("Download page at http://{}/download", addr);
|
||
|
|
tracing::info!("QUIC relay listening on port 3001");
|
||
|
|
|
||
|
|
let listener = tokio::net::TcpListener::bind(&addr).await?;
|
||
|
|
axum::serve(listener, app).await?;
|
||
|
|
|
||
|
|
Ok(())
|
||
|
|
}
|