//! Application configuration read from environment variables. use std::sync::Arc; use uuid::Uuid; #[derive(Clone)] pub struct Config { pub mnw_base_url: Arc, pub oauth_client_id: String, pub oauth_redirect_uri: String, pub platform_admin_id: Option, /// Whether to set the `Secure` flag on session cookies. /// Defaults to `true`. Set `COOKIE_SECURE=false` for local HTTP development. pub cookie_secure: bool, /// S3 storage configuration. None if S3 env vars are missing. pub s3: Option, /// Shared secret for HMAC-signed internal API requests from MNW. pub internal_shared_secret: Option, } #[derive(Clone)] pub struct S3Config { pub endpoint: String, pub bucket: String, pub access_key: String, pub secret_key: String, pub region: String, } impl S3Config { fn from_env() -> Option { let endpoint = std::env::var("S3_ENDPOINT").ok()?; let bucket = std::env::var("S3_BUCKET").ok()?; let access_key = std::env::var("S3_ACCESS_KEY").ok()?; let secret_key = std::env::var("S3_SECRET_KEY").ok()?; let region = std::env::var("S3_REGION").unwrap_or_else(|_| "us-east-1".to_string()); Some(Self { endpoint, bucket, access_key, secret_key, region }) } } impl Config { pub fn from_env() -> Self { Self { mnw_base_url: std::env::var("MNW_BASE_URL") .unwrap_or_else(|_| "http://127.0.0.1:3000".to_string()) .into(), oauth_client_id: std::env::var("OAUTH_CLIENT_ID") .expect("OAUTH_CLIENT_ID must be set"), oauth_redirect_uri: std::env::var("OAUTH_REDIRECT_URI") .unwrap_or_else(|_| "http://127.0.0.1:3400/auth/callback".to_string()), platform_admin_id: std::env::var("PLATFORM_ADMIN_ID") .ok() .and_then(|s| Uuid::parse_str(&s).ok()), cookie_secure: std::env::var("COOKIE_SECURE") .map(|v| v != "false") .unwrap_or(true), s3: S3Config::from_env(), internal_shared_secret: std::env::var("INTERNAL_SHARED_SECRET").ok(), } } }