diff --git a/src/config/mod.rs b/src/config/mod.rs index d51b480..a3383b6 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -1,4 +1,3 @@ - pub mod host { pub const PORT: i64 = 9081; @@ -10,116 +9,117 @@ pub mod host { pub mod init { use std::time::Duration; -use axum::routing::{delete, get, patch, post}; -use tower_http::timeout::TimeoutLayer; -use utoipa::OpenApi; + use axum::routing::{delete, get, patch, post}; + use tower_http::timeout::TimeoutLayer; + use utoipa::OpenApi; -use crate::callers::coverart as coverart_caller; -use crate::callers::queue::coverart as coverart_queue_callers; -use crate::callers::queue::metadata as metadata_queue_caller; -use crate::callers::queue::song as song_queue_callers; -use crate::callers::song as song_caller; -use coverart_caller::endpoint as coverart_endpoints; -use coverart_caller::response as coverart_responses; -use coverart_queue_callers::endpoint as coverart_queue_endpoints; -use coverart_queue_callers::response as coverart_queue_responses; -use metadata_queue_caller::endpoint as metadata_queue_endpoints; -use metadata_queue_caller::response as metadata_queue_responses; -use song_caller::endpoint as song_endpoints; -use song_caller::response as song_responses; -use song_queue_callers::endpoint as song_queue_endpoints; -use song_queue_callers::response as song_queue_responses; + use crate::callers::coverart as coverart_caller; + use crate::callers::queue::coverart as coverart_queue_callers; + use crate::callers::queue::metadata as metadata_queue_caller; + use crate::callers::queue::song as song_queue_callers; + use crate::callers::song as song_caller; + use coverart_caller::endpoint as coverart_endpoints; + use coverart_caller::response as coverart_responses; + use coverart_queue_callers::endpoint as coverart_queue_endpoints; + use coverart_queue_callers::response as coverart_queue_responses; + use metadata_queue_caller::endpoint as metadata_queue_endpoints; + use metadata_queue_caller::response as metadata_queue_responses; + use song_caller::endpoint as song_endpoints; + use song_caller::response as song_responses; + use song_queue_callers::endpoint as song_queue_endpoints; + use song_queue_callers::response as song_queue_responses; -mod cors { - pub async fn configure_cors() -> tower_http::cors::CorsLayer { - let cors = tower_http::cors::CorsLayer::new() - .allow_methods([ - axum::http::Method::GET, - axum::http::Method::POST, - axum::http::Method::PUT, - axum::http::Method::DELETE, - ]) // Specify allowed methods:cite[2] - .allow_headers([ - axum::http::header::CONTENT_TYPE, - axum::http::header::AUTHORIZATION, - ]) // Specify allowed headers:cite[2] - .allow_credentials(true) // If you need to send cookies or authentication headers:cite[2] - .max_age(std::time::Duration::from_secs(3600)); // Cache the preflight response for 1 hour:cite[2] + mod cors { + pub async fn configure_cors() -> tower_http::cors::CorsLayer { + let cors = tower_http::cors::CorsLayer::new() + .allow_methods([ + axum::http::Method::GET, + axum::http::Method::POST, + axum::http::Method::PUT, + axum::http::Method::DELETE, + ]) // Specify allowed methods:cite[2] + .allow_headers([ + axum::http::header::CONTENT_TYPE, + axum::http::header::AUTHORIZATION, + ]) // Specify allowed headers:cite[2] + .allow_credentials(true) // If you need to send cookies or authentication headers:cite[2] + .max_age(std::time::Duration::from_secs(3600)); // Cache the preflight response for 1 hour:cite[2] - // Dynamically set the allowed origin based on the environment - match std::env::var(textsender_models::envy::keys::APP_ENV).as_deref() { - Ok("production") => { - // In production, allow only your specific, trusted origins - let allowed_origins_env = textsender_models::envy::environment::get_allowed_origins().await; - match textsender_models::envy::utility::delimitize(&allowed_origins_env) { - Ok(alwd) => { - let allowed_origins: Vec = alwd - .into_iter() - .map(|a| a.parse::().unwrap()) - .collect(); - cors.allow_origin(allowed_origins) - } - Err(err) => { - eprintln!("Error getting allowed origins: Error: {err:?}"); - std::process::exit(-1); + // Dynamically set the allowed origin based on the environment + match std::env::var(textsender_models::envy::keys::APP_ENV).as_deref() { + Ok("production") => { + // In production, allow only your specific, trusted origins + let allowed_origins_env = + textsender_models::envy::environment::get_allowed_origins().await; + match textsender_models::envy::utility::delimitize(&allowed_origins_env) { + Ok(alwd) => { + let allowed_origins: Vec = alwd + .into_iter() + .map(|a| a.parse::().unwrap()) + .collect(); + cors.allow_origin(allowed_origins) + } + Err(err) => { + eprintln!("Error getting allowed origins: Error: {err:?}"); + std::process::exit(-1); + } } } - } - _ => { - // Development (default): Allow localhost origins - cors.allow_origin(vec![ - "http://localhost:8000".parse().unwrap(), - "http://127.0.0.1:8000".parse().unwrap(), - "http://localhost:4200".parse().unwrap(), - "http://127.0.0.1:4200".parse().unwrap(), - ]) + _ => { + // Development (default): Allow localhost origins + cors.allow_origin(vec![ + "http://localhost:8000".parse().unwrap(), + "http://127.0.0.1:8000".parse().unwrap(), + "http://localhost:4200".parse().unwrap(), + "http://127.0.0.1:4200".parse().unwrap(), + ]) + } } } } -} -#[derive(utoipa::OpenApi)] -#[openapi( + #[derive(utoipa::OpenApi)] + #[openapi( paths(song_queue_endpoints::queue_song,), components(schemas(song_queue_callers::response::song_queue::Response)), tags( (name = "textsender API", description = "Web API to manage texting") ) )] -struct ApiDoc; + struct ApiDoc; -pub async fn routes() -> axum::Router { - axum::Router::new() - .route( - crate::callers::queue::endpoints::QUEUESONG, - post(crate::callers::queue::song::endpoint::queue_song).route_layer( - axum::middleware::from_fn(crate::auth::auth::), - ), - ) - .layer(cors::configure_cors().await) -} - -pub async fn app() -> axum::Router { - let pool = crate::db::create_pool() - .await - .expect("Failed to create pool"); - - crate::db::migrations(&pool).await; - - let cors = cors::configure_cors().await; - - routes() - .await - .merge( - utoipa_swagger_ui::SwaggerUi::new("/swagger-ui") - .url("/api-docs/openapi.json", ApiDoc::openapi()), - ) - .layer(axum::Extension(pool)) - .layer(axum::extract::DefaultBodyLimit::max(1024 * 1024 * 1024)) - .layer(TimeoutLayer::with_status_code( - axum::http::StatusCode::OK, - Duration::from_secs(300), - )) - .layer(cors) -} + pub async fn routes() -> axum::Router { + axum::Router::new() + .route( + crate::callers::queue::endpoints::QUEUESONG, + post(crate::callers::queue::song::endpoint::queue_song).route_layer( + axum::middleware::from_fn(crate::auth::auth::), + ), + ) + .layer(cors::configure_cors().await) + } + + pub async fn app() -> axum::Router { + let pool = crate::db::create_pool() + .await + .expect("Failed to create pool"); + + crate::db::migrations(&pool).await; + + let cors = cors::configure_cors().await; + + routes() + .await + .merge( + utoipa_swagger_ui::SwaggerUi::new("/swagger-ui") + .url("/api-docs/openapi.json", ApiDoc::openapi()), + ) + .layer(axum::Extension(pool)) + .layer(axum::extract::DefaultBodyLimit::max(1024 * 1024 * 1024)) + .layer(TimeoutLayer::with_status_code( + axum::http::StatusCode::OK, + Duration::from_secs(300), + )) + .layer(cors) + } } diff --git a/src/main.rs b/src/main.rs index d499e1d..a6e5f5f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,7 +3,7 @@ async fn main() { // initialize tracing tracing_subscriber::fmt::init(); - match tokio::net::TcpListener::bind(textsender_api::config::host::get_full()).await { + match tokio::net::TcpListener::bind(textsender_api::config::host::get_full()).await { Ok(listener) => { // build our application with routes let app = textsender_api::config::init::app().await;