Override settings may be wrong after upgrade from 1.2.x

Created on 8 October 2023, about 1 year ago
Updated 27 October 2023, about 1 year ago

Problem

The problem occurs when upgrading from v1.2.x when both the following conditions are true:

  • symfony_mailer_bc was enabled
  • Some Mailer configuration import operations had been ignored (neither imported or skipped)

For more detail, see #7.

Workaround

Visit the mailer overrides page, and correct the settings - enable or import any overrides that are missing. Warning: this resets any changes you have made to the default configuration.

Proposed resolution

Fix the update hook as described in #8.

Original summary

On Override tab I enabled & imported User items.
And now the user tokens in the password reset emails are not replaced. Only [site:xxx] are replaced.

Explanation why it happens:
Password reset emails provide their own 'user' context token data. And user tokens are replaced AFTER text formatters are applied to the text.
If text formatters use "Replace tokens" with "Replace empty values" option checked, tokens will be deleted from text and mail provider will have text without tokens already.

What can I do?

๐Ÿ› Bug report
Status

Fixed

Version

1.3

Component

Code

Created by

๐Ÿ‡ท๐Ÿ‡ธSerbia super_romeo Belgrade

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

  • Issue created by @super_romeo
  • Status changed to Postponed: needs info about 1 year ago
  • ๐Ÿ‡ฌ๐Ÿ‡งUnited Kingdom adamps

    It works for me. UserEmailBuilder::build passes the callback user_mail_tokens.

  • after updating to V1.3.2 I seem to have the same issue.
    Tokens are not replaced.
    Even [site:name] is not replaced.
    Any ideas?

  • Status changed to Active about 1 year ago
  • ๐Ÿ‡บ๐Ÿ‡ฆUkraine vlad.dancer Kyiv

    Ok. I had this issue too.
    I think after updating symfony_mailer from 1.2.1 to 1.3.1 the new user policies from symfony_mailer were added but not enabled.
    And LegacyEmailBuilder was used in symfony_mailer_mailer_builder_info_alter to build emails with user policies because override_manager->isEnabled can't find overrides in $\Drupal\symfony_mailer\Processor\OverrideManager::isEnabled $this->configFactory->get('symfony_mailer.settings')->get('override').

    So @nojj is right in order to fix this issue we need to enable/disable user policies override.

  • ๐Ÿ‡บ๐Ÿ‡ฆUkraine vlad.dancer Kyiv

    Changing priority since register user/restore password features are very important on many sites.

  • Status changed to Postponed: needs info about 1 year ago
  • ๐Ÿ‡ฌ๐Ÿ‡งUnited Kingdom adamps

    I still don't understand how to reproduce the bug. #3 talks about User Registration Password. #4 talks about updating from v1.2. Neither one has a precise sequence of steps I can follow. The issue summary is totally missing the "Steps to reproduce" section which is essential for a bug report.

    The following are both by design, not a bug

    1. Overrides are disabled by default
    2. If the user override is disabled then tokens won't work in a Mailer Policy - that's mixing up the old and new way of doing things
  • Status changed to Active about 1 year ago
  • ๐Ÿ‡บ๐Ÿ‡ฆUkraine vlad.dancer Kyiv

    I think there will be more bug reports in this issue.
    I came to this issue when detected that user related emails were with raw tokens. But other people can detect this issue on different emails.

    Steps to reproduce:

    • 1. Install latest drupal 9. Installing Drupal โ†’
    • 2. (optional) Install mailhog
    • 3. Go to restore password page, restore password and expect to receive email with token replaced.
    • 4. Install mailer 1.2.1: composer require 'drupal/symfony_mailer:1.2.1' --no-audit. Installing Modules โ†’
    • 5. Enable mailer: drush en symfony_mailer
    • 6. Configure best transport for you as default transport: /admin/config/system/mailer/transport. I'm using mailhog via SMTP.
    • 7. Go to restore password page, restore password and expect to receive email with token replaced.
    • 8. Enable symfony_mailer_bc: drush en symfony_mailer_bc
    • 10. Now in admin interface there is an error message: "There are Mailer configuration import operations pending: import." (Ignore it in order to reproduce the problem)
    • 11. Go to restore password, expect to receive email with token replaced
    • 12. Install mailer 1.3.1+: composer require 'drupal/symfony_mailer:1.3.1' && drush cr
    • 13. Go to restore password, expect to receive email with token replaced. Instead, email sent now with raw tokens without beeing replaced.

    Summary

    If you used 1.2.1 mailer with symfony_mailer_bc and then updated to 1.3+ using drush (without visiting admin interface) you'll end up with having mailer policies but with disabled overrides for them:

    default_transport: sendmail
    override: {}
    

    Suggested way to fix

    Provide runtime check in symfony_mailer_requirements to compare if mail policies exist and symfony_mailer.settings.override is empty.
    If that was detected then suggest user to re-enable policy overrides or delete that policies.

    Let me know if you need additional information or access to the test drupal instance.

  • ๐Ÿ‡บ๐Ÿ‡ฆUkraine vlad.dancer Kyiv
  • ๐Ÿ‡ฌ๐Ÿ‡งUnited Kingdom adamps

    Great thanks for a detailed report and excellent debugging. The override setting is initialised in symfony_mailer_update_10008(). However if there was never any import or skip, then the old import key-value wasn't set, so the update hook doesn't work.

    It's perfectly allowed to have a policy but no override. The policy could be to add a bcc, skip sending the message, or log it. So we can't rely on existing policy. Also we can't assume the overrides available now were also available in v1.2 as this module added commerce in v1.3.

    I believe the correct fix is in the update hook.

    1. If symfony_mailer_bc is enabled then call OverrideManager::getInfo() to get a list of available overrides.
    2. Calculate the intersection of this with the overrides that were available in symfony_mailer_bc: contact, contact_form, simplenews_newsletter, simplenews, update, user, user_registrationpassword.
    3. If these are missing then set them to STATE_ENABLED.
  • ๐Ÿ‡บ๐Ÿ‡ฆUkraine vlad.dancer Kyiv

    Here is requirement check that can inform users to delete odd policies manually:

    if ($phase == 'runtime' || $phase == 'update') {
        $version = \Drupal::service("extension.list.module")->getExtensionInfo('symfony_mailer')['version'] ?? 0;
        $affectedVersion = version_compare($version, '1.3.0', '>=');
    
        if ($affectedVersion) {
          $overrides = \Drupal::configFactory()->get('symfony_mailer.settings')->get("override") ?? FALSE;
          /** @var \Drupal\symfony_mailer\Entity\MailerPolicy[] $policies */
          $policies = \Drupal::entityTypeManager()->getListBuilder('mailer_policy')->load();
    
          $oddPolicies = [];
    
          /** @var \Drupal\symfony_mailer\Entity\MailerPolicy $entity */
          foreach ($policies as $entity) {
            $hasPolicyOfType = in_array($entity->getType(), ['user', 'update', 'contact']);
            $isDisabled = !isset($overrides[$entity->getType()]) || $overrides[$entity->getType()] === \Drupal\symfony_mailer\Processor\OverrideManagerInterface::STATE_DISABLED;
    
            if ($hasPolicyOfType && $isDisabled) {
              $oddPolicies[] = $entity->id();
            }
          }
    
          $corruptedState = empty($overrides) || count($oddPolicies) > 0;
    
          if ($corruptedState) {
            $args = [
              '@policies_link' => \Drupal\Core\Link::fromTextAndUrl(
                'Symfony Mailer policies overview page',
                \Drupal\Core\Url::fromUserInput('/admin/config/system/mailer', ['absolute' => TRUE])
              )->toString(),
              '@overrides_page' => \Drupal\Core\Link::fromTextAndUrl(
                'Symfony Mailer policy overrides page',
                \Drupal\Core\Url::fromUserInput('/admin/config/system/mailer/override', ['absolute' => TRUE])
              )->toString(),
            ];
    
            $description = t('Visit @policies_link to delete odd policies, or visit @overrides_page to delete in a bulk mode policy overrides of specific type.', $args);
            $requirements['symfony_mailer_wrong_overrides'] = [
              'title' => t('Disabled overrides with custom mailer policies detected'),
              'value' => t('Policies for update: @policies', ['@policies' => implode(', ', $oddPolicies)]),
              'severity' => REQUIREMENT_ERROR,
              'description' => $description,
            ];
          }
        }
      }
    

    BTW: thanks for keeping original summary because lots of people will search by "User tokens in Password reset email are not replaced".

  • Status changed to Needs review about 1 year ago
  • Open in Jenkins โ†’ Open on Drupal.org โ†’
    Core: 9.5.x + Environment: PHP 7.4 & MySQL 5.7
    last update about 1 year ago
    PHPLint Failed
  • ๐Ÿ‡ฌ๐Ÿ‡งUnited Kingdom adamps

    Patch not fully tested yet

  • ๐Ÿ‡ฌ๐Ÿ‡งUnited Kingdom adamps

    #10 is an interesting idea thanks. However (as I said in #9) it's perfectly allowed to have a policy but no override. The policy could be to add a bcc, skip sending the message, or log it.

  • Status changed to Needs work about 1 year ago
  • ๐Ÿ‡บ๐Ÿ‡ฆUkraine vlad.dancer Kyiv

    ParseError: syntax error, unexpected token ";" in /var/www/html/web/modules/contrib/symfony_mailer/symfony_mailer.install on line 202 #0 /var/www/html/web/core/includes/install.inc(87): Drupal\Core\Extension\ModuleHandler->loadInclude()

  • Status changed to Needs review about 1 year ago
  • Open in Jenkins โ†’ Open on Drupal.org โ†’
    Core: 9.5.x + Environment: PHP 7.4 & MySQL 5.7
    last update about 1 year ago
    Patch Failed to Apply
  • ๐Ÿ‡บ๐Ÿ‡ฆUkraine vlad.dancer Kyiv

    Thank you @AdamPS, your fix works for me.

    Just fixed syntax error and notices in your patch:

    Undefined variable $settings symfony_mailer.install:201
    > [error] array_key_exists(): Argument #2 ($array) must be of type array, null given
    > [error] Update failed: symfony_mailer_update_10008

  • Open in Jenkins โ†’ Open on Drupal.org โ†’
    Core: 9.5.x + Environment: PHP 7.4 & MySQL 5.7
    last update about 1 year ago
    Patch Failed to Apply
  • ๐Ÿ‡บ๐Ÿ‡ฆUkraine vlad.dancer Kyiv

    I've copied code from the patch not fully)
    Now should work.

  • Open in Jenkins โ†’ Open on Drupal.org โ†’
    Core: 9.5.x + Environment: PHP 7.4 & MySQL 5.7
    last update about 1 year ago
    Patch Failed to Apply
  • ๐Ÿ‡บ๐Ÿ‡ฆUkraine vlad.dancer Kyiv

    Heh. Hope this is last one.

  • Open in Jenkins โ†’ Open on Drupal.org โ†’
    Core: 9.5.x + Environment: PHP 8.1 & MySQL 5.7
    last update about 1 year ago
    Patch Failed to Apply
  • Open in Jenkins โ†’ Open on Drupal.org โ†’
    Core: 9.5.x + Environment: PHP 7.4 & MySQL 5.7
    last update about 1 year ago
    7 pass
  • ๐Ÿ‡บ๐Ÿ‡ฆUkraine vlad.dancer Kyiv

    Added ending line-feed.

    • AdamPS โ†’ committed e18a2c2a on 1.x
      Issue #3392446 by vlad.dancer, AdamPS: Override settings may be wrong...
  • ๐Ÿ‡ฌ๐Ÿ‡งUnited Kingdom adamps

    Great thanks

  • Status changed to Fixed about 1 year ago
  • ๐Ÿ‡ฌ๐Ÿ‡งUnited Kingdom adamps
  • ๐Ÿ‡ฎ๐Ÿ‡นItaly Giuseppe87

    Am I wrong or this patch approach doesn't consider the case the updates of 1.4.0-beta1 has been done?

    From a quick test setting the version to a previous state, e.g.

    drush ev "\Drupal::service('update.update_hook_registry')->setInstalledVersion('symfony_mailer', 10007);"

    and re-do the updates should work, but please correct me if this it is not right.

  • ๐Ÿ‡ฌ๐Ÿ‡งUnited Kingdom adamps

    For sites that have already upgraded to 1.4.0-beta1, then symfony_mailer_update_10009 has removed the symfony_mailer_bc module, so symfony_mailer_update_10008 would have no effect. I can't see any possible automatic fix as the code can't tell if symfony_mailer_bc was previously installed - sorry.

    The code in #21 should work if you manually enable symfony_mailer_bc again first.

  • ๐Ÿ‡ฎ๐Ÿ‡นItaly Giuseppe87

    Yes, I can confirm that

    drush en symfony_mailer_bc 
    drush ev "\Drupal::service('update.update_hook_registry')->setInstalledVersion('symfony_mailer', 10007);"
    

    fixed the token replacement in my site, even if already run the updates with 1-4.0-beta1.

    Thank you.

  • ๐Ÿ‡จ๐Ÿ‡ญSwitzerland michรจle

    I can confirm #23, too. Thank you!

    But bear in mind, that you have to
    drush en symfony_mailer_bc
    again, after updatedb, as 10007 will disable the module.

  • ๐Ÿ‡ฉ๐Ÿ‡ชGermany kreatIL

    In my case, the method described under #23 also worked. However, afterwards I had to reactivate symfony_mailer_bc and go to admin/config/system/mailer/override and perform "User" > "Enable & Import". Why symfony_mailer_bc now has to be active again, even though it was declared as obsolete, is beyond me.

  • Automatically closed - issue fixed for 2 weeks with no activity.

Production build 0.71.5 2024