Skip to main content

qualia_client_core/api/
mail.rs

1//! Local mail product (inbox + SMTP receiver)
2
3#![allow(non_snake_case)]
4
5/// Accept a message into the local inbox (same path as SMTP DATA) — for tests and mesh inject.
6pub fn mail_accept(
7    from: String,
8    to: String,
9    subject: String,
10    body: String,
11    sender_verified: bool,
12) -> Result<serde_json::Value, String> {
13    let r = crate::mail_inbound::accept_message(&from, &to, &subject, &body, sender_verified, None);
14    serde_json::to_value(r).map_err(|e| e.to_string())
15}
16
17/// List local inbox messages (newest first).
18pub fn mail_list(
19    mailbox: Option<String>,
20    include_quarantine: Option<bool>,
21) -> Result<serde_json::Value, String> {
22    let inc = include_quarantine.unwrap_or(true);
23    let list = crate::mail_store::list(mailbox.as_deref(), inc);
24    let (total, unread, quarantine) = crate::mail_store::counts();
25    Ok(serde_json::json!({
26        "messages": list,
27        "counts": { "total": total, "unread": unread, "quarantine": quarantine },
28    }))
29}
30
31pub fn mail_get(id: String) -> Result<serde_json::Value, String> {
32    let m = crate::mail_store::get(&id).ok_or_else(|| format!("unknown message '{id}'"))?;
33    serde_json::to_value(m).map_err(|e| e.to_string())
34}
35
36pub fn mail_set_read(id: String, read: bool) -> Result<serde_json::Value, String> {
37    let m = crate::mail_store::set_read(&id, read)?;
38    serde_json::to_value(m).map_err(|e| e.to_string())
39}
40
41pub fn mail_delete(id: String) -> Result<serde_json::Value, String> {
42    crate::mail_store::delete(&id)?;
43    Ok(serde_json::json!({ "deleted": id }))
44}
45
46/// MX/SPF paste block + local receiver status for a domain.
47pub fn mail_dns_forms(
48    domain: String,
49    mx_host: Option<String>,
50) -> Result<serde_json::Value, String> {
51    Ok(crate::mail_inbound::mail_dns_forms(
52        &domain,
53        mx_host.as_deref(),
54    ))
55}
56
57pub fn mail_receiver_status() -> Result<serde_json::Value, String> {
58    Ok(crate::mail_inbound::receiver_status())
59}
60
61/// Start local SMTP receiver (default `127.0.0.1:2525`). Use `0.0.0.0:2525` for LAN/tunnel.
62#[cfg(not(target_arch = "wasm32"))]
63pub fn mail_receiver_start(bind: Option<String>) -> Result<serde_json::Value, String> {
64    let b = bind.unwrap_or_default();
65    crate::mail_inbound::start_receiver(&b)
66}
67
68#[cfg(not(target_arch = "wasm32"))]
69pub fn mail_receiver_stop() -> Result<serde_json::Value, String> {
70    crate::mail_inbound::stop_receiver()
71}