Repository navigation
Conversation
SES requires a non-ASCII display name in From and To as an RFC 2047 encoded word, so "Café Müller" went out as raw UTF-8. formatMailbox now encodes such names and keeps the quoted string for ASCII names. Sender name overrides keep quotes, angle brackets and backslashes inside the escaped name instead of stripping them. The maildev path hands nodemailer a structured address, because nodemailer would quote an encoded word as literal text. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
nodemailer's encodeWord splits a long name on UTF-16 units and keeps surrogate pairs whole only in the emoji range, so a name with a character such as U+20BB7 decoded with replacement characters. The email service now builds the encoded words itself and splits only between code points, at most 45 bytes per word. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Replace the explanatory comments with named constants for the RFC 2047 word layout and the printable-ASCII check. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Merging to
After your PR is submitted to the merge queue, this comment will be automatically updated with its status. If the PR fails, failure details will also be posted here |
nodemailer's Q encoder splits long names on UTF-8 character boundaries and escapes phrase specials itself, so the hand-written base64 framing and code-point splitter go away. The round-trip test now decodes each encoded word on its own, as a mail client does, so a character split across two words fails it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Risk: No findings This change encodes non-ASCII display names as RFC 2047 Q-words in SES Sentinel reviewed |
Problem
Fromheader.Impact
Pays into Grow Workflows through the email activation rate (measured here). In scope: email, Messaging. Expected move: small, up. Run cost: n/a.
Warning
🟡 Merge risk: medium · one-way door: an email sent with a wrong
Fromname stays sent (merge-risk rubric)FromandToheaders throughformatMailbox. A bug there fails or garbles real sends for any team."<>\take a changed branch. Unit and SES-command tests cover each branch. A revert restores the old headers.Changes
=?UTF-8?Q?Caf=C3=A9_M=C3=BCller?= <a@example.com>. Mail clients show "Café Müller".encodeWord, already a dependency. It splits a long name between characters, keeps each word within 75 characters, and escapes"<>,\inside the word.From(SpamAssassinFROM_EXCESS_BASE64).{ name, address }object. Nodemailer encodes it itself, and it would show a pre-encoded word as literal text.How did you test this code?
0d55d35:tsc --noEmitclean, eslint, oxlint and the semgrep security rules clean on the changed files,email.service.test.tsgreen against local Postgres and maildev.Test rationale:
formatMailboxtable, one new row: a non-ASCII name becomes an encoded word. It catches the bug itself. The expected bytes come from the UTF-8 encoding of the name, not from the code.formatMailboxround trip for a long CJK name with 𠮷 and a long emoji name: each word decodes to UTF-8 on its own, as a mail client does, and the joined result must equal the name. It catches a split inside a character: a byte-slicing encoder fails the CJK row, and so did nodemailer's base64 mode.from overridestable: the old "sanitized" row now expects quotes, angle brackets and a backslash kept and escaped. A new row sends a non-ASCII name with quotes. They catch the SES wiring and any return of the stripping.towould cause.Test seams:
formatMailbox, andEmailService.executeSendEmailobserved at the SESSendEmailCommandinput and at the maildev inbox.Owed proofs:
Fromvalues for eight names were each parsed by Python's RFC 5322/2047 header parser. All are 7-bit ASCII and decode to the exact input name with no parser defects.From header at HEAD 0d55d35, decoded by Python's email parser
Release status
Docs update
None. No doc under
docs/covers how the email service formats sender names.🤖 Agent context
Autonomy: Human-driven (agent-assisted)
Agent: Claude Code, Claude Opus 5.5 (
claude-opus-5-5)impact,tdd,/writing-tests,/writing-code-comments,qa-swarm,pr-description,/writing-pr-descriptions,merge-risk.PostHog/posthogfound no other fix for display-name encoding."<>\in a sender name override?FROM_EXCESS_BASE64Involvement: one question answered (merge path), one design pass, a review round and two final reads on the fork draft, two QA swarm rounds here, live-run evidence captured.
🤖 Generated with Claude Code