diff --git a/src/application/routes/api/auth/webauthn.rs b/src/application/routes/api/auth/webauthn.rs index 804d207..9d5ffe0 100644 --- a/src/application/routes/api/auth/webauthn.rs +++ b/src/application/routes/api/auth/webauthn.rs @@ -487,8 +487,7 @@ async fn create_session(state: &AppState, cookies: &Cookies, user_id: crate::dom cookie.set_http_only(true); cookie.set_same_site(tower_cookies::cookie::SameSite::Lax); - let insecure = std::env::var("BREWLOG_INSECURE_COOKIES").unwrap_or_default() == "true"; - if !insecure { + if !state.insecure_cookies { cookie.set_secure(true); } diff --git a/src/application/server.rs b/src/application/server.rs index 305127f..6379b54 100644 --- a/src/application/server.rs +++ b/src/application/server.rs @@ -22,6 +22,7 @@ pub struct ServerConfig { pub database_url: String, pub rp_id: String, pub rp_origin: String, + pub insecure_cookies: bool, pub openrouter_api_key: String, pub openrouter_model: String, pub foursquare_api_key: String, @@ -48,6 +49,7 @@ pub async fn serve(config: ServerConfig) -> anyhow::Result<()> { &database, AppStateConfig { webauthn, + insecure_cookies: config.insecure_cookies, foursquare_url: crate::infrastructure::foursquare::FOURSQUARE_SEARCH_URL.to_string(), foursquare_api_key: config.foursquare_api_key, openrouter_url: crate::infrastructure::ai::OPENROUTER_URL.to_string(), diff --git a/src/application/state.rs b/src/application/state.rs index 0f68843..9d46f27 100644 --- a/src/application/state.rs +++ b/src/application/state.rs @@ -36,6 +36,7 @@ use crate::infrastructure::webauthn::ChallengeStore; /// automatically from the database pool. pub struct AppStateConfig { pub webauthn: Arc, + pub insecure_cookies: bool, pub foursquare_url: String, pub foursquare_api_key: String, pub openrouter_url: String, @@ -77,6 +78,7 @@ pub struct AppState { pub gear_service: GearService, pub cafe_service: CafeService, pub cup_service: CupService, + pub insecure_cookies: bool, pub stats_invalidator: StatsInvalidator, } @@ -164,6 +166,7 @@ impl AppState { gear_service, cafe_service, cup_service, + insecure_cookies: config.insecure_cookies, stats_invalidator: config.stats_invalidator, } } diff --git a/src/main.rs b/src/main.rs index fab38e9..9da8be9 100644 --- a/src/main.rs +++ b/src/main.rs @@ -70,19 +70,16 @@ async fn main() -> Result<()> { } async fn run_server(command: ServeCommand) -> Result<()> { - let rp_id = command.rp_id.ok_or_else(|| { - anyhow::anyhow!( - "BREWLOG_RP_ID is required. Set this to the domain where the app is hosted \ - (e.g. 'brewlog.example.com' or 'localhost')." - ) - })?; + let rp_id = command.rp_id; + let rp_origin = command.rp_origin; - let rp_origin = command.rp_origin.ok_or_else(|| { - anyhow::anyhow!( - "BREWLOG_RP_ORIGIN is required. Set this to the full origin URL \ - (e.g. 'https://brewlog.example.com' or 'http://localhost:3000')." - ) - })?; + let insecure_cookies = command.insecure_cookies + || (rp_id == "localhost" && rp_origin.starts_with("http://localhost")); + if insecure_cookies { + tracing::warn!( + "insecure cookies enabled for development/demo setup - do not use in production" + ); + } let openrouter_api_key = command.openrouter_api_key.ok_or_else(|| { anyhow::anyhow!( @@ -105,6 +102,7 @@ async fn run_server(command: ServeCommand) -> Result<()> { database_url: command.database_url, rp_id, rp_origin, + insecure_cookies, openrouter_api_key, openrouter_model: command.openrouter_model, foursquare_api_key, diff --git a/src/presentation/cli/mod.rs b/src/presentation/cli/mod.rs index 0207514..1ad4073 100644 --- a/src/presentation/cli/mod.rs +++ b/src/presentation/cli/mod.rs @@ -111,11 +111,18 @@ pub struct ServeCommand { #[arg(long, env = "BREWLOG_BIND_ADDRESS", default_value = "127.0.0.1:3000")] pub bind_address: SocketAddr, - #[arg(long, env = "BREWLOG_RP_ID")] - pub rp_id: Option, + #[arg(long, env = "BREWLOG_RP_ID", default_value = "localhost")] + pub rp_id: String, - #[arg(long, env = "BREWLOG_RP_ORIGIN")] - pub rp_origin: Option, + #[arg( + long, + env = "BREWLOG_RP_ORIGIN", + default_value = "http://localhost:3000" + )] + pub rp_origin: String, + + #[arg(long, env = "BREWLOG_INSECURE_COOKIES")] + pub insecure_cookies: bool, #[arg(long, env = "BREWLOG_OPENROUTER_API_KEY")] pub openrouter_api_key: Option, diff --git a/tests/cli/helpers.rs b/tests/cli/helpers.rs index 05aef08..0e935b4 100644 --- a/tests/cli/helpers.rs +++ b/tests/cli/helpers.rs @@ -90,6 +90,7 @@ fn ensure_server_started() -> Result<(String, String), String> { &database, AppStateConfig { webauthn: test_webauthn(), + insecure_cookies: true, foursquare_url: brewlog::infrastructure::foursquare::FOURSQUARE_SEARCH_URL .to_string(), foursquare_api_key: String::new(), diff --git a/tests/server/helpers.rs b/tests/server/helpers.rs index efc8385..43d4ace 100644 --- a/tests/server/helpers.rs +++ b/tests/server/helpers.rs @@ -76,6 +76,7 @@ fn test_state_config() -> AppStateConfig { let (tx, _rx) = tokio::sync::mpsc::channel(1); AppStateConfig { webauthn: test_webauthn(), + insecure_cookies: true, foursquare_url: brewlog::infrastructure::foursquare::FOURSQUARE_SEARCH_URL.to_string(), foursquare_api_key: String::new(), openrouter_url: brewlog::infrastructure::ai::OPENROUTER_URL.to_string(),