Repository navigation
HTML password reset does not work for @yahoo.com accounts #4314
Description
Activity
Just for completeness, this is my html template fragment that does the change your password link:
<a href="{{link}}">Change your password</a>The template itself is a bit more complex with some CSS and styling attached. The email comes to the host
mail.example.comand is pointing back toapi.example.comhost for password reset.That's shitty, what do you use to deliver the emails? Do other emails sent with your provider are equally borked?
I'm using mailgun.com and everywhere else it works as expected (@gmail.com, @icloud.com, ...), it's just the HTML email delivered to @yahoo.com. I had a conversation with mailgun guys where they explained to me that they need to do certain tricks to even deliver the emails to @yahoo.com, meaning yahoo.com is generally probably rather broken in many other ways.
I just want to confirm whether this has something to do with my HTML templates, or is it a wide spread issue. Does it happen for your apps as well @flovilmart? Or you sending just the plaintext variant?
We don't use email login in our apps, so I'm, not sure it is widespread or not. I don'T believe it's an issue with the way we do templates, but perhaps it is.
Geez, they're just encoding the entire thing -_-. That is super weird. We've dealt with yahoo.com issues in the past, particularly with multipart text/html emails, but never saw an issue with them failing to decode links afterwards. For it to be specifically yahoo is a bit suspicious though.
I'm curious, I'm going to take a look and see if something has changed with their handling.
@mman Nothing out of the ordinary for our stuff, links in yahoo look fine. Granted I tested with a direct send, not with mailgun. Just curious, what transfer encodings are being used in the parts of the received email? We run with the following:
// plain Content-Transfer-Encoding: base64 Content-Type: text/plain; charset=UTF-8; format=flowed; delsp=yes // html Content-Transfer-Encoding: quoted-printable Content-Type: text/html; charset=UTF-8From what we've seen encoding with
base64andquoted-printableworks pretty good for us, even on some of the weirder hosts.It's possible that something is being misrepresented, resulting in a failure to properly decode content. We've seen that some providers will do some inferring for things like this, resulting in stuff that seems to work even if it's not quite formatted right.
Maybe there’s some tweaking to do in the html payload / metadatas sent through the mailgun API? That seems bending over backwards.
Perhaps. I just looked and didn't really see anything about setting outgoing encodings from the API, but I think they go to
quoted-printableby default, not really sure though.@mman can you specify what adapter you're using? There's the default and some community ones, and perhaps you have your own too. Knowing how the api is being interacted with would be a start.
I'm using
"parse-server-mailgun": "^2.0.0"as the adapter and copy pasted the config from readme, like this:passwordResetEmail: { subject: 'Password Reset Email', pathPlainText: resolve(__dirname, 'templates/password_reset_email.txt'), pathHtml: resolve(__dirname, 'templates/password_reset_email.html') },So I wonder whether my .html can have some garbage in it that will confuse either parse server, or mailgun, or yahoo...
But given the fact that all other email addresses are working, I bet it's something towards the yahoo.com side...
I'm wondering if that's the case. When I have a moment I'll put together something to test this out against mailgun and see if I can't dig something up or find a way to work around what's going on here.
@mman, this may be a stupid question, but what happens when using mailgun from the JS SDK / another SDK and sending those mails?
@mman I went ahead and setup a little test server with
parse-server-mailgunas the email adapter and sent using the mailgun sandbox api. The link in the final email looked just fine the first time around. Here's a snippet of the plain & html parts.------sinikael-?=_1-15099907682760.5737941825734576 Content-Type: text/plain Content-Transfer-Encoding: 7bit Hi there! This is a request to reset your password. You can use the link here, http://localhost:1337/parse Have a nice day! ------sinikael-?=_1-15099907682760.5737941825734576 Content-Type: text/html Content-Transfer-Encoding: 7bit <body> <h1>Hi there!</h1> <h2>This is a request to reset your password.</h2> <p> You can use the link <a href="http://localhost:1337/parse">here</a>. </p> <p>Have a nice day!</p> </body> ------sinikael-?=_1-15099907682760.5737941825734576--Notice that both part encodings are
7bitand the link is as expected.However I realized that you were dynamically adding the link when you send the email, so I went ahead and did that as well.
<p> You can use the link <a href="{{link}}">here</a>. </p>
Now that caused a problem.
------sinikael-?=_1-15099912063160.9182591906745077 Content-Type: text/plain Content-Transfer-Encoding: 7bit Hi there! This is a request to reset your password. You can use the link here, http://localhost:1337 Have a nice day! ------sinikael-?=_1-15099912063160.9182591906745077 Content-Type: text/html Content-Transfer-Encoding: quoted-printable <body> <h1>Hi there!</h1> <h2>This is a request to reset your = password.</h2> <p> You can use the link <a = href=3D"http://localhost:1337">here</a>. </p> <p>Have a nice day!</p> </body> ------sinikael-?=_1-15099912063160.9182591906745077--The encoding for the html part has now changed to
quoted-printable, probably just a choice they're making because of the characters that are showing up where link is injected.To further verify I wanted to send the same email to gmail to see what happened there. Sure enough the link works! But, looking under the hood...
------sinikael-?=_1-15099920779000.39336503352272967 Content-Type: text/plain Content-Transfer-Encoding: 7bit Hi there! This is a request to reset your password. You can use the link here, http://localhost:1337 Have a nice day! ------sinikael-?=_1-15099920779000.39336503352272967 Content-Type: text/html Content-Transfer-Encoding: quoted-printable <body> <h1>Hi there!</h1> <h2>This is a request to reset your password.</h2> <p> You can use the link <a href=3D"http://localhost:1337">he= re</a>. </p> <p>Have a nice day!</p> </body> ------sinikael-?=_1-15099920779000.39336503352272967--it's still broken!
Although their
quoted-printableencoding approach is slightly different it can be considered equivalent. So, gmail is capable of recognizing and properly decoding the urls back.Ultimately looks like whatever is happening it has to do with the injection being done by mustaches and parse-server-mailgun in the templates you are using. Later I'm going to check exactly where it's causing this, and will see if I can't submit a PR to them to patch this behavior.
After looking a bit further at mustache I found the following in their docs.
All variables are HTML escaped by default. If you want to return unescaped HTML, use the triple mustache: {{{name}}}.
Went ahead and tried this out on my test setup and it worked just fine 👍 .
So that's a moustache issue then!
Reacted by Benjamin Friedman WilsonYep, normal behavior, just need to change the template to get the expected results. Closing this out since that's pretty much it.
@mman let us know that this does actually work for you. I'm expecting it will, but in any case keep us posted!
@montymxb @flovilmart I have now updated both the .txt and .html template to quote all variables using
{{{and}}}and it indeed works as expected and Yahoo users can click the password reset link. Looking at the raw email body it also looks much better. I was not even aware there is mustache involved but I thank you both a lot for your effort +1 +1 +1 +1 :)Looks to me that the docs will need to be updated because I did copy/paste this from somewhere I'm sure...
That's great news! Thanks @montymxb for tracking it down!
Just to follow up, the README at https://github.com/sebsylvester/parse-server-mailgun already mentions that
{{{link}}}needs to be escaped using{{{and}}}. Thanks all for your help.Reacted by Benjamin Friedman Wilsonhahah so it was actually documented! easy to miss though.
Sure thing, and of course it was right there the whole time -_-
Issue Description
Using both plain text and html templates for password reset. Both templates use the
{{link}}macro to expand the password reset link. Works like a charm for all users except for those who have @yahoo.com email address.Yahoo does something to the email while receiving it that the password reset link can not be clicked. This is what I see when opening the raw email message via browser based html email client (the link excerpt):
The plaintext version:
The HTML version:
I'm not sure how to get to the plaintext version of the email, but the HTML version seems garbled and the href is clearly wrong.
Any ideas where this could be coming from? Are you experiencing the same as well?
Steps to reproduce
Create an account for your Parse App using @yahoo.com email address and try to reset your password.
Expected Results
HTML link to change the password be clickable.
Actual Outcome
When reading an email either in the mobile Yahoo Mail app, or via browser based Yahoo Mail, the link is not clickable.
Environment Setup
Server
Database
Logs/Trace
Include all relevant logs. You can turn on additional logging by configuring VERBOSE=1 in your environment.