feat(server): auto-enable insecure cookies for localhost defaults
Default BREWLOG_RP_ID to "localhost" and BREWLOG_RP_ORIGIN to "http://localhost:3000". When these localhost defaults are active, insecure cookies are enabled automatically so local dev works without setting BREWLOG_INSECURE_COOKIES. A warning is logged at startup when insecure cookies are active. The insecure_cookies flag is now threaded through AppState instead of reading the env var at cookie-set time.
This commit is contained in:
parent
43b5ccb34a
commit
000f20eab7
7 changed files with 29 additions and 18 deletions
|
|
@ -487,8 +487,7 @@ async fn create_session(state: &AppState, cookies: &Cookies, user_id: crate::dom
|
||||||
cookie.set_http_only(true);
|
cookie.set_http_only(true);
|
||||||
cookie.set_same_site(tower_cookies::cookie::SameSite::Lax);
|
cookie.set_same_site(tower_cookies::cookie::SameSite::Lax);
|
||||||
|
|
||||||
let insecure = std::env::var("BREWLOG_INSECURE_COOKIES").unwrap_or_default() == "true";
|
if !state.insecure_cookies {
|
||||||
if !insecure {
|
|
||||||
cookie.set_secure(true);
|
cookie.set_secure(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@ pub struct ServerConfig {
|
||||||
pub database_url: String,
|
pub database_url: String,
|
||||||
pub rp_id: String,
|
pub rp_id: String,
|
||||||
pub rp_origin: String,
|
pub rp_origin: String,
|
||||||
|
pub insecure_cookies: bool,
|
||||||
pub openrouter_api_key: String,
|
pub openrouter_api_key: String,
|
||||||
pub openrouter_model: String,
|
pub openrouter_model: String,
|
||||||
pub foursquare_api_key: String,
|
pub foursquare_api_key: String,
|
||||||
|
|
@ -48,6 +49,7 @@ pub async fn serve(config: ServerConfig) -> anyhow::Result<()> {
|
||||||
&database,
|
&database,
|
||||||
AppStateConfig {
|
AppStateConfig {
|
||||||
webauthn,
|
webauthn,
|
||||||
|
insecure_cookies: config.insecure_cookies,
|
||||||
foursquare_url: crate::infrastructure::foursquare::FOURSQUARE_SEARCH_URL.to_string(),
|
foursquare_url: crate::infrastructure::foursquare::FOURSQUARE_SEARCH_URL.to_string(),
|
||||||
foursquare_api_key: config.foursquare_api_key,
|
foursquare_api_key: config.foursquare_api_key,
|
||||||
openrouter_url: crate::infrastructure::ai::OPENROUTER_URL.to_string(),
|
openrouter_url: crate::infrastructure::ai::OPENROUTER_URL.to_string(),
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,7 @@ use crate::infrastructure::webauthn::ChallengeStore;
|
||||||
/// automatically from the database pool.
|
/// automatically from the database pool.
|
||||||
pub struct AppStateConfig {
|
pub struct AppStateConfig {
|
||||||
pub webauthn: Arc<Webauthn>,
|
pub webauthn: Arc<Webauthn>,
|
||||||
|
pub insecure_cookies: bool,
|
||||||
pub foursquare_url: String,
|
pub foursquare_url: String,
|
||||||
pub foursquare_api_key: String,
|
pub foursquare_api_key: String,
|
||||||
pub openrouter_url: String,
|
pub openrouter_url: String,
|
||||||
|
|
@ -77,6 +78,7 @@ pub struct AppState {
|
||||||
pub gear_service: GearService,
|
pub gear_service: GearService,
|
||||||
pub cafe_service: CafeService,
|
pub cafe_service: CafeService,
|
||||||
pub cup_service: CupService,
|
pub cup_service: CupService,
|
||||||
|
pub insecure_cookies: bool,
|
||||||
pub stats_invalidator: StatsInvalidator,
|
pub stats_invalidator: StatsInvalidator,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -164,6 +166,7 @@ impl AppState {
|
||||||
gear_service,
|
gear_service,
|
||||||
cafe_service,
|
cafe_service,
|
||||||
cup_service,
|
cup_service,
|
||||||
|
insecure_cookies: config.insecure_cookies,
|
||||||
stats_invalidator: config.stats_invalidator,
|
stats_invalidator: config.stats_invalidator,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
22
src/main.rs
22
src/main.rs
|
|
@ -70,19 +70,16 @@ async fn main() -> Result<()> {
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn run_server(command: ServeCommand) -> Result<()> {
|
async fn run_server(command: ServeCommand) -> Result<()> {
|
||||||
let rp_id = command.rp_id.ok_or_else(|| {
|
let rp_id = command.rp_id;
|
||||||
anyhow::anyhow!(
|
let rp_origin = command.rp_origin;
|
||||||
"BREWLOG_RP_ID is required. Set this to the domain where the app is hosted \
|
|
||||||
(e.g. 'brewlog.example.com' or 'localhost')."
|
|
||||||
)
|
|
||||||
})?;
|
|
||||||
|
|
||||||
let rp_origin = command.rp_origin.ok_or_else(|| {
|
let insecure_cookies = command.insecure_cookies
|
||||||
anyhow::anyhow!(
|
|| (rp_id == "localhost" && rp_origin.starts_with("http://localhost"));
|
||||||
"BREWLOG_RP_ORIGIN is required. Set this to the full origin URL \
|
if insecure_cookies {
|
||||||
(e.g. 'https://brewlog.example.com' or 'http://localhost:3000')."
|
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(|| {
|
let openrouter_api_key = command.openrouter_api_key.ok_or_else(|| {
|
||||||
anyhow::anyhow!(
|
anyhow::anyhow!(
|
||||||
|
|
@ -105,6 +102,7 @@ async fn run_server(command: ServeCommand) -> Result<()> {
|
||||||
database_url: command.database_url,
|
database_url: command.database_url,
|
||||||
rp_id,
|
rp_id,
|
||||||
rp_origin,
|
rp_origin,
|
||||||
|
insecure_cookies,
|
||||||
openrouter_api_key,
|
openrouter_api_key,
|
||||||
openrouter_model: command.openrouter_model,
|
openrouter_model: command.openrouter_model,
|
||||||
foursquare_api_key,
|
foursquare_api_key,
|
||||||
|
|
|
||||||
|
|
@ -111,11 +111,18 @@ pub struct ServeCommand {
|
||||||
#[arg(long, env = "BREWLOG_BIND_ADDRESS", default_value = "127.0.0.1:3000")]
|
#[arg(long, env = "BREWLOG_BIND_ADDRESS", default_value = "127.0.0.1:3000")]
|
||||||
pub bind_address: SocketAddr,
|
pub bind_address: SocketAddr,
|
||||||
|
|
||||||
#[arg(long, env = "BREWLOG_RP_ID")]
|
#[arg(long, env = "BREWLOG_RP_ID", default_value = "localhost")]
|
||||||
pub rp_id: Option<String>,
|
pub rp_id: String,
|
||||||
|
|
||||||
#[arg(long, env = "BREWLOG_RP_ORIGIN")]
|
#[arg(
|
||||||
pub rp_origin: Option<String>,
|
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")]
|
#[arg(long, env = "BREWLOG_OPENROUTER_API_KEY")]
|
||||||
pub openrouter_api_key: Option<String>,
|
pub openrouter_api_key: Option<String>,
|
||||||
|
|
|
||||||
|
|
@ -90,6 +90,7 @@ fn ensure_server_started() -> Result<(String, String), String> {
|
||||||
&database,
|
&database,
|
||||||
AppStateConfig {
|
AppStateConfig {
|
||||||
webauthn: test_webauthn(),
|
webauthn: test_webauthn(),
|
||||||
|
insecure_cookies: true,
|
||||||
foursquare_url: brewlog::infrastructure::foursquare::FOURSQUARE_SEARCH_URL
|
foursquare_url: brewlog::infrastructure::foursquare::FOURSQUARE_SEARCH_URL
|
||||||
.to_string(),
|
.to_string(),
|
||||||
foursquare_api_key: String::new(),
|
foursquare_api_key: String::new(),
|
||||||
|
|
|
||||||
|
|
@ -76,6 +76,7 @@ fn test_state_config() -> AppStateConfig {
|
||||||
let (tx, _rx) = tokio::sync::mpsc::channel(1);
|
let (tx, _rx) = tokio::sync::mpsc::channel(1);
|
||||||
AppStateConfig {
|
AppStateConfig {
|
||||||
webauthn: test_webauthn(),
|
webauthn: test_webauthn(),
|
||||||
|
insecure_cookies: true,
|
||||||
foursquare_url: brewlog::infrastructure::foursquare::FOURSQUARE_SEARCH_URL.to_string(),
|
foursquare_url: brewlog::infrastructure::foursquare::FOURSQUARE_SEARCH_URL.to_string(),
|
||||||
foursquare_api_key: String::new(),
|
foursquare_api_key: String::new(),
|
||||||
openrouter_url: brewlog::infrastructure::ai::OPENROUTER_URL.to_string(),
|
openrouter_url: brewlog::infrastructure::ai::OPENROUTER_URL.to_string(),
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue