use chrono::Duration; pub use cookie::{Key, SameSite}; use std::{ borrow::Cow, fmt::{Debug, Formatter, Result}, sync::Arc, }; use uuid::Uuid; /// Mode at which the Session will function As. /// /// # Examples /// ```rust /// use session::{SessionConfig, SessionMode}; /// /// let config = SessionConfig::default().with_mode(SessionMode::Persistent); /// ``` /// #[derive(Debug, Clone)] pub enum SessionMode { /// Creates a SessionID Without SessionData.The End user must run `session.create_data()` /// to create the SessionData. /// Functions will emit a Info warning and do nothing until Created. /// Deletes SessionData and cookie if `session.store` is false. /// if SessionData.store is true retains SessionData and Syncs with Database. /// You can Set SessionData.store to true using 'session.set_store(true)' Manual, /// Always Creates a Session. /// Deletes SessionData and cookie if `session.store` is false. /// if SessionData.store is true retains SessionData and Syncs with Database. /// You can Set SessionData.store to true using 'session.set_store(true)' OptIn, /// Always Creates a Session /// Always retains in Memory and syncs with Database. Persistent, } impl SessionMode { /// Checks if the Mode is set to only if OptIn or Manual. /// pub fn is_opt_in(&self) -> bool { matches!(self, SessionMode::OptIn | SessionMode::Manual) } /// Checks if the user needs to manually create the SessionData per user. /// When created the Session will get Set to loaded. pub fn is_manual(&self) -> bool { matches!(self, SessionMode::Manual) } } #[derive(Clone)] pub struct CookieAndHeaderConfig { /// The Cookie or Header name that contains a boolean for session saving. /// only used when session_mode is set to SessionMode::OptIn or Manual. pub(crate) store_name: Cow<'static, str>, /// Session Cookie or Header name. pub(crate) session_name: Cow<'static, str>, /// Session cookie domain. pub(crate) cookie_domain: Option>, /// Session cookie http only flag. pub(crate) cookie_http_only: bool, /// Session cookie max age None means the browser deletes cookie on close. /// Please make sure the Duration is longer than max_lifespan. pub(crate) cookie_max_age: Option, /// Session cookie path. pub(crate) cookie_path: Cow<'static, str>, /// Resticts how Cookies are sent cross-site. Default is `SameSite::Lax`. pub(crate) cookie_same_site: SameSite, /// Session cookie secure flag. pub(crate) cookie_secure: bool, /// Encyption Key used to sign cookies and header for integrity, and authenticity. pub(crate) key: Option, /// This is used to append __Host- to the front of all Cookie names to prevent sub domain usage. /// This will not append to Headers only Cookies. It is enabled by default. pub(crate) prefix_with_host: bool, /// If Key is Some and this is true then the ip and user agent will be used to further sign cookies /// and header values. This will help prevent others from spoofing your cookies and headers. /// It is enabled by default. pub(crate) with_ip_and_user_agent: bool, } impl Debug for CookieAndHeaderConfig { fn fmt(&self, f: &mut Formatter<'_>) -> Result { f.debug_struct("CookieAndHeaderConfig") .field("store_name", &self.store_name) .field("cookie_domain", &self.cookie_domain) .field("cookie_http_only", &self.cookie_http_only) .field("cookie_max_age", &self.cookie_max_age) .field("session_name", &self.session_name) .field("cookie_path", &self.cookie_path) .field("cookie_same_site", &self.cookie_same_site) .field("cookie_secure", &self.cookie_secure) .field("prefix_with_host", &self.prefix_with_host) .field("with_ip_and_user_agent", &self.with_ip_and_user_agent) .field("key", &"key hidden") .finish() } } #[derive(Clone)] pub struct DatabaseConfig { /// Encyption Key used to encypt Session data stored in the database for confidentiality. pub(crate) database_key: Option, /// Session Database table name default is sessions. pub(crate) table_name: Cow<'static, str>, /// This value represents the duration for how often session's data gets purged from the database per request. pub(crate) purge_database_update: Duration, /// Ignore's the update checks and will always save the session to the database if set to true. pub(crate) always_save: bool, /// Minimum time interval between database updates for the same session. /// Sessions will only be updated in the database if this duration has elapsed /// since the last database update. This helps reduce database write load /// for frequently accessed sessions. Default is 10 seconds. pub(crate) db_update_interval: Duration, } impl Debug for DatabaseConfig { fn fmt(&self, f: &mut Formatter<'_>) -> Result { f.debug_struct("DatabaseConfig") .field("table_name", &self.table_name) .field("purge_database_update", &self.purge_database_update) .field("always_save", &self.always_save) .field("db_update_interval", &self.db_update_interval) .field("database_key", &"key hidden") .finish() } } #[derive(Clone)] pub struct MemoryConfig { /// This value represents the duration for how often session's data gets purged from memory per request. pub(crate) purge_update: Duration, /// Session Memory lifespan, determines when to unload it from memory /// this works fine since the data can stay in the database till its needed /// if not yet expired. pub(crate) memory_lifespan: Duration, /// How many Elements could we see at one time in the Table? /// So if you have 1000 unique visitors a second and each generate a UUID. /// That would be 1000 * 60(secs) * 60(mins) * 24(hours) to get 1 days worth of visitors. pub(crate) filter_expected_elements: u64, /// The probability of how many allowable false positives you want to have based on the expected elements. /// 0.01 is a good starting point. pub(crate) filter_false_positive_probability: f64, /// This enabled using a counting bloom filter. If this is taking to much Memory or is to slow or you just dont want /// the false positives it can give you can disable it by setting it to false. This will reduce memory usage. /// By default this is enabled unless the specific database cant function with it then disabled. pub(crate) use_bloom_filters: bool, } impl Debug for MemoryConfig { fn fmt(&self, f: &mut Formatter<'_>) -> Result { f.debug_struct("MemoryConfig") .field("memory_lifespan", &self.memory_lifespan) .field("filter_expected_elements", &self.filter_expected_elements) .field("use_bloom_filters", &self.use_bloom_filters) .field("purge_update", &self.purge_update) .field( "filter_false_positive_probability", &self.filter_false_positive_probability, ) .finish() } } #[derive(Clone)] pub struct IpUserAgentConfig { /// Uses the Direct Socket IP addresss of the socket connection. pub(crate) use_ip: bool, /// (XFF) request header is a de-facto standard header for identifying the originating /// IP address of a client connecting to a web server through a proxy server pub(crate) use_xforward_ip: bool, /// Contains information that may be added by reverse proxy servers pub(crate) use_forward_ip: bool, /// The last remote peers ip addresss. pub(crate) use_real_ip: bool, /// The Browser user agent. pub(crate) use_user_agent: bool, } impl Debug for IpUserAgentConfig { fn fmt(&self, f: &mut Formatter<'_>) -> Result { f.debug_struct("IpUserAgentConfig") .field("use_ip", &self.use_ip) .field("use_xforward_ip", &self.use_xforward_ip) .field("use_forward_ip", &self.use_forward_ip) .field("use_real_ip", &self.use_real_ip) .field("use_user_agent", &self.use_user_agent) .finish() } } pub trait IdGenerator: Debug + Send + Sync + 'static { fn generate(&self) -> String; } impl IdGenerator for Uuid { fn generate(&self) -> String { Uuid::new_v4().to_string() } } /// Configuration for how the Session and Cookies are used. /// /// # Examples /// ```rust /// use session::SessionConfig; /// /// let config = SessionConfig::default(); /// ``` /// #[derive(Clone)] pub struct SessionConfig { /// Disables the need to avoid session saving. pub(crate) session_mode: SessionMode, pub(crate) id_generator: Arc, /// Minimal lifespan of database store and cookie before expiring. /// This is set to the Cookie before sending and to the database before updating/inserting. pub(crate) lifespan: Duration, /// Maximum lifespan of database store and cookie before expiring. /// This is set to the Cookie before sending and to the database before updating/inserting. /// Only Set when Long Term is true. pub(crate) max_lifespan: Duration, /// This is to be used when your handling multiple Parallel Sessions to prevent the next one from unloaded data. pub(crate) clear_check_on_load: bool, /// where All Database Storage options exist. pub(crate) database: DatabaseConfig, /// where All In Memory Storage options exist. pub(crate) memory: MemoryConfig, /// where All the cookie and header Options Exist. pub(crate) cookie_and_header: CookieAndHeaderConfig, /// tells how we should build the string for hashing to secure the cookie. pub(crate) ip_user_agent: IpUserAgentConfig, pub(crate) thread_sleep_duration: Duration, } impl Debug for SessionConfig { fn fmt(&self, f: &mut Formatter<'_>) -> Result { f.debug_struct("SessionConfig") .field("id_generator", &self.id_generator) .field("database", &self.database) .field("memory", &self.memory) .field("cookie_and_header", &self.cookie_and_header) .field("session_mode", &self.session_mode) .field("lifespan", &self.lifespan) .field("max_lifespan", &self.max_lifespan) .field("clear_check_on_load", &self.clear_check_on_load) .field("thread_sleep_duration", &self.thread_sleep_duration) .finish() } } impl SessionConfig { /// Creates [`Default`] configuration of [`SessionConfig`]. /// This is equivalent to the [`SessionConfig::default()`]. #[inline] pub fn new() -> Self { Default::default() } /// Set a custom session ID generator. /// By default session IDs are UUIDs, but this allows for custom /// session ID formats. For example, to generate an ID that matches /// those from another web framework. /// /// # Examples /// ```rust /// use session::{IdGenerator, SessionConfig}; /// /// #[derive(Debug)] /// struct CustomSessionId(); /// /// impl CustomSessionId { /// pub fn new() -> Self { /// CustomSessionId() /// } /// } /// /// impl IdGenerator for CustomSessionId { /// fn generate(&self) -> String { /// // Return a custom Session ID... /// "something random".into() /// } /// } /// /// let config = SessionConfig::default().with_id_generator(CustomSessionId::new()); /// ``` #[must_use] pub fn with_id_generator(mut self, id_generator: impl IdGenerator) -> Self { self.id_generator = Arc::new(id_generator); self } /// Set the session's store Cookie or Header name. /// /// # Examples /// ```rust /// use session::SessionConfig; /// /// let config = SessionConfig::default().with_store_name("my_stored_cookie".to_owned()); /// ``` /// #[must_use] pub fn with_store_name(mut self, name: impl Into>) -> Self { self.cookie_and_header.store_name = name.into(); self } /// Set's the session's cookie's domain name. /// /// # Examples /// ```rust /// use session::SessionConfig; /// /// let config = SessionConfig::default().with_cookie_domain("www.helpme.com".to_string()); /// ``` /// #[must_use] pub fn with_cookie_domain(mut self, name: impl Into>) -> Self { self.cookie_and_header.cookie_domain = Some(name.into()); self } /// Set's the session's Cookie or Header name. /// /// # Examples /// ```rust /// use session::SessionConfig; /// /// let config = SessionConfig::default().with_session_name("my_cookie"); /// ``` /// #[must_use] pub fn with_session_name(mut self, name: impl Into>) -> Self { self.cookie_and_header.session_name = name.into(); self } /// Set's the session's cookie's path. /// /// This is used to determine when the cookie takes effect within the website path. /// Leave as default ("/") for cookie to be used site wide. /// /// # Examples /// ```rust /// use session::SessionConfig; /// /// let config = SessionConfig::default().with_cookie_path("/"); /// ``` /// #[must_use] pub fn with_cookie_path(mut self, path: impl Into>) -> Self { self.cookie_and_header.cookie_path = path.into(); self } /// Set's the session's cookie's Same Site Setting for Cross-Site restrictions. /// /// # Examples /// ```rust /// use session::SessionConfig; /// use cookie::SameSite; /// /// let config = SessionConfig::default().with_cookie_same_site(SameSite::Strict); /// ``` /// #[must_use] pub fn with_cookie_same_site(mut self, same_site: SameSite) -> Self { self.cookie_and_header.cookie_same_site = same_site; self } /// Set's whether the session Persistantly stores data or on stores if storable. /// /// # Examples /// ```rust /// use session::{SessionMode, SessionConfig}; /// use cookie::SameSite; /// /// let config = SessionConfig::default().with_mode(SessionMode::Persistent); /// ``` /// #[must_use] pub fn with_mode(mut self, mode: SessionMode) -> Self { self.session_mode = mode; self } /// Set's the session's cookie's to http only. /// /// # Examples /// ```rust /// use session::SessionConfig; /// /// let config = SessionConfig::default().with_http_only(false); /// ``` /// #[must_use] pub fn with_http_only(mut self, is_set: bool) -> Self { self.cookie_and_header.cookie_http_only = is_set; self } /// Set's the session's lifetime (expiration time) within database storage. /// This should be equal too or less than the Cookies Expiration time. /// # Examples /// ```rust /// use session::SessionConfig; /// use chrono::Duration; /// /// let config = SessionConfig::default().with_lifetime(Duration::days(32)); /// ``` /// #[must_use] pub fn with_lifetime(mut self, time: Duration) -> Self { self.lifespan = time; self } /// Set's the session's cookies max_age (expiration time). /// /// If this is set to None then the Cookie will be unloaded on browser Close. /// Set this to be the duration of max_lifespan or longer to prevent session drops. /// This is generally in a duration of how many Days a cookie should live in the browser. /// Please Ensure the Duration is greater or equal to max_lifespan for proper storage. /// # Examples /// ```rust /// use session::SessionConfig; /// use chrono::Duration; /// /// let config = SessionConfig::default().with_max_age(Some(Duration::days(64))); /// ``` /// #[must_use] pub fn with_max_age(mut self, time: Option) -> Self { self.cookie_and_header.cookie_max_age = time; self } /// Set's the session's long term lifetime (expiration time) within database storage. /// /// # Examples /// ```rust /// use session::SessionConfig; /// use chrono::Duration; /// /// let config = SessionConfig::default().with_max_lifetime(Duration::days(32)); /// ``` /// #[must_use] pub fn with_max_lifetime(mut self, time: Duration) -> Self { self.max_lifespan = time; self } /// Set's the session's lifetime (expiration time) within memory storage. /// This setting should be Less than lifespan and max_lifespan. This is to /// Unload the data from memory and allow it to stay stored in the database. /// /// Set this to Duration::zero() if you dont want it to stay in memory. /// Warning: This will cause it to be loaded from the database each request. /// /// # Examples /// ```rust /// use session::SessionConfig; /// use chrono::Duration; /// /// let config = SessionConfig::default().with_memory_lifetime(Duration::days(32)); /// ``` /// #[must_use] pub fn with_memory_lifetime(mut self, time: Duration) -> Self { self.memory.memory_lifespan = time; self } /// This value represents the offset duration for how often session purge for memory is ran. /// /// # Examples /// ```rust /// use session::SessionConfig; /// use chrono::Duration; /// /// let config = SessionConfig::default().with_purge_update(Duration::hours(1)); /// ``` /// #[must_use] pub fn with_purge_update(mut self, duration: Duration) -> Self { self.memory.purge_update = duration; self } /// This value represents the offset duration for how often session purge for database is ran. /// If using Redis or any auto purge database this Setting will be ignored. /// /// # Examples /// ```rust /// use session::SessionConfig; /// use chrono::Duration; /// /// let config = SessionConfig::default().with_purge_database_update(Duration::hours(5)); /// ``` /// #[must_use] pub fn with_purge_database_update(mut self, duration: Duration) -> Self { self.database.purge_database_update = duration; self } /// This value represents if the database should check for updates to save or /// to just save the data regardless of updates. When set to true it will disable the /// update checks. /// /// # Examples /// ```rust /// use session::SessionConfig; /// use chrono::Duration; /// /// let config = SessionConfig::default().with_always_save(true); /// ``` /// #[must_use] pub fn with_always_save(mut self, always_save: bool) -> Self { self.database.always_save = always_save; self } /// Set the database update interval for throttling session saves. /// This controls how frequently a session's data is persisted to the database. /// Only sessions that haven't been updated to the database within this interval /// will have their data saved on the next request. /// /// # Examples /// ```rust /// use session::SessionConfig; /// use chrono::Duration; /// /// let config = SessionConfig::default() /// .with_db_update_interval(Duration::try_seconds(10).unwrap_or_default()); /// ``` /// #[must_use] pub fn with_db_update_interval(mut self, interval: Duration) -> Self { self.database.db_update_interval = interval; self } /// Set's the session's secure flag for if it gets sent over https. /// /// # Examples /// ```rust /// use session::SessionConfig; /// /// let config = SessionConfig::default().with_secure(true); /// ``` /// #[must_use] pub fn with_secure(mut self, is_set: bool) -> Self { self.cookie_and_header.cookie_secure = is_set; self } /// Set's the session's database table name. /// /// # Examples /// ```rust /// use session::SessionConfig; /// /// let config = SessionConfig::default().with_table_name("my_table"); /// ``` /// #[must_use] pub fn with_table_name(mut self, table_name: impl Into>) -> Self { self.database.table_name = table_name.into(); self } /// Set's the session's cookie encyption key enabling Signed cookies. /// /// When Set it will enforce Signed cookies across all Sessions. /// If you use Key::generate() it will make a new key each server reboot. /// To prevent this make and save a key to a config file for long term usage. /// For Extra Security Regenerate the key every so many months to a year. /// A new key will invalidate all old Sessions so it be wise to run session_store.clear_store() on reboot. /// /// Must be Set to Some() in order to use Security::PerSession. /// /// # Examples /// ```rust /// use session::{Key, SessionConfig}; /// /// let config = SessionConfig::default().with_key(Key::generate()); /// ``` /// #[must_use] pub fn with_key(mut self, key: Key) -> Self { self.cookie_and_header.key = Some(key); self } /// Set's the session's database encyption key for per session key storage. /// /// Must be Set to Some() in order to use Security::PerSession or will panic if not. /// /// # Examples /// ```rust /// use session::{Key, SessionConfig}; /// /// let config = SessionConfig::default().with_key(Key::generate()); /// ``` /// #[must_use] pub fn with_database_key(mut self, key: Key) -> Self { self.database.database_key = Some(key); self } /// Set's the session's filters expected elements. /// Please Set this by a daily value. /// Example: 1000 * 60(secs) * 60(mins) * 24(hours) to get 1 days worth of visitors. /// /// # Examples /// ```rust /// use session::SessionConfig; /// /// let config = SessionConfig::default().with_filter_expected_elements(100_000); /// ``` /// #[must_use] pub fn with_filter_expected_elements(mut self, elements: u64) -> Self { self.memory.filter_expected_elements = elements; self } /// Set's the session's filters False Posistive probability when creating and comparing UUID. /// /// # Examples /// ```rust /// use session::SessionConfig; /// /// let config = SessionConfig::default().with_filter_false_positive_probability(0.01); /// ``` /// #[must_use] pub fn with_filter_false_positive_probability(mut self, probability: f64) -> Self { self.memory.filter_false_positive_probability = probability; self } /// Set's the session's bloom filters to be disabled or enabled. By default they are enabled. /// /// # Examples /// ```rust /// use session::SessionConfig; /// /// let config = SessionConfig::default().with_bloom_filter(true); /// ``` /// #[must_use] pub fn with_bloom_filter(mut self, enable: bool) -> Self { self.memory.use_bloom_filters = enable; self } /// Get's the session's Cookie/Header name /// /// # Examples /// ```rust /// use session::SessionConfig; /// /// let name = SessionConfig::default().get_session_name(); /// ``` /// pub fn get_session_name(&self) -> String { self.cookie_and_header.session_name.to_string() } /// Get's the session's store booleans Cookie/Header name /// /// # Examples /// ```rust /// use session::SessionConfig; /// /// let name = SessionConfig::default().get_store_name(); /// ``` /// pub fn get_store_name(&self) -> String { self.cookie_and_header.store_name.to_string() } /// Set's the session's loading to either true: unload data if checks fail or false: bypass. /// /// # Examples /// ```rust /// use session::SessionConfig; /// /// let config = SessionConfig::default().with_bloom_filter(true); /// ``` /// #[must_use] pub fn with_clear_check_on_load(mut self, enable: bool) -> Self { self.clear_check_on_load = enable; self } /// Set's the session's prefix_with_host to either true: __Host- gets prefixed to the cookie names false: __Host- does not get prepended. /// /// __Host- prefix: Cookies with names starting with __Host- must be set with the secure flag, must be from a secure page (HTTPS), /// must not have a domain specified (and therefore, are not sent to subdomains), and the path must be /. /// /// # Examples /// ```rust /// use session::SessionConfig; /// /// let config = SessionConfig::default().with_prefix_with_host(true); /// ``` /// #[must_use] pub fn with_prefix_with_host(mut self, enable: bool) -> Self { self.cookie_and_header.prefix_with_host = enable; self } /// Set's the session's with_ip_and_user_agent. /// /// If Key is Some and this is true then the ip and user agent will be used to further sign cookies /// and header values. This will help prevent others from spoofing your cookies and headers. /// It is enabled by default. /// /// # Examples /// ```rust /// use session::SessionConfig; /// /// let config = SessionConfig::default().with_ip_and_user_agent(false); /// ``` /// #[must_use] pub fn with_ip_and_user_agent(mut self, enable: bool) -> Self { self.cookie_and_header.with_ip_and_user_agent = enable; self } /// Set's the session's to use the Socket connected IP when hashing and verifying the cookies integrity. /// Only if with_ip_and_user_agent is also enabled. /// /// # Examples /// ```rust /// use session::SessionConfig; /// /// let config = SessionConfig::default().with_hashed_ip(true); /// ``` /// #[must_use] pub fn with_hashed_ip(mut self, enable: bool) -> Self { self.ip_user_agent.use_ip = enable; self } /// Set's the session's to use the xforward information when hashing and verifying the cookies integrity. /// Only if with_ip_and_user_agent is also enabled. /// /// # Examples /// ```rust /// use session::SessionConfig; /// /// let config = SessionConfig::default().with_hashed_xforward(true); /// ``` /// #[must_use] pub fn with_hashed_xforward(mut self, enable: bool) -> Self { self.ip_user_agent.use_xforward_ip = enable; self } /// Set's the session's to use the forward information when hashing and verifying the cookies integrity. /// Only if with_ip_and_user_agent is also enabled. /// /// # Examples /// ```rust /// use session::SessionConfig; /// /// let config = SessionConfig::default().with_hashed_forward(true); /// ``` /// #[must_use] pub fn with_hashed_forward(mut self, enable: bool) -> Self { self.ip_user_agent.use_forward_ip = enable; self } /// Set's the session's to use the real ip information when hashing and verifying the cookies integrity. /// Only if with_ip_and_user_agent is also enabled. /// /// # Examples /// ```rust /// use session::SessionConfig; /// /// let config = SessionConfig::default().with_hashed_real_ip(true); /// ``` /// #[must_use] pub fn with_hashed_real_ip(mut self, enable: bool) -> Self { self.ip_user_agent.use_real_ip = enable; self } /// Set's the session's to use the browsers user agent information when hashing and verifying the cookies integrity. /// Only if with_ip_and_user_agent is also enabled. /// /// # Examples /// ```rust /// use session::SessionConfig; /// /// let config = SessionConfig::default().with_hashed_user_agent(true); /// ``` /// #[must_use] pub fn with_hashed_user_agent(mut self, enable: bool) -> Self { self.ip_user_agent.use_user_agent = enable; self } /// Set's the session's thread Sleep Timer to reduce CPU cycle times. /// /// # Examples /// ```rust /// use session::SessionConfig; /// use chrono::Duration; /// /// let config = SessionConfig::default().with_thread_sleep_duration(Duration::try_minutes(5).unwrap_or_default()); /// ``` /// #[must_use] pub fn with_thread_sleep_duration(mut self, duration: Duration) -> Self { self.thread_sleep_duration = duration; self } } impl Default for SessionConfig { fn default() -> Self { Self { id_generator: Arc::new(Uuid::default()), // Set to a 6 hour default in Database Session stores unloading. lifespan: Duration::try_hours(6).unwrap_or_default(), cookie_and_header: CookieAndHeaderConfig::default(), database: DatabaseConfig::default(), memory: MemoryConfig::default(), // Unload long term session after 60 days if it has not been accessed. max_lifespan: Duration::try_days(60).unwrap_or_default(), session_mode: SessionMode::Persistent, clear_check_on_load: true, ip_user_agent: IpUserAgentConfig::default(), thread_sleep_duration: Duration::try_minutes(5).unwrap_or_default(), } } } impl Default for MemoryConfig { fn default() -> Self { Self { // Unload memory after 60 minutes if it has not been accessed. memory_lifespan: Duration::try_minutes(60).unwrap_or_default(), // Default to purge old sessions every 1 hours. purge_update: Duration::try_hours(1).unwrap_or_default(), // Simple is the Default mode for compatibilty with older versions of the crate. filter_expected_elements: 100_000, // The probability of how many allowable false positives you want to have based on the expected elements. // 0.01 is a good starting point. filter_false_positive_probability: 0.01, // Always set to on. use_bloom_filters: true, } } } impl Default for DatabaseConfig { fn default() -> Self { Self { // Set to a 6 hour default in Database Session stores unloading. table_name: "sessions".into(), // Default to purge old sessions in the database every 5 hours per request. purge_database_update: Duration::try_hours(5).unwrap_or_default(), always_save: false, // Database key is set to None it will panic if you attempt to use SecurityMode::PerSession. database_key: None, // Default to 10 seconds between database updates for the same session. db_update_interval: Duration::try_seconds(10).unwrap_or_default(), } } } impl Default for CookieAndHeaderConfig { fn default() -> Self { Self { session_name: "session".into(), cookie_path: "/".into(), cookie_max_age: Some(Duration::try_days(100).unwrap_or_default()), cookie_http_only: true, cookie_secure: false, cookie_domain: None, cookie_same_site: SameSite::Lax, store_name: "store".into(), // Key is set to None so Private cookies are not used by default. Please set this if you want to use private cookies. key: None, prefix_with_host: false, with_ip_and_user_agent: true, } } } impl Default for IpUserAgentConfig { fn default() -> Self { Self { use_ip: true, use_xforward_ip: false, use_forward_ip: false, use_real_ip: false, use_user_agent: true, } } }