use crate::parse::{
default_idle_timeout, default_max_connections_per_ip, default_max_total_connections,
default_reaper_interval, parse_duration, parse_size,
};
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct SmtpOutboundConfig {
#[serde(default = "default_outbound_idle_timeout")]
pub idle_timeout_secs: u64,
#[serde(default = "default_outbound_per_remote_cap")]
pub per_remote_cap: usize,
#[serde(default = "default_outbound_global_cap")]
pub global_cap: usize,
}
fn default_outbound_idle_timeout() -> u64 {
30
}
fn default_outbound_per_remote_cap() -> usize {
8
}
fn default_outbound_global_cap() -> usize {
256
}
impl Default for SmtpOutboundConfig {
fn default() -> Self {
Self {
idle_timeout_secs: default_outbound_idle_timeout(),
per_remote_cap: default_outbound_per_remote_cap(),
global_cap: default_outbound_global_cap(),
}
}
}
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct SmtpServerConfig {
pub host: String,
pub port: u16,
#[serde(default)]
pub tls_port: Option<u16>,
pub max_message_size: String,
#[serde(default)]
pub require_auth: bool,
#[serde(default)]
pub enable_starttls: bool,
#[serde(default)]
pub rate_limit: Option<RateLimitConfig>,
#[serde(default)]
pub outbound: SmtpOutboundConfig,
}
impl SmtpServerConfig {
pub fn max_message_size_bytes(&self) -> anyhow::Result<usize> {
parse_size(&self.max_message_size)
}
}
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct RateLimitConfig {
#[serde(default = "default_max_connections_per_ip")]
pub max_connections_per_ip: usize,
pub max_messages_per_hour: u32,
pub window_duration: String,
}
impl RateLimitConfig {
pub fn window_duration_seconds(&self) -> anyhow::Result<u64> {
parse_duration(&self.window_duration)
}
}
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct ImapServerConfig {
pub host: String,
pub port: u16,
#[serde(default)]
pub tls_port: Option<u16>,
}
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct JmapServerConfig {
pub host: String,
pub port: u16,
pub base_url: String,
#[serde(default)]
pub push: Option<JmapPushConfig>,
}
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct JmapPushConfig {
#[serde(default)]
pub vapid_key_path: Option<std::path::PathBuf>,
#[serde(default = "default_vapid_admin_email")]
pub admin_email: String,
}
fn default_vapid_admin_email() -> String {
"admin@localhost".to_string()
}
impl Default for JmapPushConfig {
fn default() -> Self {
Self {
vapid_key_path: None,
admin_email: default_vapid_admin_email(),
}
}
}
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct Pop3ServerConfig {
pub host: String,
pub port: u16,
#[serde(default)]
pub tls_port: Option<u16>,
#[serde(default = "default_pop3_timeout")]
pub timeout_seconds: u64,
#[serde(default)]
pub enable_stls: bool,
}
fn default_pop3_timeout() -> u64 {
600
}
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct RelayConfig {
pub host: String,
pub port: u16,
#[serde(default)]
pub username: Option<String>,
#[serde(default)]
pub password: Option<String>,
#[serde(default = "default_use_tls")]
pub use_tls: bool,
}
fn default_use_tls() -> bool {
true
}
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct ConnectionLimitsConfig {
#[serde(default = "default_max_connections_per_ip")]
pub max_connections_per_ip: usize,
#[serde(default = "default_max_total_connections")]
pub max_total_connections: usize,
#[serde(default = "default_idle_timeout")]
pub idle_timeout: String,
#[serde(default = "default_reaper_interval")]
pub reaper_interval: String,
}
impl ConnectionLimitsConfig {
pub fn idle_timeout_seconds(&self) -> anyhow::Result<u64> {
parse_duration(&self.idle_timeout)
}
pub fn reaper_interval_seconds(&self) -> anyhow::Result<u64> {
parse_duration(&self.reaper_interval)
}
}