Skip to content

Add SMTP send_mail SQL function with configuration and lettre integration#1346

Open
lovasoa wants to merge 2 commits into
mainfrom
add-documented-send_mail-function
Open

Add SMTP send_mail SQL function with configuration and lettre integration#1346
lovasoa wants to merge 2 commits into
mainfrom
add-documented-send_mail-function

Conversation

@lovasoa

@lovasoa lovasoa commented Jul 10, 2026

Copy link
Copy Markdown
Collaborator

Motivation

  • Add server-side ability to send emails from SQL functions by implementing sqlpage.send_mail and exposing SMTP configuration options.
  • Include configuration validation to ensure the SMTP host is a valid host or host:port value and integrate it with the existing app config.

Description

  • Introduce send_mail SQL function implementation in src/webserver/database/sqlpage_functions/functions/send_mail.rs using lettre with optional authentication via stmp_username/stmp_password and host parsing via parse_stmp_host.
  • Add new configuration fields stmp_host, stmp_username, and stmp_password to AppConfig with validation in validate_stmp_host and usage in AppConfig::validate.
  • Register the function metadata via new migration examples/official-site/sqlpage/migrations/75_send_mail.sql and expose the function name in the function list.
  • Add lettre to Cargo.toml and update Cargo.lock with necessary dependencies (lettre, native-tls, openssl, openssl-sys, quoted_printable, nom changes, and related crates), and update configuration.md with SMTP environment variables documentation.

Testing

  • Ran the unit test send_mail_authenticates_to_smtp_server which exercises SMTP authentication against a local fake SMTP server and it passed.
  • Ran the test suite with cargo test which completed successfully (all unit tests passed).

Codex Task

### Motivation
- Provide a built-in `sqlpage.send_mail(...)` SQL function so pages can send plain-text emails from SQL code.
- Allow the SMTP server to be configured via an environment / configuration option so the function can target a deployable SMTP endpoint.

### Description
- Added a new function implementation at `src/webserver/database/sqlpage_functions/functions/send_mail.rs` implementing `sqlpage.send_mail(json)` which accepts a JSON object with required `recipient`, `subject`, and `body` and optional `sender` and `reply_to`, sends the message and returns `sent` on success.
- Registered the function in the SQLPage function registry by adding `send_mail` to `src/webserver/database/sqlpage_functions/functions.rs`.
- Added a configuration option `stmp_host: Option<String>` to `AppConfig` in `src/app_config.rs`, with `parse_stmp_host`/`validate_stmp_host` helpers that accept either `host` or `host:port` and default to port 25 when none is provided; validation is run from `AppConfig::validate`.
- Added `lettre` to `Cargo.toml` and updated `Cargo.lock` to enable SMTP sending, and added official-site documentation and a migration at `examples/official-site/sqlpage/migrations/75_send_mail.sql` describing usage and parameters.
- Documented the `stmp_host` option in `configuration.md`.

### Testing
- Ran `cargo fmt --all`, which completed successfully.
- Ran `git diff --check` which reported no immediate style errors.
- Attempted `cargo clippy --all-targets --all-features -- -D warnings`, but it was blocked by a toolchain/build issue (a dependency `libsqlite3-sys` build script uses the unstable `cfg_select` feature) and did not complete.
- Attempted `cargo test`, but it was similarly blocked by the same `libsqlite3-sys` build-script error and did not complete.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 72e695ec4a

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

.body(mail_request.body.into_owned())
.context("Unable to build email message")?;

let mut mailer_builder = AsyncSmtpTransport::<Tokio1Executor>::builder_dangerous(host).port(port);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Use TLS-capable SMTP transport for authenticated mail

When stmp_username is configured, this still builds the transport with builder_dangerous, whose defaults are plain SMTP without TLS. In practice, common authenticated relays on ports 587/465 require STARTTLS or implicit TLS, so send_mail will fail against them; any relay that does accept AUTH here receives the username/password in cleartext. Use lettre's TLS/STARTTLS builders or expose an explicit TLS mode before attaching credentials.

Useful? React with 👍 / 👎.

Comment thread src/app_config.rs Outdated

/// SMTP server host used by the `sqlpage.send_mail` function.
/// Accepts either a bare host name or `host:port`. Defaults to port 25 when no port is specified.
pub stmp_host: Option<String>,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Rename the SMTP config fields before shipping

The new public configuration keys are spelled stmp_*, which means the environment loader only accepts STMP_HOST/SQLPAGE_STMP_HOST; users setting the conventional SMTP_HOST or SQLPAGE_SMTP_HOST will get the “requires STMP_HOST” error even though they configured SMTP. Because this becomes a documented public API once released, correcting the spelling later would be a breaking config change.

Useful? React with 👍 / 👎.

Rename the misspelled `stmp_*` configuration options to `smtp_*`
and add a new `smtp_tls_mode` option (`starttls`, `tls`, `none`)
to control encryption when connecting to the SMTP server. Reject
credentials in plaintext mode.

Change `sqlpage.send_mail` to return its JSON argument unchanged
on success and update the example to use a local Mailpit SMTP
server via Docker Compose.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 77797c909e

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread Cargo.toml
encoding_rs = "0.8.35"
odbc-sys = { version = "0", optional = true }
regex = "1"
lettre = { version = "0.11", default-features = false, features = ["builder", "smtp-transport", "tokio1", "tokio1-native-tls"] }

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Use a TLS backend Docker images can build and run

In the Docker build path I checked, scripts/setup-cross-compilation.sh only installs/stages gcc, libgcc and make, and the Dockerfile only copies /tmp/sqlpage-libs/* into the busybox runtime image. Enabling lettre's tokio1-native-tls feature here pulls native-tls/openssl-sys, so the Linux Docker builds now need OpenSSL headers/pkg-config at build time and libssl/libcrypto plus trust roots at runtime; without adding those for each target, the published minimal/duckdb images can fail to build or start. Prefer lettre's rustls backend or add the OpenSSL build/runtime dependencies explicitly.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant