Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
927 changes: 909 additions & 18 deletions src/config.rs

Large diffs are not rendered by default.

16 changes: 9 additions & 7 deletions src/doctor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -179,10 +179,10 @@ pub fn gather_status_with_ops<S: SystemOps>(
let dns = gather_dns_section(config, net);

StatusInfo {
domain: config.domain.clone(),
domain: config.default_domain().to_string(),
data_dir: config.data_dir.to_string_lossy().to_string(),
config_path: crate::config::config_path().to_string_lossy().to_string(),
dkim_selector: config.dkim_selector.clone(),
dkim_selector: config.default_dkim_selector().to_string(),
dkim_key_present,
smtp_running,
client_version,
Expand Down Expand Up @@ -214,34 +214,36 @@ fn gather_dns_section(config: &Config, net: &dyn NetworkOps) -> Option<DnsSectio
None
};

let primary_domain = config.default_domain();
let selector = config.default_dkim_selector();
let results = setup::verify_all_dns(
net,
&config.domain,
primary_domain,
&server_ip,
server_ipv6.as_ref(),
&config.dkim_selector,
selector,
local_dkim_pubkey.as_deref(),
);

let server_ipv6_str = server_ipv6.map(|ip| ip.to_string());
let mut records = setup::generate_dns_records(
&config.domain,
primary_domain,
&server_ip.to_string(),
server_ipv6_str.as_deref(),
local_dkim_pubkey
.as_deref()
.map(|p| format!("v=DKIM1; k=rsa; p={p}"))
.unwrap_or_default()
.as_str(),
&config.dkim_selector,
selector,
);

// Without a local DKIM public key on disk we have no authoritative value
// to suggest in the "→ Add:" hint, so drop the DKIM record and the hint is
// suppressed. The DKIM DNS check itself still runs (it just verifies the
// record exists) and its FAIL/MISSING badge is still rendered.
if local_dkim_pubkey.is_none() {
let dkim_name = format!("{}._domainkey.{}", config.dkim_selector, config.domain);
let dkim_name = format!("{selector}._domainkey.{primary_domain}");
records.retain(|r| !(r.record_type == "TXT" && r.name == dkim_name));
}

Expand Down
5 changes: 3 additions & 2 deletions src/hook.rs
Original file line number Diff line number Diff line change
Expand Up @@ -669,12 +669,13 @@ mod tests {
fn sample_config() -> Config {
force_sandbox_fallback();
Config {
domain: "test.com".to_string(),
domains: vec!["test.com".to_string()],
data_dir: PathBuf::from("/tmp/aimx-test"),
dkim_selector: "aimx".to_string(),
dkim_selector: Some("aimx".to_string()),
trust: "none".to_string(),
trusted_senders: vec![],
mailboxes: HashMap::new(),
per_domain: std::collections::HashMap::new(),
verify_host: None,
enable_ipv6: false,
signature: None,
Expand Down
5 changes: 3 additions & 2 deletions src/hook_handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -424,12 +424,13 @@ mod tests {
},
);
Config {
domain: "example.com".to_string(),
domains: vec!["example.com".to_string()],
data_dir: data_dir.to_path_buf(),
dkim_selector: "aimx".to_string(),
dkim_selector: Some("aimx".to_string()),
trust: "none".to_string(),
trusted_senders: vec![],
mailboxes,
per_domain: std::collections::HashMap::new(),
verify_host: None,
enable_ipv6: false,
signature: None,
Expand Down
5 changes: 3 additions & 2 deletions src/hook_list_handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -184,12 +184,13 @@ mod tests {
},
);
Config {
domain: "example.com".to_string(),
domains: vec!["example.com".to_string()],
data_dir: data_dir.to_path_buf(),
dkim_selector: "aimx".to_string(),
dkim_selector: Some("aimx".to_string()),
trust: "none".to_string(),
trusted_senders: vec![],
mailboxes,
per_domain: std::collections::HashMap::new(),
verify_host: None,
enable_ipv6: false,
signature: None,
Expand Down
10 changes: 6 additions & 4 deletions src/ingest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1341,12 +1341,13 @@ mod tests {
},
);
Config {
domain: "test.com".to_string(),
domains: vec!["test.com".to_string()],
data_dir: tmp.to_path_buf(),
dkim_selector: "aimx".to_string(),
dkim_selector: Some("aimx".to_string()),
trust: "none".to_string(),
trusted_senders: vec![],
mailboxes,
per_domain: std::collections::HashMap::new(),
verify_host: None,
enable_ipv6: false,
signature: None,
Expand Down Expand Up @@ -3019,12 +3020,13 @@ mod tests {
},
);
let config = Config {
domain: "test.com".to_string(),
domains: vec!["test.com".to_string()],
data_dir: tmp.path().to_path_buf(),
dkim_selector: "aimx".to_string(),
dkim_selector: Some("aimx".to_string()),
trust: "none".to_string(),
trusted_senders: vec![],
mailboxes,
per_domain: std::collections::HashMap::new(),
verify_host: None,
enable_ipv6: false,
signature: None,
Expand Down
9 changes: 5 additions & 4 deletions src/mailbox.rs
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ pub fn create_mailbox(
}

let new_mb = MailboxConfig {
address: format!("{name}@{}", config.domain),
address: format!("{name}@{}", config.default_domain()),
owner: owner.to_string(),
hooks: vec![],
trust: None,
Expand Down Expand Up @@ -553,7 +553,7 @@ fn resolve_create_owner(
}
return Ok(o.to_string());
}
let address = format!("{name}@{domain}", domain = config.domain);
let address = format!("{name}@{}", config.default_domain());
crate::setup::prompt_mailbox_owner(&address, sys)
}

Expand Down Expand Up @@ -1065,12 +1065,13 @@ mod tests {
);
}
Config {
domain: "agent.example.com".into(),
domains: vec!["agent.example.com".into()],
data_dir: std::path::PathBuf::from("/tmp/test"),
dkim_selector: "aimx".into(),
dkim_selector: Some("aimx".into()),
trust: "none".into(),
trusted_senders: vec![],
mailboxes,
per_domain: std::collections::HashMap::new(),
verify_host: None,
enable_ipv6: false,
signature: None,
Expand Down
7 changes: 4 additions & 3 deletions src/mailbox_handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -381,7 +381,7 @@ fn handle_create(
// resolved-side chown uses this MailboxConfig so a future
// `config.toml` reload would still agree with the on-disk owner.
let mut new_config: Config = (*current).clone();
let address = format!("{name}@{}", new_config.domain);
let address = format!("{name}@{}", new_config.default_domain());
let mb_cfg = MailboxConfig {
address,
owner: owner.to_string(),
Expand Down Expand Up @@ -638,12 +638,13 @@ mod tests {
},
);
Config {
domain: "example.com".to_string(),
domains: vec!["example.com".to_string()],
data_dir: data_dir.to_path_buf(),
dkim_selector: "aimx".to_string(),
dkim_selector: Some("aimx".to_string()),
trust: "none".to_string(),
trusted_senders: vec![],
mailboxes,
per_domain: std::collections::HashMap::new(),
verify_host: None,
enable_ipv6: false,
signature: None,
Expand Down
5 changes: 3 additions & 2 deletions src/mailbox_list_handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -241,12 +241,13 @@ mod tests {
},
);
Config {
domain: "example.com".to_string(),
domains: vec!["example.com".to_string()],
data_dir: data_dir.to_path_buf(),
dkim_selector: "aimx".to_string(),
dkim_selector: Some("aimx".to_string()),
trust: "none".to_string(),
trusted_senders: vec![],
mailboxes,
per_domain: std::collections::HashMap::new(),
verify_host: None,
enable_ipv6: false,
signature: None,
Expand Down
9 changes: 6 additions & 3 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -197,9 +197,12 @@ fn dispatch_with_config(
match cmd {
Command::Ingest { rcpt } => ingest::run(&rcpt, config),
Command::Hooks(cmd) => hooks::run(cmd, config),
Command::DkimKeygen { selector, force } => {
dkim::run_keygen(&config::dkim_dir(), &config.domain, &selector, force)
}
Command::DkimKeygen { selector, force } => dkim::run_keygen(
&config::dkim_dir(),
config.default_domain(),
&selector,
force,
),
Command::Serve {
bind,
tls_cert,
Expand Down
5 changes: 3 additions & 2 deletions src/mcp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1907,12 +1907,13 @@ mod auth_tests {
);
}
Config {
domain: "agent.example.com".into(),
domains: vec!["agent.example.com".into()],
data_dir: tmp.to_path_buf(),
dkim_selector: "aimx".into(),
dkim_selector: Some("aimx".into()),
trust: "none".into(),
trusted_senders: vec![],
mailboxes,
per_domain: std::collections::HashMap::new(),
verify_host: None,
enable_ipv6: false,
signature: None,
Expand Down
2 changes: 1 addition & 1 deletion src/portcheck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -404,7 +404,7 @@ mod tests {
fn config_without_verify_address_parses() {
let toml_str = "domain = \"test.com\"\n[mailboxes]\n";
let config: Config = toml::from_str(toml_str).unwrap();
assert_eq!(config.domain, "test.com");
assert_eq!(config.domains, vec!["test.com".to_string()]);
}

#[test]
Expand Down
17 changes: 10 additions & 7 deletions src/send_handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ where
// MAILBOX-CREATE/DELETE that lands after this point still runs; the
// swap just doesn't affect the decision for *this* particular send.
let config = ctx.config_handle.load();
let primary_domain = config.domain.as_str();
let primary_domain = config.default_domain();
let mailboxes = config.mailboxes.iter().map(|(name, mb)| {
(
name.clone(),
Expand Down Expand Up @@ -805,12 +805,13 @@ mod tests {
},
);
let config = crate::config::Config {
domain: "example.com".to_string(),
domains: vec!["example.com".to_string()],
data_dir: dir.clone(),
dkim_selector: "aimx".to_string(),
dkim_selector: Some("aimx".to_string()),
trust: "none".to_string(),
trusted_senders: vec![],
mailboxes,
per_domain: std::collections::HashMap::new(),
verify_host: None,
enable_ipv6: false,
signature: None,
Expand Down Expand Up @@ -1425,12 +1426,13 @@ mod tests {
},
);
let config = crate::config::Config {
domain: "example.com".into(),
domains: vec!["example.com".into()],
data_dir: data_dir.path().to_path_buf(),
dkim_selector: "aimx".into(),
dkim_selector: Some("aimx".into()),
trust: "none".into(),
trusted_senders: vec![],
mailboxes,
per_domain: std::collections::HashMap::new(),
verify_host: None,
enable_ipv6: false,
signature: None,
Expand Down Expand Up @@ -1489,12 +1491,13 @@ mod tests {
},
);
let config = crate::config::Config {
domain: "example.com".to_string(),
domains: vec!["example.com".to_string()],
data_dir: data_dir.clone(),
dkim_selector: "aimx".to_string(),
dkim_selector: Some("aimx".to_string()),
trust: "none".to_string(),
trusted_senders: vec![],
mailboxes,
per_domain: std::collections::HashMap::new(),
verify_host: None,
enable_ipv6: false,
signature,
Expand Down
Loading
Loading