Repository navigation
Backend: email -- SMTP and SES, templates, an outbox, password reset, verification and mailed sign-in codes - #6215
Merged
Merged
Conversation
…y flows on top A mail API for the backend runtime (com.codename1.backend.mail): MailSender and an immutable Mail, MIME written once (quoted-printable, wrapped Base64, encoded words, multipart nesting), and transports chosen by cn1.mail.url -- smtp:// and smtps:// (STARTTLS, PLAIN/LOGIN/XOAUTH2, pipelining, a small connection pool), ses:// over the signed API, memory: for tests and log: for development. Only the transport the application names is linked. With a data source a mail is staged in cn1_mail_outbox inside the caller's transaction and sent after commit, retried with back-off, and buried in cn1_mail_dead when it is refused for good. Templates under templates/mail render through the generated views. Security: password reset, email verification and a mailed sign-in code as a second factor, all on single-use hashed tokens. The generated login page links to the reset page when one is configured. MailCheck runs one body on the JVM and natively against an in-process SMTP server, and on SQLite, PostgreSQL and MySQL; BackendMailTest runs it in CI. Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
Contributor
Cloudflare Preview
|
Contributor
|
Developer Guide build artifacts are available for download from this workflow run:
Developer Guide quality checks: |
Contributor
✅ Continuous Quality ReportTest & Coverage
Static Analysis
Generated automatically by the PR CI workflow. |
Collaborator
Author
|
Compared 231 screenshots: 231 matched. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The backend can now send email, and the security package uses it for the three flows every application ends up writing by hand.
Sending
Mailis immutable and validated inbuild();MailSenderis injected by constructor type.cn1.mail.url=smtp://…,smtps://…,ses://eu-west-1,log:for development andmemory:for tests. The build reads the property and links only that transport.multipart/alternative,relatedandmixednested as needed.templates/mailrender through the generated views; a.txtbeside the.htmlbecomes the plain alternative, otherwise it is derived.Delivery
With a data source,
sendstages the mail incn1_mail_outboxinside the caller's transaction: a rolled back order mails no receipt, and a committed one is sent even if the server stops before the transport answers. Failures retry with back-off; a final refusal moves the mail tocn1_mail_dead. Several servers share the table without sending a mail twice.Counters, a span per send (recipient count, never an address) and a health entry come with it.
Security flows
http.passwordReset(...). The request page answers the same whether or not the account exists; the link is single use and only its hash is stored. The generated login page gains a "Forgot your password?" link whenever a reset page is configured..verifiedEmail()as an authorization rule.Testing
@BackendTestcaptures mail in memory;MailSender.sent()exposes it.MailCheckruns one body on the JVM and natively against an in-process SMTP server that asserts on the bytes received, on SQLite, PostgreSQL and MySQL.BackendMailTestruns it in CI.Docs
A new Mail chapter in the developer guide, and password reset, verification and mailed codes in the Security chapter.
🤖 Generated with Claude Code