Compare commits

..

11 Commits

Author SHA1 Message Date
6a5221ec56 chore(deps): lock file maintenance
Some checks failed
Continuous integration / Check (push) Has been cancelled
Continuous integration / Test Suite (push) Has been cancelled
Continuous integration / Trunk (push) Has been cancelled
Continuous integration / Rustfmt (push) Has been cancelled
Continuous integration / build (push) Has been cancelled
Continuous integration / Disallow unused dependencies (push) Has been cancelled
2025-09-03 02:17:28 +00:00
710e440fbf Merge pull request 'chore(deps): update dependency font-awesome to v7' (#135) from renovate/font-awesome-7.x into master
All checks were successful
Continuous integration / Check (push) Successful in 1m8s
Continuous integration / Test Suite (push) Successful in 1m50s
Continuous integration / Trunk (push) Successful in 7m19s
Continuous integration / Rustfmt (push) Successful in 45s
Continuous integration / build (push) Successful in 2m22s
Continuous integration / Disallow unused dependencies (push) Successful in 2m18s
Reviewed-on: #135
2025-09-02 19:01:38 -07:00
af48dff922 chore(deps): update dependency font-awesome to v7
All checks were successful
Continuous integration / Check (push) Successful in 1m18s
Continuous integration / Test Suite (push) Successful in 2m37s
Continuous integration / Trunk (push) Successful in 1m1s
Continuous integration / Rustfmt (push) Successful in 40s
Continuous integration / build (push) Successful in 3m11s
Continuous integration / Disallow unused dependencies (push) Successful in 2m14s
2025-09-02 22:00:56 +00:00
cbe7dbed96 Merge pull request 'chore(deps): lock file maintenance' (#150) from renovate/lock-file-maintenance into master
All checks were successful
Continuous integration / Check (push) Successful in 59s
Continuous integration / Test Suite (push) Successful in 1m24s
Continuous integration / Trunk (push) Successful in 56s
Continuous integration / Rustfmt (push) Successful in 38s
Continuous integration / build (push) Successful in 1m31s
Continuous integration / Disallow unused dependencies (push) Successful in 2m12s
2025-08-21 19:00:55 -07:00
6b011e0ffa chore(deps): lock file maintenance
All checks were successful
Continuous integration / Check (push) Successful in 2m0s
Continuous integration / Test Suite (push) Successful in 4m12s
Continuous integration / Trunk (push) Successful in 7m13s
Continuous integration / Rustfmt (push) Successful in 40s
Continuous integration / build (push) Successful in 4m6s
Continuous integration / Disallow unused dependencies (push) Successful in 2m28s
2025-08-22 00:32:11 +00:00
ab1862db2d chore: Release
All checks were successful
Continuous integration / Check (push) Successful in 51s
Continuous integration / Test Suite (push) Successful in 1m7s
Continuous integration / Trunk (push) Successful in 46s
Continuous integration / Rustfmt (push) Successful in 39s
Continuous integration / build (push) Successful in 1m35s
Continuous integration / Disallow unused dependencies (push) Successful in 2m16s
2025-08-21 17:15:42 -07:00
0afa6da3f2 server: remove unused icalendar dep 2025-08-21 17:15:23 -07:00
f85649dadd cargo fmt 2025-08-21 17:09:57 -07:00
0140fa5efe chore: Release
Some checks failed
Continuous integration / Check (push) Successful in 52s
Continuous integration / Test Suite (push) Successful in 1m9s
Continuous integration / Trunk (push) Successful in 58s
Continuous integration / Rustfmt (push) Failing after 38s
Continuous integration / build (push) Successful in 1m36s
Continuous integration / Disallow unused dependencies (push) Failing after 2m16s
2025-08-21 16:47:03 -07:00
832b322b77 web: much more compact read mail headers 2025-08-21 16:45:35 -07:00
66dbcf2cfd server: style tweak for tls_report summary 2025-08-21 11:21:10 -07:00
9 changed files with 406 additions and 461 deletions

727
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -8,7 +8,7 @@ authors = ["Bill Thiede <git@xinu.tv>"]
edition = "2021"
license = "UNLICENSED"
publish = ["xinu"]
version = "0.17.36"
version = "0.17.38"
repository = "https://git.z.xinu.tv/wathiede/letterbox"
[profile.dev]

View File

@@ -31,10 +31,9 @@ flate2 = "1.1.2"
futures = "0.3.31"
headers = "0.4.0"
html-escape = "0.2.13"
icalendar = "0.17.1"
ical = "0.10"
letterbox-notmuch = { path = "../notmuch", version = "0.17.36", registry = "xinu" }
letterbox-shared = { path = "../shared", version = "0.17.36", registry = "xinu" }
letterbox-notmuch = { path = "../notmuch", version = "0.17.38", registry = "xinu" }
letterbox-shared = { path = "../shared", version = "0.17.38", registry = "xinu" }
linkify = "0.10.0"
lol_html = "2.3.0"
mailparse = "0.16.1"

View File

@@ -1838,7 +1838,6 @@ pub fn render_ical_summary(ical_data: &str) -> Result<String, ServerError> {
Ok(summary_parts.join("<hr>"))
}
fn parse_ical_datetime_tz(dt: &str, tz: Tz) -> Option<chrono::DateTime<Tz>> {
let dt = dt.split(':').last().unwrap_or(dt);
if let Ok(ndt) = chrono::NaiveDateTime::parse_from_str(dt, "%Y%m%dT%H%M%SZ") {

View File

@@ -1,8 +1,10 @@
<!DOCTYPE html>
<html>
<head>
<title>TLS Report</title>
</head>
<body>
<h3>TLS Report Summary:</h3>
<p>Organization: {{ report.organization_name }}</p>
@@ -10,34 +12,37 @@
<p>Contact: {{ report.contact_info }}</p>
<p>Report ID: {{ report.report_id }}</p>
<h4>Policies:</h4>
<h4><b>Policies:</b></h4>
{% for policy in report.policies %}
<h5>Policy Domain: {{ policy.policy.policy_domain }}</h5>
<ul>
<li>Policy Type: {{ policy.policy.policy_type }}</li>
<li>Policy String: {{ policy.policy.policy_string | join(", ") }}</li>
<li>Successful Sessions: {{ policy.summary.total_successful_session_count }}</li>
<li>Failed Sessions: {{ policy.summary.total_failure_session_count }}</li>
</ul>
<h5><b>Policy Domain:</b> {{ policy.policy.policy_domain }}</h5>
<ul>
<li><b>Policy Type:</b> {{ policy.policy.policy_type }}</li>
<li><b>Policy String:</b> {{ policy.policy.policy_string | join(", ") }}</li>
<li><b>Successful Sessions:</b> {{ policy.summary.total_successful_session_count }}</li>
<li><b>Failed Sessions:</b> {{ policy.summary.total_failure_session_count }}</li>
</ul>
<ul>
{% for mx_host in policy.policy.mx_host %}
<li>Hostname: {{ mx_host.hostname }}, Failures: {{ mx_host.failure_count }}, Result: {{ mx_host.result_type }}</li>
{% endfor %}
</ul>
<ul>
{% for mx_host in policy.policy.mx_host %}
<li><b>Hostname:</b> {{ mx_host.hostname }}, <b>Failures:</b> {{ mx_host.failure_count }}, <b>Result:</b> {{
mx_host.result_type }}</li>
{% endfor %}
</ul>
<ul>
{% for detail in policy.failure_details %}
<li>Result: {{ detail.result_type }}, Sending IP: {{ detail.sending_mta_ip }}, Failed Sessions: {{ detail.failed_session_count }}
{% if detail.failure_reason_code != "" %}
(Reason: {{ detail.failure_reason_code }})
{% endif %}
</li>
(Receiving IP: {{ detail.receiving_ip }})
(Receiving MX: {{ detail.receiving_mx_hostname }})
(Additional Info: {{ detail.additional_info }})
{% endfor %}
</ul>
<ul>
{% for detail in policy.failure_details %}
<li><b>Result:</b> {{ detail.result_type }}, <b>Sending IP:</b> {{ detail.sending_mta_ip }}, <b>Failed
Sessions:</b> {{ detail.failed_session_count }}
{% if detail.failure_reason_code != "" %}
(<b>Reason:</b> {{ detail.failure_reason_code }})
{% endif %}
</li>
(<b>Receiving IP:</b> {{ detail.receiving_ip }})
(<b>Receiving MX:</b> {{ detail.receiving_mx_hostname }})
(<b>Additional Info:</b> {{ detail.additional_info }})
{% endfor %}
</ul>
{% endfor %}
</body>
</html>

View File

@@ -12,7 +12,7 @@ version.workspace = true
[dependencies]
build-info = "0.0.41"
letterbox-notmuch = { path = "../notmuch", version = "0.17.36", registry = "xinu" }
letterbox-notmuch = { path = "../notmuch", version = "0.17.38", registry = "xinu" }
regex = "1.11.1"
serde = { version = "1.0.219", features = ["derive"] }
sqlx = "0.8.5"

View File

@@ -33,7 +33,7 @@ wasm-bindgen = "=0.2.100"
uuid = { version = "1.16.0", features = [
"js",
] } # direct dep to set js feature, prevents Rng issues
letterbox-shared = { path = "../shared/", version = "0.17.36", registry = "xinu" }
letterbox-shared = { path = "../shared/", version = "0.17.38", registry = "xinu" }
seed_hooks = { version = "0.4.1", registry = "xinu" }
strum_macros = "0.27.1"
gloo-console = "0.3.0"

View File

@@ -4,8 +4,8 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.7.2/css/all.min.css"
integrity="sha512-Evv84Mr4kqVGRNSgIGL/F/aIDqQb7xQ2vcrdIwxfjThSH8CSR7PBEakCr51Ck+w+/U6swU2Im1vVX0SVk9ABhg=="
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/7.0.1/css/all.min.css"
integrity="sha512-2SwdPD6INVrV/lHTZbO2nodKhrnDdJK9/kg2XD1r9uGqPo1cUbujc+IYdlYdEErWNu69gVcYgdxlmVmzTWnetw=="
crossorigin="anonymous" referrerpolicy="no-referrer" />
<link rel="icon" href="https://static.xinu.tv/favicon/letterbox.svg" />
<!-- tall thin font for user icon -->

View File

@@ -901,13 +901,22 @@ fn render_closed_header(msg: &ShowThreadQueryThreadOnEmailThreadMessages) -> Nod
.collect();
let show_x_original_to = !*to_xinu.borrow() && msg.x_original_to.is_some();
let show_delivered_to = !*to_xinu.borrow() && !show_x_original_to && msg.delivered_to.is_some();
let common_style = C!["text-sm", "pr-2", "text-gray-500"];
div![
C!["flex", "p-4", "bg-neutral-800"],
div![avatar],
C!["flex", "bg-neutral-800"],
div![C!["self-center"], avatar],
div![
C!["px-4", "mr-auto"],
span![
C!["font-semibold", "text-sm"],
C![
"mx-2",
"flex-1",
"flex",
"flex-nowrap",
"items-center",
"truncate",
],
div![
C!["font-semibold", "text-white"],
&common_style,
from_detail.as_ref().map(|addr| attrs! {
At::Title => addr
}),
@@ -915,7 +924,7 @@ fn render_closed_header(msg: &ShowThreadQueryThreadOnEmailThreadMessages) -> Nod
],
" ",
IF!(!msg.to.is_empty() => div![
C!["text-xs"],
&common_style,
span![
C!["font-semibold"],
"To: "
@@ -926,7 +935,7 @@ fn render_closed_header(msg: &ShowThreadQueryThreadOnEmailThreadMessages) -> Nod
" "
]),
IF!(!msg.cc.is_empty() => div![
C!["text-xs", "max-w-full", "overflow-clip", "text-ellipsis"],
&common_style,
span![
C!["font-semibold"],
"CC: "
@@ -934,7 +943,7 @@ fn render_closed_header(msg: &ShowThreadQueryThreadOnEmailThreadMessages) -> Nod
cc_addrs
]),
IF!(show_x_original_to => div![
C!["text-xs"],
&common_style,
span![
C!["font-semibold"],
"Original To: "
@@ -953,7 +962,7 @@ fn render_closed_header(msg: &ShowThreadQueryThreadOnEmailThreadMessages) -> Nod
]
]),
IF!(show_delivered_to => div![
C!["text-xs"],
&common_style,
span![
C!["font-semibold"],
"Delivered To: "
@@ -972,27 +981,25 @@ fn render_closed_header(msg: &ShowThreadQueryThreadOnEmailThreadMessages) -> Nod
]
]),
],
span![
C!["text-right"],
msg.timestamp
.map(|ts| div![C!["text-xs", "text-nowrap"], human_age(ts)]),
div![
C!["p-2"],
i![C![
"mx-4",
"read-status",
"far",
if is_unread {
"fa-envelope"
} else {
"fa-envelope-open"
},
]],
ev(Ev::Click, move |e| {
e.stop_propagation();
Msg::SetUnread(id, !is_unread)
})
],
msg.timestamp.map(|ts| div![
C!["text-xs", "text-nowrap", "justify-self-end", "self-center"],
human_age(ts)
]),
div![
i![C![
"m-2",
"read-status",
"far",
if is_unread {
"fa-envelope"
} else {
"fa-envelope-open"
},
]],
ev(Ev::Click, move |e| {
e.stop_propagation();
Msg::SetUnread(id, !is_unread)
})
]
]
}
@@ -1007,7 +1014,7 @@ fn message_render(msg: &ShowThreadQueryThreadOnEmailThreadMessages, open: bool)
};
let from = from.map(|f| f.replace('.', "-").replace('@', "-"));
div![
C!["lg:mb-4"],
C!["pb-1"],
div![
if open {
render_open_header(&msg)