Two part problem:
-
Selecting HTML message format and unchecking the "Respect provided e-mail format." option on
/admin/config/swiftmailer/messages
breaks drupal's default email display.All newlines in Drupal's default user account emails (eg the password reset email) are destroyed after being sent with the
swiftmailer.html.twig
formatting because HTML doesn't respect whitespace. Attempting to remedy this via Drupal's UI seems to not be possible because all HTML tags (eg<p>
) added to the message templates on /admin/config/people/accounts appear as escaped (eg<p>
) in the final email.Further, if you have the "Generate alternative plain text version." option checked, and try to add HTML to the Drupal user account email templates, then you end up with the HTML version that is escaped (as mentioned above) and the Plain text version has the HTML tags (ie, the tags are not stripped).
-
Said checkbox's description is unclear and doesn't warn you the site will break.
The header "Content-Type", if available, will be respected if you enable this setting. Settings such as e-mail format ("text/plain" or "text/html") and character set may be provided through this header. Unless your site somehow alters e-mails, enabling this setting will result in all e-mails to be sent as plain text as this is the content type Drupal by default will apply to all e-mails
This explanation is written with a voicing that seems like leaving it unchecked is the right thing to do if you're trying to send HTML emails for everything, which may be factually true and the first step to doing so, but it also breaks the display of your site emails. The description should:
- be less vague (ie, remove word "somehow")
- warn against what happens if you leave it unchecked
- explain more clearly that more steps are required to actually render default messages as if they were HTML instead of plain text,
- explain what those other steps are or where to go look for instructions.
I'd be happy to help write documentation and patches but first, I honestly don't know what the next step is on how to actually fix the problem.
Comment | File | Size | Author |
---|---|---|---|
#32 | interdiff_27-32.txt | 3.42 KB | heddn |
#32 | 2831959-32.patch | 5.52 KB | heddn |
#32 | 2831959-32_tests_only.patch | 2.72 KB | heddn |
Comments
Comment #2
jwilson3Comment #3
jwilson3Comment #4
jwilson3Found one more thing.
If you have HTML selected, "Respect provided e-mail format." unchecked, and "Generate alternative plain text version." checked, and try to add HTML to the Drupal user account email templates, then you end up with an HTML version that is escaped and the Plain text version has the normal HTML (ie, the tags are not stripped).
Comment #5
jwilson3Generalizing the title because this problem isn't just limited to user module but basically any non-custom module that sends email.
Comment #6
jwilson3Comment #7
jwilson3Comment #8
marthinal CreditAttribution: marthinal commentedHi @jwilson3
The problem is when formatting the emails from Swiftmailer module:
This line:
By default if you add HTML for example to reset_password email from the UI, the $body will be a string and that's the problem. IMHO makes sense to escape but we cannot add html to the body for the recovery password emails and others.
Comment #9
jwilson3IMHO if you have permissions to change the email text that is sent out from Drupal via the UI, you're already a trusted user.
What I'm suggesting here is to basically provide a default way to "somehow" mark the HTML as safe.
For example, is there a reason we cannot just mark all the text as valid HTML (running it through an XSS filter instead of HTML::escape) when the user selects this combination of settings: HTML message format + "don't respect email format"?
Comment #10
jhedstromWould it be out of scope for this module to add some handling to core emails (eg, attach a format dropdown to the form, or similar)? I'm not remembering offhand how this was previously handled in D7...
Comment #11
jhedstromComment #12
Boymix81 CreditAttribution: Boymix81 as a volunteer commentedHi,
for me, I have partial HTML in the new user welcome email translations,
I develop the following change to check also partial html (not instanceof MarkupInterface) and now email is correctly html formatted in function
\Drupal\swiftmailer\Plugin\Mail\SwiftMailer::massageMessageBody
Certainly I think there is a best way of mine to do this work.
What do you think ?
I'm not be able to do the overrite of Plugin instead to change your code, could you help me, please ?
Thank you,
Best Regards.
Bye Boymix81.
Comment #13
Boymix81 CreditAttribution: Boymix81 as a volunteer commentedHi,
after your last release of module (version 8.x-1.0-beta1 2017-Feb-16) the update overrides my modify and I had new wrong email.
Now I find like to override your plugin but for me your module non work well if I have a translation of email in HTML, like tell in my last post.
I use the following code.
and I select my plugin in the Mail System configuration.
I attach the email example.
I hope you fix this problem so I not must to do an override Plugin.
Best Regards.
Boymix81.
Comment #14
Pls CreditAttribution: Pls as a volunteer commented@Boymix81, thanks for sharing. Your code works great with HTML format selected, otherwise it wasn't working. Cheers for sharing! :)
Comment #15
weseze CreditAttribution: weseze commentedI'm using this to force HTML output on whatever was inputted as body for the mail: (works great for user mails)
Comment #16
DamienMcKennaBumping this to "major" because it basically breaks core email handling.
Comment #17
milos.kroulik CreditAttribution: milos.kroulik commented#15 works perfectly for me.
Comment #18
hanoiion a
hook_mail_alter() will also help
Comment #19
0Sarah0Al CreditAttribution: 0Sarah0Al commentedIn swiftmailer.html.twig, I used:
{{ body|nl2br }}
It does the job without the need of a hook or a plugin class.
Comment #20
heddnThe attached approach uses the fallback_filter for non-HTML. That filter escapes the markup as long someone hasn't intentionally mucked up their site's fallback filter. The added benefit, is it also converts new lines to brs and converts urls to links. All things I'd want to see in emails.
Comment #21
heddnAnd here are two screenshots of what an HTML message looks like (its using commerce's order template, which is html markup from a twig template). And here's an example email from the core user welcome message.
Comment #22
heddnI wonder if we need to do a check against getApplicableFormat() and confirm we are supposed to send HTML too?
Comment #23
heddnDoing that check. Now we only convert to BRs if someone asks for HTML formatted emails.
Comment #24
webflo CreditAttribution: webflo at UEBERBIT GmbH commentedThe patch looks great and the result even more. Converting Plain Text E-Mails to HTML is a great feature. I wonder if should make the input format configurable? People could add a dedicated format for processing emails.
Comment #25
heddnre #24: I'm +1 for that. What do you think about leaving it a non-UI configurable thing for advanced use cases?
Comment #26
webflo CreditAttribution: webflo at UEBERBIT GmbH commentedYeah, its fine for me. We can expose it later if we need it.
Comment #27
heddnComment #28
webflo CreditAttribution: webflo at UEBERBIT GmbH commentedI would like to see some test coverage for this feature, this important to catch bc breaks later.
Comment #29
webflo CreditAttribution: webflo at UEBERBIT GmbH commentedLets use \Drupal\Component\Utility\Unicode::strlen instead of the plain strlen.
Comment #30
heddnWhat type of test coverage are you looking for? Unit, Kernel, BTB?
Or a test of the update hook?
Comment #31
heddnQuick summary of a chat in Slack.
Add a kernel test (with data provider of html & without html). And only test
massageMessageBody
.Comment #32
heddnHere's a test as requested.
Comment #33
andyg5000I missed #25 and was wondering where the option was in the UI :) I'd support adding a select widget to the message config for this.
Comment #34
webflo CreditAttribution: webflo at UEBERBIT GmbH commentedI think this is RTBC, but we should lower the update hook number. Swiftmailer is currently in version 1.x. It should be something like 8100?
Comment #35
FMB CreditAttribution: FMB commentedIt should indeed be 8101 according to the documentation.
Comment #37
webflo CreditAttribution: webflo at UEBERBIT GmbH commentedThanks to all!
Comment #39
0Sarah0Al CreditAttribution: 0Sarah0Al commentedHi there
Sorry for posting in a closed issue.
I got this error:
"Notice: Undefined index: filter_format in Drupal\swiftmailer\Plugin\Mail\SwiftMailer->massageMessageBody() (line 592 of modules/contrib/swiftmailer/src/Plugin/Mail/SwiftMailer.php)."
After I applied the patch.
So, I am wondering if that line (592) should be rewritten as:
$filter_format = isset($this->config['message']['filter_format']) ? $this->config['message']['filter_format'] : 'plain_text';
??
Thanks
EDIT:
Nevermind, I realized I needed to run 'drush updb'
Sorry for the false alarm.
Comment #40
claudiu.cristeaIt seems that this issue has introduced a bug. See #2948607: Notice: Undefined index: filter_format.
Comment #41
RenrhafSame here, got the error but drush updb resolved it ;)
Comment #42
AdamPS CreditAttribution: AdamPS at AlbanyWeb commentedThe config setting added in #25 is causing confusion and security risk - see #3016912: Add a setting to apply a HTML filter and my response in #8. Setting anything other than plain text might be a security bug.
See https://api.drupal.org/api/drupal/core%21modules%21filter%21filter.modul... which says
We are not doing any validation, and cannot - it is impossible to know which user created the content that is being sent in this email. Therefore to use any format other than the fallback format is breaking the rule quoted above.
Now I think that the intention of #24-26 was that people would set the config value to another format that is guaranteed safe. However people aren't necessarily going to know that.
In fact this patch is hard-coded to use the plain-text format and a site could have created a different format to be the default one then deleted plain-text. Presumably the correct way to get the default format is to call
filter_default_format()
?So perhaps we should remove the config setting and replace it with a call to
filter_default_format()
? I guess there could be a hook to allow altering it??Comment #43
AdamPS CreditAttribution: AdamPS at AlbanyWeb commentedI have raised #3122389: Bugs with format conversion
Comment #44
AdamPS CreditAttribution: AdamPS at AlbanyWeb commentedOK I have analysed this carefully and I have a proposal. The code here works for many people most of the time - or to put it another way it is unreliable and causes problems in some cases.
I have an alternative plan that I believe works for everyone all the time. Hence in the new 2.x branch I propose we back this commit out, and I'm setting needs work as the closest status I can see to try to indicate this.
The comments here include some prominent members of the Drupal community so please drop over to #3122389: Bugs with format conversion and tell me what you think.
Comment #45
AdamPS CreditAttribution: AdamPS at AlbanyWeb commentedOK Setting this one back to fixed. Obviously it was checked-in and solved a practical problem.
Moving forward:
#3122389: Bugs with format conversion will fix some edge cases, mostly HTML messages that look like plain text and vice versa
#3125042: [META] New & improved format conversions asks the wider question whether there might be a better way to solve the problem