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

Email Validation #627

Merged
merged 9 commits into from
Mar 1, 2016
Merged

Email Validation #627

merged 9 commits into from
Mar 1, 2016

Conversation

flovilmart
Copy link
Contributor

From #583

@flovilmart flovilmart closed this Feb 24, 2016
@flovilmart flovilmart reopened this Feb 24, 2016
@flovilmart flovilmart closed this Feb 24, 2016
@flovilmart flovilmart reopened this Feb 24, 2016
@flovilmart flovilmart changed the title Mail adapter Email Validation Feb 24, 2016
@facebook-github-bot
Copy link

@flovilmart updated the pull request.

@flovilmart flovilmart closed this Feb 24, 2016
@flovilmart flovilmart reopened this Feb 24, 2016
@flovilmart
Copy link
Contributor Author

@drew-gross I've reopened here with a proper rebase on master.

"" +
"Click here to confirm it:\n" + link;
return sendMail({
to:user.email,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will have to be user.get('email') I believe. Tests for the actual adapter is one thing I had punted on in the original PR :p

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I pass the request body there. so that's a plain JS object.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh man me and @gfosco and @nlutsenko had a big debate about this a couple days ago. Me and @gfosco would rather we give Parse.Objects to adapters and @nlutsenko would rather we give them raw json. Would you like to weigh in on that discussion?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also cc @lacker, since he had an opinion on this yesterday as well.
I feel quite strongly about not requiring people to use Parse.Objects here, since it provides absolutely no benefit.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In push adapter we pass raw objects for the installations.
Passing Parse.Objects would leave the opportunity to CRUD, do we want to allow that?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My standing is that for places where we want to allow CRUD, like in Parse.Cloud things - it makes an absolute sense to do this.
Otherwise, where this is not the intention of the adapter - you can still do it by creating a Parse.Object from JSON object that you get in the adapter, but it's in your best interest to actually not do it.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My standing is that Parse.Object is a more consistent, more well known, and generally better interface for interacting with data, and that if we want to prevent mutations and/or queries in a particular adapter, we should make an immutable version of Parse.Object instead of changing the entire interface.

For the push adapter I would rather have it accept Parse.Installation but I didn't catch that change before it was merged. We can still consistently use Parse.Objects for future adapters if we decide that is the way we want to go.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so the vote is 2 vs 2 we need a tie breaker.

@facebook-github-bot
Copy link

@flovilmart updated the pull request.

@@ -24,7 +24,7 @@ describe('Parse.GeoPoint testing', () => {
});
}
});
});
}, 60000);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the 60000s for? Tried looking up jasmine docs, they're useful for examples but not much of an api reference..

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Timeout on this test. I think this accommodates an old thing, since these tests don't timeout anymore but fail in a flaky way. Meaning - please remove?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pretty sure we have a global 2s timeout for each test already, defined at the top of helper.js

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll remove them, those were to bypass the failures that we had for a while in the geo point tests.

@facebook-github-bot
Copy link

@flovilmart updated the pull request.

1 similar comment
@facebook-github-bot
Copy link

@flovilmart updated the pull request.

super();

if (options && !options.logsFolder) {
throw "FileLoggerAdapter requires logsFolder";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a backwards incompatible change

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes it is, but unlikely to hurt anyone.
in index.js loggerAdapter is defaulted to undefined and logsFolder is the only option.
that would throw only if the user did loggerAdatper: {}

I could remove but it's part of the validation for the adapter loaders

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That seems like a weak justification for breaking compatibility to me. I'd suggest documenting that it's required, and warn if it's not supplied, but not actually fail if it's not supplied.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no problem

@facebook-github-bot
Copy link

@flovilmart updated the pull request.

1 similar comment
@facebook-github-bot
Copy link

@flovilmart updated the pull request.

@@ -18,6 +18,10 @@ export class OneSignalPushAdapter extends PushAdapter {
this.validPushTypes = ['ios', 'android'];
this.senderMap = {};
this.OneSignalConfig = {};
const { oneSignalAppId, oneSignalApiKey } = pushConfig;
if (!oneSignalAppId || !oneSignalApiKey) {
throw "Trying to initialiazed OneSignalPushAdapter without oneSignalAppId or oneSignalApiKey";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typo: initialize

@facebook-github-bot
Copy link

@flovilmart updated the pull request.

// Need direct database access because verification token is not a parse field
return coll.findOne({
username: username,
_email_reset_token: token,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think for compatibility with databases migrated from Parse.com the name needs to be _perishable_token

@drew-gross
Copy link
Contributor

Sweet, looks like this is getting pretty close to ready. Don't forget to resend the email and set emailVerified to false if the user changes their email.

@flovilmart
Copy link
Contributor Author

Oh right! For the UserController, do you want me to support multiple adapters right away?

@facebook-github-bot
Copy link

@flovilmart updated the pull request.

@drew-gross
Copy link
Contributor

I think we can cross that bridge when we get to it. I'm just expressing my concern :p

@flovilmart
Copy link
Contributor Author

I thought about it too, then I remembered 'easily fixable' :)

@tanmays
Copy link

tanmays commented Mar 7, 2016

If all files are located at their original location i.e. parse-server/public_html and parse-server/views you don't need to specify customPages nor modify choose_password file or add any extension to it.

@432player
Copy link

Thank @tanmays

Now I get this error:
Uncaught internal server error. { [Error: ENOENT: no such file or directory, open '/app/node_modules/parse-server/views/choose_password']

I still have the 'public_html' and it's content and 'views' and it's content inside my parse-server-example directory..
I've replaced SERVER_URL with http://medidate.herokuapp.com/parse inside my 'choose_password' file (which is inside views/)

It's like he's not even looking inside my own 'choose_password' file..

@tanmays
Copy link

tanmays commented Mar 7, 2016

If you are using parse-server-example, the public_html and views folder needs to be inside the parse-server dependancy. Their path should be something like this parse-server-example/node_modules/parse-server/views/

There was a bug in v2.1.4 which didn't include these folders with the npm release. You should probably wait for v2.1.5.

@432player
Copy link

@tanmays Thank you for your help. We will wait for the new release as you suggest.
Cheers!

@btate
Copy link

btate commented Mar 7, 2016

Just a heads up. I saw some parse errors with code 100, can't connect to parse API when I was querying from my cloud functions after I set the SERVER_URI in my environment variables. For some reason using the public server url for the serverURL configuration value was causing this. I updated my configuration to use localhost for serverURL and the issue went away. Not sure if this is just a me problem, but if anyone else sees it, try this fix.

serverURL: 'http://localhost:' + port + '/parse',
publicServerURL: process.env.SERVER_URI || 'http://localhost:' + port + '/parse',

@flovilmart
Copy link
Contributor Author

The public server URL should be a public facing URL if you're not developing, otherwise, you can remove process.env.SERVER_URI || and just set it 'http://localhost:' + port + '/parse'

@btate
Copy link

btate commented Mar 7, 2016

The publicServerURL is fine. It was the serverURL that was breaking if it wasn't local host. Just documenting this issue in case anyone else sees it.

@flovilmart
Copy link
Contributor Author

Oh right! Thanks!

@btate btate mentioned this pull request Mar 7, 2016
@thamer898
Copy link

Hello

@drew-gross i have a parse server version 2.1.4 so i want to implement user reset password feature using mailgun can you help me with that ?

Regards

@drew-gross
Copy link
Contributor

Email validation in Parse Server is still experimental. If you want to try it out, you can read this thread to get an idea of how to enable it, but there are no docs yet.

@thamer898
Copy link

Hello @drew-gross

when the reset user password feature will be enabled ?

regards

@432player
Copy link

Hey @drew-gross
Everything's almost working for us for the reset password but as @tanmays says it can't find the relevant files and folders on the parse-server (version 2.1.4). Here is the log from Heroku
Uncaught internal server error. { [Error: ENOENT: no such file or directory, open '/app/node_modules/parse-server/views/choose_password']
Any ideas? Perhaps a timeline for a new version that exposes the files and folders correctly?

@btate
Copy link

btate commented Mar 9, 2016

@432player I got that working by copying the custom files out of my old cloud code and setting the custom pages in my configuration. You could also just download the 2.1.4 branch of parse-server and pull those files out and put them somewhere public. I believe you'll need to follow @tanmays advice about the choose_password file.

@432player
Copy link

Hey @btate thanks for your input! Can you further explain how to copy the custom files (invalid_link.html, password_reset_success.html, verify_email_success.html,choose_password) into the configuration.
And then how to reference them with hope that it will find the files.
Thanks!

@btate
Copy link

btate commented Mar 9, 2016

@432player, you just have to copy those files out of the node module's public_html and view folders and put them somewhere public facing. Then you set the custom page urls in the api configuration.

var api = new ParseServer({
    ...other options
    appName: 'Your app name here',
    publicServerURL: '<same as serverURL>',
    // Optional only if you want to provide you own pages hosted on your web server
    customPages: {
          invalidLink: 'http://yourdomain.com/invalid_link.html',
          verifyEmailSuccess: 'http://yourdomain.com/verify_email_success.html',
          choosePassword: 'http://yourdomain.com/choose_password.html',
          passwordResetSuccess: 'http://yourdomain.com/password_reset_success.html'
    }
});

@432player
Copy link

@btate Is there any way to do so in heroku with the same deployment?

@btate
Copy link

btate commented Mar 9, 2016

@432player my custom pages are in another web application separate from my services application. So you'll have to figure out where public pages go in your node application using parse-server. I'm not sure where they go. I'd imagine there's just a public_html folder or something that node recognizes.

@432player
Copy link

@btate Thank you so much! we finally got this working. You were right indeed.
It's important to know that the public_html folder in the parse-server at this point does not run the html files or is not public facing. which means they are unreachable.
To get this eventually working the html files need to be self hosted somewhere publicly and the links replaced accordingly in the customPages the emailAdapter has.
Cheers! and good luck everyone

@flovilmart
Copy link
Contributor Author

the html_pages should be visible with 2.1.5. But you can still use the customPages as it's nicer!

@mtrezza
Copy link
Member

mtrezza commented Mar 11, 2016

I've set the parse server configuration and made the custom pages publicly accessible. However after sending the form choose_password I always get redirected to the invalid_link page. As if the token was invalid.

Here's the server config:

// Start Parse server
var api = new ParseServer({
    appName: '<removed/>',
    databaseURI: 'mongodb://<removed/>',
    cloud: process.env.CLOUD_CODE_MAIN || __dirname + '/cloud/main.js',
    appId: '<removed/>',
    masterKey: '<removed/>',
    serverURL: 'https://<removed/>/parse',
    publicServerURL: 'https://<removed/>/parse',
    fileKey: '<removed/>',
    filesAdapter: new S3Adapter(<removed/>),
    push: {<removed/>},
    emailAdapter: SimpleMailgunAdapter({
        apiKey: '<removed/>',
        domain: '<removed/>',
        fromAddress: '<removed/>'
    }),
    customPages: {
        invalidLink: 'http://<removed/>/invalid_link.html',
        verifyEmailSuccess: 'http://<removed/>/verify_email_success.html',
        choosePassword: 'http://<removed/>/choose_password.html',
        passwordResetSuccess: 'http://<removed/>/password_reset_success.html'
    }
});

In choose_password I only modified this line to:
var base = 'https://<removed/>/parse';

What am I missing here?

UPDATE: Had a wrong path in the base var in choose_password. ".heroku.com" instead of ".herokuapp.com". Works fine now.

@rafapetter
Copy link

@flovilmart after reading this thread, I still have 2 questions:

  1. when using customPages on another domain, what are the steps? I'm getting those 4 pages, putting them accessible on the new domain and changing the publicServerURL to point to that domain.

  2. when not using customPages, everything is works fine, but is accepting any length of password, any idea on how to restrict to a password policy?

@facebook-github-bot
Copy link

@flovilmart updated the pull request.

@seonman
Copy link

seonman commented Mar 22, 2016

I could successfully enable email verification and reset password by adding required parameters in ParseServer initializer. However, I cannot find how to change the Email Templates (the Text templates to be sent in the email), like "Verification Email Subject", "Verification Email Body", "Password Reset Subject", etc.
Where can I find those files?

@tanmays
Copy link

tanmays commented Mar 26, 2016

@seonman Afaik there's no way to provide templates for reset and welcome email right now. You should probably open up a separate issue as a feature request.

@gowridev
Copy link

gowridev commented Apr 6, 2016

@tanmays I have configured email adapter in parse server. How to write parse cloud code for parse server? do we need to have heroku account for parse cloud code?

@tanmays
Copy link

tanmays commented Apr 7, 2016

@gowridev no need to write cloud code for reset email and verify email functions. For any other custom events you'll probably want to use official mailgun client https://github.com/1lobby/mailgun-js

@techyrajeev
Copy link

Hi @tanmays
is there any way I can provide custom page for verify email and reset password not just verify email success or reset password success pages?
What configuration I need to set up?
Please help.

@AnChiChang
Copy link

AnChiChang commented May 3, 2017

hi @tanmays

I am using parse-server-example.
I had implemented emailAdapter, and customPages. I will receive reset password from mailgun. However, after click the link in the mail. The web display Cannot GET /apps/appid/request_password_reset?token=token&username=username. Therefore, I have to implement my app.get(/request_password_reset) function by myself? or can use Parse Server default html and forms?

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

Successfully merging this pull request may close these issues.