use serde::Deserialize;
use super::source::TokenSourceConfig;
#[non_exhaustive]
#[derive(Debug, Clone, Deserialize)]
#[serde(default)]
pub struct JwtSessionsConfig {
pub signing_secret: String,
pub issuer: Option<String>,
pub access_ttl_secs: u64,
pub refresh_ttl_secs: u64,
pub max_per_user: usize,
pub touch_interval_secs: u64,
pub stateful_validation: bool,
pub access_source: TokenSourceConfig,
pub refresh_source: TokenSourceConfig,
}
impl Default for JwtSessionsConfig {
fn default() -> Self {
Self {
signing_secret: String::new(),
issuer: None,
access_ttl_secs: 900,
refresh_ttl_secs: 2_592_000,
max_per_user: 20,
touch_interval_secs: 300,
stateful_validation: true,
access_source: TokenSourceConfig::Bearer,
refresh_source: TokenSourceConfig::Body {
field: "refresh_token".into(),
},
}
}
}
impl JwtSessionsConfig {
pub fn new(signing_secret: impl Into<String>) -> Self {
Self {
signing_secret: signing_secret.into(),
..Self::default()
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn deserialize_full_config() {
let yaml = r#"
signing_secret: "my-secret"
issuer: "my-app"
access_ttl_secs: 900
refresh_ttl_secs: 2592000
max_per_user: 20
touch_interval_secs: 300
stateful_validation: true
"#;
let config: JwtSessionsConfig = serde_yaml_ng::from_str(yaml).unwrap();
assert_eq!(config.signing_secret, "my-secret");
assert_eq!(config.issuer.as_deref(), Some("my-app"));
assert_eq!(config.access_ttl_secs, 900);
assert_eq!(config.refresh_ttl_secs, 2_592_000);
assert_eq!(config.max_per_user, 20);
assert_eq!(config.touch_interval_secs, 300);
assert!(config.stateful_validation);
}
#[test]
fn deserialize_minimal_config() {
let yaml = r#"signing_secret: "my-secret""#;
let config: JwtSessionsConfig = serde_yaml_ng::from_str(yaml).unwrap();
assert_eq!(config.signing_secret, "my-secret");
assert!(config.issuer.is_none());
assert_eq!(config.access_ttl_secs, 900);
}
#[test]
fn missing_secret_defaults_to_empty() {
let yaml = r#"access_ttl_secs: 1800"#;
let config: JwtSessionsConfig = serde_yaml_ng::from_str(yaml).unwrap();
assert!(config.signing_secret.is_empty());
assert_eq!(config.access_ttl_secs, 1800);
}
#[test]
fn default_values() {
let config = JwtSessionsConfig::default();
assert!(config.signing_secret.is_empty());
assert!(config.issuer.is_none());
assert_eq!(config.access_ttl_secs, 900);
assert_eq!(config.refresh_ttl_secs, 2_592_000);
assert_eq!(config.max_per_user, 20);
assert_eq!(config.touch_interval_secs, 300);
assert!(config.stateful_validation);
}
#[test]
fn new_sets_signing_secret() {
let config = JwtSessionsConfig::new("my-super-secret");
assert_eq!(config.signing_secret, "my-super-secret");
assert_eq!(config.access_ttl_secs, 900);
}
}