Skip to content

fix: parse multi-recipient addresses in getSentMail stored copy#288

Closed
moltboie wants to merge 4 commits intohoiekim:mainfrom
moltboie:fix/sent-mail-multi-recipient-287
Closed

fix: parse multi-recipient addresses in getSentMail stored copy#288
moltboie wants to merge 4 commits intohoiekim:mainfrom
moltboie:fix/sent-mail-multi-recipient-287

Conversation

@moltboie
Copy link
Copy Markdown
Contributor

Problem

When sending an email to multiple recipients (e.g., alice@example.com, bob@example.com), getSentMail() wrapped the entire comma-separated string as a single address entry in the stored sent-mail copy:

{ "value": [{ "address": "alice@example.com, bob@example.com" }] }

The actual sending via Mailgun worked correctly (uses addressParser which splits by comma), but the stored copy had incorrect structure.

Fix

Add parseRecipientAddresses() helper that splits by comma and trims each address before storing. Applied to to, cc, bcc value arrays and envelopeTo.

{ "value": [{ "address": "alice@example.com" }, { "address": "bob@example.com" }] }

Note: The existing addressParser export uses { email } format for Mailgun API calls. The new helper uses { address } which matches the Mail type's address format.

Testing

Sent an email to multiple comma-separated recipients — verified stored copy now has correct per-address entries in the value array.

Closes #287

@moltboie
Copy link
Copy Markdown
Contributor Author

Self-Review

Discussion thread status:

Checked:

  • Logic: parseRecipientAddresses() correctly splits comma-separated addresses, trims whitespace, filters empties, and wraps each in { address }. Applied to to, cc, bcc, and envelopeTo. The text field retains the raw string, which is the correct split between human-readable and structured data.
  • Edge cases: Empty string → [] ✅; trailing comma → handled by filter(Boolean) ✅; single address → single-element array ✅.
  • Named addresses: "Alice <alice@example.com>" becomes { address: "Alice <alice@example.com>" } — the name isn't stripped. This matches the old single-address behavior and is consistent with how text is already stored raw. Not a regression.
  • Types: Return type { address: string }[] matches what Mail model's value field expects.
  • saveBuffer refactor: fs.promises.writeFile with new Uint8Array() is the correct async approach and resolves the strict @types/node type issue. mkdirSync({ recursive: true }) is cleaner than the existsSync guard.
  • Security: No new attack surface — address parsing is purely internal.
  • Tests: parseRecipientAddresses is a pure utility function. Logic validated manually (split/trim/filter/map tested via bun -e).

E2E Testing:

  • Started inbox dev server on PR branch fix/sent-mail-multi-recipient-287
  • Tested parseRecipientAddresses directly via bun -e: single, multi, named, empty, trailing-comma — all correct
  • Full compose-to-send E2E not possible in dev (Mailgun not configured), but getSentMail() logic change is contained to the stored copy, not the actual send
  • CI: test ✅ build ✅

Issues found:

  • None

Confidence: High

moltboie and others added 4 commits March 21, 2026 09:39
Replace synchronous writeFileSync wrapped in Promise constructor with
truly async fs.promises.writeFile. Also:
- Use mkdirSync with recursive:true to remove TOCTOU race on dir creation
- Remove unnecessary 'as unknown as Uint8Array' type cast

Closes hoiekim#283
When sending to multiple recipients, getSentMail() was wrapping the
entire comma-separated string as a single address entry. Split by
comma and trim each address before storing.

Adds parseRecipientAddresses() helper used for to/cc/bcc value arrays
and envelopeTo. The existing addressParser export uses { email } format
for Mailgun sending; this new helper uses { address } for Mail storage.

Closes hoiekim#287
@moltboie moltboie force-pushed the fix/sent-mail-multi-recipient-287 branch from c6c5ce1 to 1319d13 Compare March 21, 2026 16:40
@hoiekim hoiekim closed this Mar 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bug: sent mail stores multiple recipients as single address in to/cc/bcc value array

2 participants