Skip to content

Forced From is lost for an unmapped sender after a mapped-address send in the same request (provider handler is a shared singleton) #428

Description

@proskurius

Version: FluentSMTP 2.3.1, WordPress 6.9.7, PHP 8.5, provider Amazon SES (any provider with force_from_email = yes should behave the same).

Setup: one SES connection, sender inform@example.org, "Force From Email" on, set as default; mappings only for inform@ and a fallback connection. Site code and WooCommerce send some mail with From: contact@example.org (unmapped).

Expected: every unmapped From is rewritten to the default connection's sender, as it is for a single send.

Actual: within one request, after a send from the mapped address, later sends from the unmapped address go out with their own From (contact@). Observed on a WooCommerce order: customer mail (forced OK) → site "Welcome" mail from inform@ → admin "New order" mail delivered with From: contact@.

Repro (WP-CLI, one request):

wp_mail('me@example.org', 'A', 'a', ['From: X <contact@example.org>']); // forced → inform@
wp_mail('me@example.org', 'B', 'b', ['From: X <inform@example.org>']);  // mapped
wp_mail('me@example.org', 'C', 'c', ['From: X <contact@example.org>']); // NOT forced → contact@

With an SES IAM key restricted to ses:FromAddress = inform@…, C fails with AccessDenied; with an unrestricted key it is delivered from contact@.

Cause: app/Bindings.php registers every provider handler as a container singleton. fluentMailGetProvider() (app/Functions/helpers.php) caches a driver per From address, but the per-address entries point to the same object; force_from_email_id is added only in the default-connection branch. The mapped send calls setSettings() on the shared object without that key, so the cached entry for the unmapped address no longer carries it, and FluentPHPMailer::send() skips the rewrite. The log still shows the connection's sender (BaseHandler::setFrom() reads sender_email from settings), so the leak is invisible in the FluentSMTP log.

Suggested fix: resolve a fresh handler per lookup ($app->make() without the singleton binding), or re-apply the per-address settings (including force_from_email_id) on every fluentMailGetProvider() hit instead of trusting the cached object.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions