Skip to main content

ferro_rs/session/
config.rs

1//! Session configuration
2
3use std::time::Duration;
4
5/// Session configuration
6#[derive(Clone, Debug)]
7pub struct SessionConfig {
8    /// Session lifetime
9    pub lifetime: Duration,
10    /// Cookie name for the session ID
11    pub cookie_name: String,
12    /// Cookie path
13    pub cookie_path: String,
14    /// Whether to set Secure flag on cookie (HTTPS only)
15    pub cookie_secure: bool,
16    /// Whether to set HttpOnly flag on cookie
17    pub cookie_http_only: bool,
18    /// SameSite attribute for the cookie
19    pub cookie_same_site: String,
20    /// Database table name for sessions
21    pub table_name: String,
22}
23
24impl Default for SessionConfig {
25    fn default() -> Self {
26        Self {
27            lifetime: Duration::from_secs(120 * 60), // 2 hours (120 minutes)
28            cookie_name: "ferro_session".to_string(),
29            cookie_path: "/".to_string(),
30            cookie_secure: true,
31            cookie_http_only: true,
32            cookie_same_site: "Lax".to_string(),
33            table_name: "sessions".to_string(),
34        }
35    }
36}
37
38impl SessionConfig {
39    /// Create a new session config with default values
40    pub fn new() -> Self {
41        Self::default()
42    }
43
44    /// Load session configuration from environment variables
45    ///
46    /// Environment variables:
47    /// - `SESSION_LIFETIME`: Session lifetime in minutes (default: 120)
48    /// - `SESSION_COOKIE`: Cookie name (default: ferro_session)
49    /// - `SESSION_SECURE`: Set Secure flag (default: true)
50    /// - `SESSION_PATH`: Cookie path (default: /)
51    /// - `SESSION_SAME_SITE`: SameSite attribute (default: Lax)
52    pub fn from_env() -> Self {
53        let lifetime_minutes: u64 = crate::env_optional("SESSION_LIFETIME")
54            .and_then(|s: String| s.parse().ok())
55            .unwrap_or(120);
56
57        let cookie_secure = crate::env_optional("SESSION_SECURE")
58            .map(|s: String| s.to_lowercase() == "true" || s == "1")
59            .unwrap_or(true);
60
61        Self {
62            lifetime: Duration::from_secs(lifetime_minutes * 60),
63            cookie_name: crate::env_optional("SESSION_COOKIE")
64                .unwrap_or_else(|| "ferro_session".to_string()),
65            cookie_path: crate::env_optional("SESSION_PATH").unwrap_or_else(|| "/".to_string()),
66            cookie_secure,
67            cookie_http_only: true, // Always true for security
68            cookie_same_site: crate::env_optional("SESSION_SAME_SITE")
69                .unwrap_or_else(|| "Lax".to_string()),
70            table_name: "sessions".to_string(),
71        }
72    }
73
74    /// Set the session lifetime
75    pub fn lifetime(mut self, duration: Duration) -> Self {
76        self.lifetime = duration;
77        self
78    }
79
80    /// Set the cookie name
81    pub fn cookie_name(mut self, name: impl Into<String>) -> Self {
82        self.cookie_name = name.into();
83        self
84    }
85
86    /// Set whether the cookie should be secure (HTTPS only)
87    pub fn secure(mut self, secure: bool) -> Self {
88        self.cookie_secure = secure;
89        self
90    }
91}