Skip to content

Commit 7816df8

Browse files
authored
fix(email): address postguard#197 deliverability + show disclosed signer name (#170)
* fix(email): address postguard#197 deliverability + show disclosed signer name - X-PostGuard header now tracks the pg-core version via a new build.rs that parses Cargo.lock, instead of the stale hardcoded "0.1.0". When pg-core releases 1.0, the header auto-bumps on the next build. - Add Reply-To header pointing to the disclosed sender on recipient mail so replies reach the human sender, not the noreply From-address. - Add Auto-Submitted: auto-generated (RFC 3834) on both notification and confirmation mail to suppress responder loops and signal "transactional" to receiving MTAs. - Send multipart/alternative with a hand-authored plain-text branch in addition to HTML (new templates/email/email.txt). - Embed the PostGuard logo as a multipart/related CID inline part instead of fetching https://postguard.eu/pg_logo.png at render time. Kills the HTML-only + remote-image spam fingerprint and keeps the logo rendering even with images-blocked-by-default. - Show the sender's disclosed full name (pbdf.gemeente.personalData.fullname) wherever the bare email used to appear in the body; filter it from the attribute pill list so it doesn't render twice. Deliberately not added: List-Unsubscribe — wrong semantic fit for person-to-person mail, would misrepresent the sender. Refs encryption4all/postguard#197 * build: copy build.rs in Dockerfile and apply rustfmt CI fallout from the previous commit: - The Docker build couldn't run build.rs because it wasn't COPY'd into the planner / builder stages, so env!("PG_CORE_VERSION") had nothing to resolve and the release build failed. Add `COPY build.rs ./build.rs` to both stages. - rustfmt wanted `build_body(...)`'s signature on a single line. Apply. * fix(email): address dobby review on disclosed-name flow - Treat empty disclosed fullname as not disclosed; fall through to the email instead of rendering a blank where the sender appears. - Match the fullname attribute by `.gemeente.personalData.fullname` suffix so the `irma-demo` scheme used in staging also routes through this path. (Previously only `pbdf.gemeente.personalData.fullname` matched.) - Log a warning when `state.sender` is `Some(...)` but doesn't parse as a `Mailbox` — the Reply-To deliverability fix shouldn't silently drop. - Move the `sender_display` docstring from above `build_body` to above `sender_display`. - Extend the `pg-core not found in Cargo.lock` panic in build.rs to mention that PG_CORE_VERSION feeds the X-PostGuard header consumed by the Outlook add-in's OnMessageRead filter. - New tests: demo-scheme name detection, empty-name fallback, and the `Someone` fallback (sender=None, no name). * feat(email): render firstName+lastName from passport/idcard/drivinglicence Extend `sender_display` so the recipient mail can show a real sender name when the signer's Yivi disclosure came from an ID credential instead of the Dutch municipality credential. `FULLNAME_ATYPE_SUFFIX` still wins when present. If absent, the new `take_firstname_lastname_pair` helper scans the disclosed attributes for a `<cred>.firstName` + `<cred>.lastName` pair from one of `pbdf.pbdf.{passport,idcard,drivinglicence}` (and matching `irma-demo.*` variants), and concatenates them. Both attributes are removed from the pill list once consumed, so the recipient doesn't see them rendered twice. Empty values fall through to the bare email, as they already did for the gemeente fullname path. Companion to the postguard-website condiscon change: senders can now satisfy the mandatory name disclosure from any of four credentials, not just gemeente. Without this rendering update, non-Dutch senders would still appear as their bare email in the recipient mail. Tests: 7 new `sender_display_*` cases (per-credential, demo-scheme, preference-order, firstname-only fallback, empty-value fallback). All 24 email tests pass, full `cargo test`: 113/113. * fix(email): use 'PostGuard' as sender display when no name is disclosed When the signer discloses no name, the recipient email now reads 'PostGuard sent you files' instead of showing the raw sender email. Also drop 'via PostGuard' from the subject — it would be redundant when the sender is already 'PostGuard', and is cleaner for named senders too. Renames the two tests that previously asserted the email fallback. * style: cargo fmt
1 parent 2af3ba0 commit 7816df8

6 files changed

Lines changed: 463 additions & 36 deletions

File tree

Dockerfile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ WORKDIR /app
1111
FROM chef AS planner
1212
COPY Cargo.toml ./Cargo.toml
1313
COPY Cargo.lock ./Cargo.lock
14+
COPY build.rs ./build.rs
1415
COPY src ./src
1516
COPY templates ./templates
1617
RUN cargo chef prepare --recipe-path recipe.json
@@ -25,6 +26,7 @@ RUN cargo chef cook --profile ${CARGO_PROFILE} --recipe-path recipe.json
2526
# Copy sources and build the application binary
2627
COPY Cargo.toml ./Cargo.toml
2728
COPY Cargo.lock ./Cargo.lock
29+
COPY build.rs ./build.rs
2830
COPY src ./src
2931
COPY templates ./templates
3032
RUN cargo build --profile ${CARGO_PROFILE} --bin cryptify

build.rs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
fn main() {
2+
println!("cargo:rerun-if-changed=Cargo.lock");
3+
4+
let lock = std::fs::read_to_string("Cargo.lock").expect("Cargo.lock not readable");
5+
let version = lock
6+
.split("[[package]]")
7+
.find_map(|block| {
8+
let mut name = None;
9+
let mut ver = None;
10+
for line in block.lines() {
11+
if let Some(rest) = line.strip_prefix("name = \"") {
12+
name = rest.strip_suffix('"');
13+
}
14+
if let Some(rest) = line.strip_prefix("version = \"") {
15+
ver = rest.strip_suffix('"');
16+
}
17+
}
18+
if name == Some("pg-core") {
19+
ver
20+
} else {
21+
None
22+
}
23+
})
24+
.expect(
25+
"pg-core entry not found in Cargo.lock — PG_CORE_VERSION feeds the \
26+
X-PostGuard mail header that the Outlook add-in's OnMessageRead \
27+
launch event filters on (see src/email.rs::XPostGuard).",
28+
);
29+
30+
println!("cargo:rustc-env=PG_CORE_VERSION={}", version);
31+
}

0 commit comments

Comments
 (0)