Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HTML password reset does not work for @yahoo.com accounts #4314

Closed
mman opened this issue Nov 3, 2017 · 20 comments
Closed

HTML password reset does not work for @yahoo.com accounts #4314

mman opened this issue Nov 3, 2017 · 20 comments

Comments

@mman
Copy link
Contributor

mman commented Nov 3, 2017

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:

https://api.example.=
com/myappname/apps/unused/request_password_reset?=
token=jQBDc29205uwCHTDDnwQnxUhZ&username=martin.czman%40yahoo=
.com

The HTML version:

<a href=3D"https:&#x2F;&#x2F; api.example.=
com&#x2F; myappname&#x2F;apps&#x2F;unused&#x2F;request_password_reset?=
token&#x3D;jQBDc29205uwCHTDDnwQnxUhZ&amp;username&#x3D;martin.czman%40yahoo=
.com">Change your password</a>

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

    • parse-server version (Be specific! Don't say 'latest'.) : 2.6.5
    • Operating System: N/A
    • Hardware: N/A
    • Localhost or remote server? (AWS, Heroku, Azure, Digital Ocean, etc): Digital Ocean
  • Database

    • MongoDB version: N/A
    • Storage engine: N/A
    • Hardware: N/A
    • Localhost or remote server? (AWS, mLab, ObjectRocket, Digital Ocean, etc): Digital Ocean

Logs/Trace

Include all relevant logs. You can turn on additional logging by configuring VERBOSE=1 in your environment.

@mman
Copy link
Contributor Author

mman commented Nov 3, 2017

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.com and is pointing back to api.example.com host for password reset.

@flovilmart
Copy link
Contributor

That's shitty, what do you use to deliver the emails? Do other emails sent with your provider are equally borked?

@mman
Copy link
Contributor Author

mman commented Nov 3, 2017

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?

@flovilmart
Copy link
Contributor

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.

@montymxb
Copy link
Contributor

montymxb commented Nov 3, 2017

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.

@montymxb
Copy link
Contributor

montymxb commented Nov 3, 2017

@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-8

From what we've seen encoding with base64 and quoted-printable works 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.

@flovilmart
Copy link
Contributor

Maybe there’s some tweaking to do in the html payload / metadatas sent through the mailgun API? That seems bending over backwards.

@montymxb
Copy link
Contributor

montymxb commented Nov 3, 2017

Perhaps. I just looked and didn't really see anything about setting outgoing encodings from the API, but I think they go to quoted-printable by 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.

@mman
Copy link
Contributor Author

mman commented Nov 4, 2017

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...

@montymxb
Copy link
Contributor

montymxb commented Nov 4, 2017

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.

@flovilmart
Copy link
Contributor

@mman, this may be a stupid question, but what happens when using mailgun from the JS SDK / another SDK and sending those mails?

@montymxb
Copy link
Contributor

montymxb commented Nov 6, 2017

@mman I went ahead and setup a little test server with parse-server-mailgun as 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 7bit and 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:&#x2F;&#x2F;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:&#x2F;&#x2F;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:&#x2F;&#x2F;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:&#x2F;&#x2F;localhost:1337">he=
re</a>.
    </p>
    <p>Have a nice day!</p>
</body>
------sinikael-?=_1-15099920779000.39336503352272967--

it's still broken!

Although their quoted-printable encoding 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.

@montymxb
Copy link
Contributor

montymxb commented Nov 6, 2017

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 👍 .

@flovilmart
Copy link
Contributor

So that's a moustache issue then!

@montymxb
Copy link
Contributor

montymxb commented Nov 6, 2017

Yep, 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 montymxb closed this as completed Nov 6, 2017
@mman
Copy link
Contributor Author

mman commented Nov 6, 2017

@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...

@flovilmart
Copy link
Contributor

That's great news! Thanks @montymxb for tracking it down!

@mman
Copy link
Contributor Author

mman commented Nov 6, 2017

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.

@flovilmart
Copy link
Contributor

hahah so it was actually documented! easy to miss though.

@montymxb
Copy link
Contributor

montymxb commented Nov 6, 2017

Sure thing, and of course it was right there the whole time -_-

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants