feat: rebuild email platform and operations console
This commit is contained in:
@@ -0,0 +1,203 @@
|
||||
use serde::Deserialize;
|
||||
|
||||
/// SMTP 收信服务配置(临时邮箱核心)
|
||||
#[derive(Debug, Deserialize, Clone)]
|
||||
pub struct SmtpConfig {
|
||||
/// 是否启用 SMTP 收信(监听 25 端口)
|
||||
#[serde(default = "default_enabled")]
|
||||
pub enabled: bool,
|
||||
/// 监听地址
|
||||
#[serde(default = "default_listen_host")]
|
||||
pub listen_host: String,
|
||||
/// 监听端口(默认 25)
|
||||
#[serde(default = "default_listen_port")]
|
||||
pub listen_port: u16,
|
||||
/// 本机主机名(SMTP 问候时使用,如 mail.shenjianl.cn)
|
||||
#[serde(default = "default_hostname")]
|
||||
pub hostname: String,
|
||||
/// 允许的收件域名白名单(只收这些域名的邮件)
|
||||
#[serde(default = "default_local_domains")]
|
||||
pub local_domains: Vec<String>,
|
||||
/// 单封邮件最大字节数
|
||||
#[serde(default = "default_max_message_bytes")]
|
||||
pub max_message_bytes: usize,
|
||||
/// 单连接超时秒数
|
||||
#[serde(default = "default_connection_timeout_seconds")]
|
||||
pub connection_timeout_seconds: u64,
|
||||
/// 单封邮件最大收件人数
|
||||
#[serde(default = "default_max_recipients")]
|
||||
pub max_recipients_per_message: u32,
|
||||
|
||||
// ===== 限流(IP 连接 + 发件域 + 收件地址) =====
|
||||
/// 单 IP 每分钟最大连接数
|
||||
#[serde(default = "default_ip_connect_per_min")]
|
||||
pub ip_connect_per_min: u32,
|
||||
/// 单发件域每分钟最大邮件数
|
||||
#[serde(default = "default_domain_per_min")]
|
||||
pub domain_per_min: u32,
|
||||
/// 单收件地址每分钟最大邮件数
|
||||
#[serde(default = "default_rcpt_per_min")]
|
||||
pub rcpt_per_min: u32,
|
||||
/// 单发件人每分钟最大邮件数
|
||||
#[serde(default = "default_sender_per_min")]
|
||||
pub sender_per_min: u32,
|
||||
/// 单(发件域→收件地址)每 10 分钟最大邮件数
|
||||
#[serde(default = "default_pair_per_10min")]
|
||||
pub pair_per_10min: u32,
|
||||
|
||||
// ===== PTR 反查 =====
|
||||
/// 是否要求来源 IP 有有效 PTR 记录
|
||||
#[serde(default = "default_require_ptr")]
|
||||
pub require_ptr: bool,
|
||||
|
||||
// ===== 灰名单 =====
|
||||
#[serde(default = "default_greylist_enabled")]
|
||||
pub greylist_enabled: bool,
|
||||
#[serde(default = "default_greylist_retry_delay_seconds")]
|
||||
pub greylist_retry_delay_seconds: i64,
|
||||
#[serde(default = "default_greylist_entry_ttl_seconds")]
|
||||
pub greylist_entry_ttl_seconds: i64,
|
||||
|
||||
// ===== 滥用评分 =====
|
||||
/// 达到此分数的邮件进入隔离区
|
||||
#[serde(default = "default_quarantine_threshold")]
|
||||
pub quarantine_threshold: i32,
|
||||
#[serde(default = "default_score_weight_subject_code")]
|
||||
pub score_weight_subject_code: i32,
|
||||
#[serde(default = "default_score_weight_spf_fail")]
|
||||
pub score_weight_spf_fail: i32,
|
||||
#[serde(default = "default_score_weight_ptr_missing")]
|
||||
pub score_weight_ptr_missing: i32,
|
||||
#[serde(default = "default_score_weight_bad_attachment")]
|
||||
pub score_weight_bad_attachment: i32,
|
||||
|
||||
// ===== 保留期与配额 =====
|
||||
/// 邮件保留天数(超过自动清理)
|
||||
#[serde(default = "default_email_ttl_days")]
|
||||
pub email_ttl_days: i64,
|
||||
/// 新建临时邮箱默认有效期(小时)
|
||||
#[serde(default = "default_mailbox_ttl_hours")]
|
||||
pub mailbox_ttl_hours: i64,
|
||||
/// 单邮箱最大容量(字节)
|
||||
#[serde(default = "default_mailbox_max_quota_bytes")]
|
||||
pub mailbox_max_quota_bytes: i64,
|
||||
/// 随机生成的邮箱本地部分长度
|
||||
#[serde(default = "default_address_local_part_len")]
|
||||
pub address_local_part_len: usize,
|
||||
/// 邮件正文加密密钥(必须恰好 32 字符;留空则不加密)
|
||||
#[serde(default)]
|
||||
pub body_encryption_key: String,
|
||||
}
|
||||
|
||||
fn default_enabled() -> bool {
|
||||
true
|
||||
}
|
||||
fn default_listen_host() -> String {
|
||||
"0.0.0.0".to_string()
|
||||
}
|
||||
fn default_listen_port() -> u16 {
|
||||
25
|
||||
}
|
||||
fn default_hostname() -> String {
|
||||
"mail.shenjianl.cn".to_string()
|
||||
}
|
||||
fn default_local_domains() -> Vec<String> {
|
||||
vec!["mail.shenjianl.cn".to_string(), "shenjianl.cn".to_string()]
|
||||
}
|
||||
fn default_max_message_bytes() -> usize {
|
||||
1024 * 1024
|
||||
}
|
||||
fn default_connection_timeout_seconds() -> u64 {
|
||||
30
|
||||
}
|
||||
fn default_max_recipients() -> u32 {
|
||||
1
|
||||
}
|
||||
fn default_ip_connect_per_min() -> u32 {
|
||||
20
|
||||
}
|
||||
fn default_domain_per_min() -> u32 {
|
||||
10
|
||||
}
|
||||
fn default_rcpt_per_min() -> u32 {
|
||||
10
|
||||
}
|
||||
fn default_sender_per_min() -> u32 {
|
||||
10
|
||||
}
|
||||
fn default_pair_per_10min() -> u32 {
|
||||
5
|
||||
}
|
||||
fn default_require_ptr() -> bool {
|
||||
true
|
||||
}
|
||||
fn default_greylist_enabled() -> bool {
|
||||
true
|
||||
}
|
||||
fn default_greylist_retry_delay_seconds() -> i64 {
|
||||
300
|
||||
}
|
||||
fn default_greylist_entry_ttl_seconds() -> i64 {
|
||||
86400
|
||||
}
|
||||
fn default_quarantine_threshold() -> i32 {
|
||||
60
|
||||
}
|
||||
fn default_score_weight_subject_code() -> i32 {
|
||||
30
|
||||
}
|
||||
fn default_score_weight_spf_fail() -> i32 {
|
||||
20
|
||||
}
|
||||
fn default_score_weight_ptr_missing() -> i32 {
|
||||
15
|
||||
}
|
||||
fn default_score_weight_bad_attachment() -> i32 {
|
||||
25
|
||||
}
|
||||
fn default_email_ttl_days() -> i64 {
|
||||
7
|
||||
}
|
||||
fn default_mailbox_ttl_hours() -> i64 {
|
||||
24
|
||||
}
|
||||
fn default_mailbox_max_quota_bytes() -> i64 {
|
||||
10 * 1024 * 1024
|
||||
}
|
||||
fn default_address_local_part_len() -> usize {
|
||||
10
|
||||
}
|
||||
|
||||
impl Default for SmtpConfig {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
enabled: default_enabled(),
|
||||
listen_host: default_listen_host(),
|
||||
listen_port: default_listen_port(),
|
||||
hostname: default_hostname(),
|
||||
local_domains: default_local_domains(),
|
||||
max_message_bytes: default_max_message_bytes(),
|
||||
connection_timeout_seconds: default_connection_timeout_seconds(),
|
||||
max_recipients_per_message: default_max_recipients(),
|
||||
ip_connect_per_min: default_ip_connect_per_min(),
|
||||
domain_per_min: default_domain_per_min(),
|
||||
rcpt_per_min: default_rcpt_per_min(),
|
||||
sender_per_min: default_sender_per_min(),
|
||||
pair_per_10min: default_pair_per_10min(),
|
||||
require_ptr: default_require_ptr(),
|
||||
greylist_enabled: default_greylist_enabled(),
|
||||
greylist_retry_delay_seconds: default_greylist_retry_delay_seconds(),
|
||||
greylist_entry_ttl_seconds: default_greylist_entry_ttl_seconds(),
|
||||
quarantine_threshold: default_quarantine_threshold(),
|
||||
score_weight_subject_code: default_score_weight_subject_code(),
|
||||
score_weight_spf_fail: default_score_weight_spf_fail(),
|
||||
score_weight_ptr_missing: default_score_weight_ptr_missing(),
|
||||
score_weight_bad_attachment: default_score_weight_bad_attachment(),
|
||||
email_ttl_days: default_email_ttl_days(),
|
||||
mailbox_ttl_hours: default_mailbox_ttl_hours(),
|
||||
mailbox_max_quota_bytes: default_mailbox_max_quota_bytes(),
|
||||
address_local_part_len: default_address_local_part_len(),
|
||||
body_encryption_key: String::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user