chore: remove SESSION_SECRET and wrap master_encryption_key in Arc

SESSION_SECRET was loaded and validated but never used anywhere in the
codebase. master_encryption_key is now wrapped in Arc<String> to avoid
cloning the secret string on every AppState clone.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
master
oabrivard 3 months ago
parent 150090a112
commit 69c1688bc7

@ -15,10 +15,6 @@ POSTGRES_PASSWORD=CHANGE_ME
# Generate with: openssl rand -hex 32
MASTER_ENCRYPTION_KEY=
# Secret for signing session cookies (at least 64 characters).
# Generate with: openssl rand -hex 32
SESSION_SECRET=
# --- Application ---
# Public URL where the app is accessible (no trailing slash).
# Used for magic link URLs, CORS origin, and cookie domain.

@ -4,6 +4,7 @@
//! to start with invalid configuration rather than failing at runtime.
use std::env;
use std::sync::Arc;
/// Typed application configuration.
#[derive(Debug, Clone)]
@ -12,8 +13,7 @@ pub struct AppConfig {
pub database_url: String,
// Security
pub session_secret: String,
pub master_encryption_key: String,
pub master_encryption_key: Arc<String>,
// Application
pub app_url: String,
@ -36,7 +36,6 @@ impl AppConfig {
/// Fails fast with a clear error message if a required variable is missing.
pub fn from_env() -> Result<Self, String> {
let database_url = required_var("DATABASE_URL")?;
let session_secret = required_var("SESSION_SECRET")?;
let master_encryption_key = required_var("MASTER_ENCRYPTION_KEY")?;
let app_url = required_var("APP_URL")?;
let resend_api_key = required_var("RESEND_API_KEY")?;
@ -54,8 +53,7 @@ impl AppConfig {
Ok(Self {
database_url,
session_secret,
master_encryption_key,
master_encryption_key: Arc::new(master_encryption_key),
app_url,
port,
static_dir,
@ -79,10 +77,6 @@ impl AppConfig {
);
}
if self.session_secret.len() < 64 {
return Err("SESSION_SECRET must be at least 64 characters".into());
}
if !self.app_url.starts_with("http://") && !self.app_url.starts_with("https://") {
return Err("APP_URL must start with http:// or https://".into());
}
@ -113,8 +107,7 @@ mod tests {
fn test_validate_valid_config() {
let config = AppConfig {
database_url: "postgres://user:pass@localhost/db".into(),
session_secret: "a".repeat(64),
master_encryption_key: "ab".repeat(32),
master_encryption_key: Arc::new("ab".repeat(32)),
app_url: "https://synth.example.com".into(),
port: 8080,
static_dir: "./static".into(),
@ -130,8 +123,7 @@ mod tests {
fn test_validate_bad_encryption_key_length() {
let config = AppConfig {
database_url: "postgres://user:pass@localhost/db".into(),
session_secret: "a".repeat(64),
master_encryption_key: "abcd".into(), // too short
master_encryption_key: Arc::new("abcd".into()), // too short
app_url: "https://synth.example.com".into(),
port: 8080,
static_dir: "./static".into(),
@ -148,8 +140,7 @@ mod tests {
fn test_validate_bad_encryption_key_not_hex() {
let config = AppConfig {
database_url: "postgres://user:pass@localhost/db".into(),
session_secret: "a".repeat(64),
master_encryption_key: "zz".repeat(32), // not hex
master_encryption_key: Arc::new("zz".repeat(32)), // not hex
app_url: "https://synth.example.com".into(),
port: 8080,
static_dir: "./static".into(),
@ -162,30 +153,11 @@ mod tests {
assert!(err.contains("MASTER_ENCRYPTION_KEY"));
}
#[test]
fn test_validate_short_session_secret() {
let config = AppConfig {
database_url: "postgres://user:pass@localhost/db".into(),
session_secret: "short".into(),
master_encryption_key: "ab".repeat(32),
app_url: "https://synth.example.com".into(),
port: 8080,
static_dir: "./static".into(),
resend_api_key: "re_test".into(),
email_from: "test@example.com".into(),
turnstile_secret_key: "0x4AAA".into(),
turnstile_site_key: "0x4BBB".into(),
};
let err = config.validate().unwrap_err();
assert!(err.contains("SESSION_SECRET"));
}
#[test]
fn test_validate_bad_app_url_scheme() {
let config = AppConfig {
database_url: "postgres://user:pass@localhost/db".into(),
session_secret: "a".repeat(64),
master_encryption_key: "ab".repeat(32),
master_encryption_key: Arc::new("ab".repeat(32)),
app_url: "ftp://synth.example.com".into(),
port: 8080,
static_dir: "./static".into(),
@ -202,8 +174,7 @@ mod tests {
fn test_validate_trailing_slash() {
let config = AppConfig {
database_url: "postgres://user:pass@localhost/db".into(),
session_secret: "a".repeat(64),
master_encryption_key: "ab".repeat(32),
master_encryption_key: Arc::new("ab".repeat(32)),
app_url: "https://synth.example.com/".into(),
port: 8080,
static_dir: "./static".into(),
@ -220,8 +191,7 @@ mod tests {
fn test_is_secure() {
let config = AppConfig {
database_url: "postgres://user:pass@localhost/db".into(),
session_secret: "a".repeat(64),
master_encryption_key: "ab".repeat(32),
master_encryption_key: Arc::new("ab".repeat(32)),
app_url: "https://synth.example.com".into(),
port: 8080,
static_dir: "./static".into(),

Loading…
Cancel
Save