From 44c9f0e7051aa9aea8528383fb034e21696c4efe Mon Sep 17 00:00:00 2001 From: Alex Selimov Date: Thu, 19 Mar 2026 23:37:03 -0400 Subject: [PATCH 1/2] Configure CORS --- Cargo.toml | 2 +- docker-compose.yml | 11 ++++++----- src/env.rs | 8 ++++++++ src/lib.rs | 18 +++++++++++++++++- 4 files changed, 32 insertions(+), 7 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 70a8350..e46bf28 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,7 +20,7 @@ sqlx = { version = "0.8.6", features = [ ] } tokio = { version = "1", features = ["full"] } tower = "0.5" -tower-http = { version = "0.6", features = ["trace"] } +tower-http = { version = "0.6", features = ["trace", "cors"] } tracing = "0.1" tracing-subscriber = { version = "0.3", features = ["env-filter"] } uuid = { version = "1.22.0", features = ["v4"] } diff --git a/docker-compose.yml b/docker-compose.yml index 5a55b89..4f36e63 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,12 +1,12 @@ services: db: image: postgres:16 - container_name: uprs_db + container_name: upvoters_db restart: always environment: - POSTGRES_USER: uprs + POSTGRES_USER: upvoters POSTGRES_PASSWORD: password123 - POSTGRES_DB: uprs + POSTGRES_DB: upvoters volumes: - pgdata:/var/lib/postgresql/data - ./db/migrations:/docker-entrypoint-initdb.d # run initial schema @@ -15,10 +15,11 @@ services: app: build: . - container_name: uprs_app + container_name: upvoters_app restart: always environment: - POSTGRES_CONNECTION_STRING: postgres://uprs:password123@db:5432/uprs + POSTGRES_CONNECTION_STRING: postgres://upvoters:password123@db:5432/upvoters + ALLOWED_ORIGINS: http://localhost:1313 ports: - "3000:3000" depends_on: diff --git a/src/env.rs b/src/env.rs index 3222dc5..110cdbb 100644 --- a/src/env.rs +++ b/src/env.rs @@ -3,6 +3,7 @@ use std::env; #[derive(Clone)] pub struct Env { pub postgres_connection_string: String, + pub allowed_origins: Vec, } impl Env { @@ -10,8 +11,15 @@ impl Env { let postgres_connection_string = env::var("POSTGRES_CONNECTION_STRING") .expect("Missing POSTGRES_CONNECTION_STRING as an environment variable"); + let allowed_origins = env::var("ALLOWED_ORIGINS") + .expect("Missing ALLOWED_ORIGINS as an environment variable") + .split(',') + .map(|s| s.trim().to_string()) + .collect(); + Env { postgres_connection_string, + allowed_origins, } } } diff --git a/src/lib.rs b/src/lib.rs index de4b4f6..d8d7450 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -5,9 +5,25 @@ pub mod test_helpers; pub mod votes; use axum::Router; +use axum::http::{HeaderValue, Method, header}; use state::AppState; +use tower_http::cors::CorsLayer; use tower_http::trace::TraceLayer; pub fn app(state: AppState) -> Router { - routes::router(state).layer(TraceLayer::new_for_http()) + let origins: Vec = state + .env + .allowed_origins + .iter() + .map(|o| o.parse().expect("Invalid origin in ALLOWED_ORIGINS")) + .collect(); + let cors = CorsLayer::new() + .allow_origin(origins) + .allow_methods([Method::GET, Method::POST, Method::DELETE]) + .allow_headers([header::CONTENT_TYPE]) + .allow_credentials(true); + + routes::router(state) + .layer(TraceLayer::new_for_http()) + .layer(cors) } From a3b201fa098319b4b16af7006a357a121fe4f768 Mon Sep 17 00:00:00 2001 From: Alex Selimov Date: Thu, 19 Mar 2026 23:44:37 -0400 Subject: [PATCH 2/2] Fix default connection string and set port as environment variable --- src/env.rs | 5 +++++ src/main.rs | 6 ++++-- src/test_helpers.rs | 2 +- src/votes/handlers.rs | 2 ++ 4 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/env.rs b/src/env.rs index 110cdbb..5b44f38 100644 --- a/src/env.rs +++ b/src/env.rs @@ -4,6 +4,7 @@ use std::env; pub struct Env { pub postgres_connection_string: String, pub allowed_origins: Vec, + pub port: String, } impl Env { @@ -17,9 +18,13 @@ impl Env { .map(|s| s.trim().to_string()) .collect(); + let port = env::var("PORT") + .unwrap_or_else(|_| "3000".to_string()); + Env { postgres_connection_string, allowed_origins, + port, } } } diff --git a/src/main.rs b/src/main.rs index 0514583..f7280c3 100644 --- a/src/main.rs +++ b/src/main.rs @@ -12,9 +12,11 @@ async fn main() { .with(tracing_subscriber::fmt::layer()) .init(); - let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap(); + let state = AppState::new().await; + let port = &state.env.port; + let listener = tokio::net::TcpListener::bind(format!("0.0.0.0:{port}")).await.unwrap(); tracing::info!("listening on {}", listener.local_addr().unwrap()); - axum::serve(listener, upvoters::app(AppState::new().await)) + axum::serve(listener, upvoters::app(state)) .await .unwrap(); } diff --git a/src/test_helpers.rs b/src/test_helpers.rs index 1ea5d68..ba20ce3 100644 --- a/src/test_helpers.rs +++ b/src/test_helpers.rs @@ -3,7 +3,7 @@ pub mod db { use sqlx::PgPool; const DEFAULT_CONNECTION_STRING: &str = - "postgres://uprs:password123@localhost:5432/uprs"; + "postgres://upvoters:password123@localhost:5432/upvoters"; pub async fn test_pool() -> PgPool { let conn = std::env::var("POSTGRES_CONNECTION_STRING") diff --git a/src/votes/handlers.rs b/src/votes/handlers.rs index 3eeb713..ced29a9 100644 --- a/src/votes/handlers.rs +++ b/src/votes/handlers.rs @@ -141,6 +141,8 @@ mod tests { db, env: Env { postgres_connection_string: String::new(), + allowed_origins: vec![], + port: "3000".to_string(), }, } }