Problem/Motivation

On a multi-domain install (domain module), a customer books on one domain but receives a confirmation email whose self-service cancel link points at another domain, and whose site name is that other domain's. Following the link leaves the site the customer used.

The mail is not tied to the booking's domain: it is rendered by whichever request advances the workflow to the notification step. When an operator validates a booking from the back office while working on another domain, or when a queued advance runs under cron, that request's context is what the mail sees.

Two things follow. CancelLinkBuilder::cancelUrl() builds the link with Url::fromRoute('yoyaku_order.cancel', ['token' => $token], ['absolute' => TRUE]), and an absolute URL takes its host from the current request context. And any per-domain configuration override, the site name among them, is the one active in that request.

Nothing corrects this today: neither yoyaku nor its Orchestra bridge touches domains (no request context, base URL or domain negotiator anywhere in either), and the transaction records no origin. Its base fields are id, uuid, langcode, tenant, state, locked_expires, reference, created, changed, booker_name, booker_email, skip_constraints, archived, metatag, orchestra_instance, ticket_hash. There is a tenant, but no domain or base URL, so the notification has nothing to switch back to.

To reproduce: install the domain module with at least two domains, book a resource on the first, validate the booking from the back office while browsing the second, then read the confirmation email.

Proposed resolution

Nothing is stored on the transaction. The process instance is what gets advanced elsewhere, and Orchestra needs the same fact for its own notifications, so the origin belongs there: Orchestra records where a run started and offers orchestra.notification_context, and the order notifier dispatches the whole customer notification in that place. One wrap covers the cancel link, the ticket link and QR code, the attached PDF and its branding, and the site name and mail settings a channel reads, because an attachment enricher runs inside the same dispatch.

Deriving the domain from the order's tenant was rejected: one tenant legitimately serves several domains. Operator-facing notifications are deliberately not wrapped here; Orchestra renders those where people work, tracked in #3613775: Task notifications link to whichever site caused the task, not to the one people work on.

Remaining tasks

  • Wrap the customer notification dispatch in the run's origin, with a test. Done in the merge request.
  • Depends on the Orchestra side landing first.

API changes

None in yoyaku: no new field and no new service. OrderNotifier gains a constructor argument.

Issue fork yoyaku-3613368

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

mably created an issue. See original summary.

mably’s picture

Status: Active » Needs review
mably’s picture

Issue summary: View changes
mably’s picture

Status: Needs review » Postponed
mably’s picture

Status: Postponed » Needs review

  • mably committed 6d22b3b2 on 1.x
    fix: #3613368 Notification links and site name come from the request...
mably’s picture

Status: Needs review » Fixed

Now that this issue is closed, review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, credit people who helped resolve this issue.