Skip to content

feat(providers): let a mail message choose its sender - #60

Merged
joaovitoriasilva merged 2 commits into
mainfrom
feat/issue_54
Nov 7, 2026
Merged

joaovitoriasilva merged 2 commits into
mainfrom
feat/issue_54

Conversation

@joaovitoriasilva

Copy link
Copy Markdown
Member

What does this PR do?

Adds MailMessage.from_address: str | None = None. When set, it is the message's sender (the From header, the envelope sender as its bare address, and the Message-ID domain) in place of the configured mail.from_address, which becomes the default.

  • SmtpMail and MemoryMail pass it to build_mime, which validates it with the same parse_address(role="sender") as the configured sender. An invalid value is a ValueError that does not echo it, and the header-injection guarantees are unchanged.
  • It is part of __hash__ and equality.
  • JASIL keeps no allowlist; the relay decides which senders it accepts. The docs, the threat model ("Sender spoofing") and the integration checklist say to take it from the host's own configuration, never from user input.

Additive: a new MailMessage field with a default.

Related issue

Closes #54

Type of change

  • Bug fix
  • New feature (exception during freeze; link prior discussion/acknowledgment)
  • Documentation
  • Refactor / code quality
  • Translation
  • Other (describe below)

Checklist

  • This PR is focused on a single concern
  • An issue was opened and acknowledged before writing this code (if not a small fix)
  • If this PR introduces a new feature during freeze, it was discussed and explicitly acknowledged first
  • The PR is under ~300 lines changed, excluding lock files, migrations, and generated code
  • Tests have been added or updated where applicable
  • Documentation has been updated where applicable
  • Commit messages follow Conventional Commits format

Notes for the reviewer

  • Named from_address, not sender as the issue proposed. It matches MailSettings.from_address, and RFC 5322 has a Sender: header with a different meaning.
  • An empty string is refused, not treated as "use the default". Only None falls back, so a host bug that produces "" fails loudly.
  • Out of scope: a bounce (envelope) address separate from From, which bulk senders sometimes want. It can be added when a host needs it.
  • Conflicts: this PR will conflict with feat(providers): tell a caller why a mail send failed and whether it may have been delivered #59 in SmtpMail.send and CHANGELOG.md. I'll rebase whichever merges second.

Checks run: ruff, ruff format, lint-imports, mypy, pytest (3656 passed, 139 skipped, 97.79% coverage), check_module_coverage.py, check_docs_api.py.

🤖 Generated with Claude Code

MailMessage.from_address sets the From header, envelope sender and
Message-ID domain of one message; the configured mail.from_address
becomes the default. Named from_address rather than sender to match
MailSettings and avoid confusion with the RFC 5322 Sender header.

Closes #54

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Nov 6, 2026 •

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 40 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

Learn how review limits work.

Review configuration:

Run configuration

  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 37390dd6-6c65-43a3-9a52-e423184b38c4
Commits

Reviewing files that changed from the base of the PR and between d7d77a9 and 539c252.

Files selected for processing: 10

  • CHANGELOG.md
  • docs/configuration.md
  • docs/providers-and-backends.md
  • docs/security/integration-checklist.md
  • docs/security/threat-model.md
  • jasil/backends/mail_memory.py
  • jasil/backends/mail_smtp.py
  • jasil/providers.py
  • jasil/settings.py
  • tests/test_mail.py
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

Share

# Conflicts:
#	CHANGELOG.md
#	docs/providers-and-backends.md
#	jasil/backends/mail_memory.py
#	jasil/backends/mail_smtp.py
@joaovitoriasilva
joaovitoriasilva merged commit f2b4c19 into main Nov 7, 2026
20 checks passed
@joaovitoriasilva
joaovitoriasilva deleted the feat/issue_54 branch November 7, 2026 09:51
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.

[FEATURE]: Per-message sender on MailMessage

1 participant