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

MailAdapter design #275

Closed
drew-gross opened this Issue Feb 6, 2016 · 72 comments

Comments

Projects
None yet
@drew-gross
Collaborator

drew-gross commented Feb 6, 2016

Hey, we are super excited to see everybody jumping to help with email verification! Since so many people are working on this, I thought it would be a good idea to get everyone working on it together to discuss what the API should look like. We want to have the smallest API possible to reduce the burden on implementers of the interface, while still being enough to satisfy the needs of Parse.

We also want to open the door for implementers of the MailAdapter interface to bring some new innovations to the table, such as customizing the emails content based on fields on the Parse.User object.

I think the ideal interface for a MailAdapter to expose would be a small handful of functions: sendEmailVerificationEmail(user, link) to send the email on signup, and sendPasswordResetEmail(user, link) for password resets. We could also ask the MailAdapter provider to provide the 4 user facing page templates with some other functions such as generateChooseNewPasswordPage(user), generatePasswordChangedPage(user), generateEmailVerifiedPage(user) and generateInvalidLinkPage(user).

To kick off the conversation about what else we might want from this interface, here some ideas to discuss:

A sendPasswordResetSuccess(user) function. A lot of services will email you when you change your password, as a defense against hacking. Maybe the Parse server should also do this.

Should the user facing pages generation be mandatory? We could provide defaults, or choose not to.

Should we think of a way to expose the MailAdapter in Cloud Code? That would increase the burden on the implementer of MailAdapter, as they would have to create a very general purpose interface, but it could also be very useful.

Parse.com implements user facing pages by asking you to provide a link to a template. Should we re-use that concept? It would aid in transitioning off of Parse.com.

Do we want to give the MailAdapter any other information to work with? Like a Parse.Installation object, maybe? We could even give the adapter the full power of the Parse JS SDK, so it can add some features like the ability to write to the user object, so it can, for example, save when the password was last reset. Of course, any MailAdapter can accept data in it's constructor that lets it do that anyway, but we could make it easier.

I'll leave the 3 PRs working on email verification open, and we can take the best ideas from those 3 PRs, plus what we can come up with here.

@taylorstine @jamiechapman @maysale01 @gfosco @nlutsenko @lucianmat @flovilmart

@flovilmart

This comment has been minimized.

Member

flovilmart commented Feb 6, 2016

Top of my mind and architercturally speaking:

Mail requests should be stored in separated objects, leaving just emailVerified in _User.

We should pass the full Parse.User object to the methods, that would allow external implementation to have a better control, tracking of sends etc.. Installation seem irrelevant at that point as it is unlikely to be linked to a particular User.

@flovilmart

This comment has been minimized.

Member

flovilmart commented Feb 6, 2016

The question about the templates begets a bigger question. What is the use case of parse-server? Standalone or as a module. Personally, I'd go the standalone approach, to replicate, and isolate the concerns.

Going the standalone approach, implies that the templates should be provided by configuration. Do we want to go that way?

@drew-gross

This comment has been minimized.

Collaborator

drew-gross commented Feb 6, 2016

I agree with the standalone approach and having the templates provided by choosing a configuration (ie. by choosing a MailAdapter) having the configuration be done in JS at the time of MailAdapter instantiation could be very powerful, and let the power users do awesome things by using an advanced MailAdapter, while also letting the beginner developers get started with a simple MailAdapter that chooses most of the defaults automatically.

Storing mail requests in a separate object is a great idea, but enabling that by default would cause backwards compatibility issues due to existing apps potentially already having data in that place. Making it possible for an advanced MailAdapter that stores requests wherever the user wants sounds like a good idea though.

@gnz00

This comment has been minimized.

Contributor

gnz00 commented Feb 6, 2016

I personally believe that email handling and template rendering are beyond the scope of the Parse Server project. I'm leaning towards Express plugin over standalone.

We could effectively plug this whole issue by adding some CloudCode mechanism to hook into. For example, a user could import a parse-server/cloudcode-mailgun-hooks plugin that automatically registers hooks for certain classes, i.e. email verification, password change notifications, password reset for _User with Mailgun, or write their own handlers with any node library they want.

However, if the consensus is to include some core mailing ability, here is an approach that keeps things flexible https://gist.github.com/maysale01/5390485e676ee3745960. Could also add a locals hook to each template definition:

const myMailTemplates = {
    password_reset: {
        html: require("./views/password_reset_html.js")(dust), // Precompiled dust template
        text: require("./views/password_reset_text.js")(dust),
        locals: function(req) {
            return {
                title: "Some hardcoded stuff",
                name: `${req.user.firstname} ${req.user.lastname}`,
                address: [`${req.user.addr_num} ${req.user.addr_street}`, req.user.addr_city, req.user.addr_state, req.user.addr_zip].join(","),
                tracking: req.Parse.server.analyticsProvider.tracking
            }
        }
    }
};

Sidebar: logic for a shouldSendUserConfirmation shouldn't be baked directly into RestWrite.js (or at least not in the runDatabaseOperation method), rather there should be a step in the handler flow where a model is validated against some configurable constraints. Possibly a system defined afterSave trigger for '_User' that checks configuration to see if email verification is required, a validator service, or model classes with static validate methods.

@flovilmart

This comment has been minimized.

Member

flovilmart commented Feb 7, 2016

Also, for the whole modularization of the project, we should be able to pass a module name, from configuration or command line in order to load a 3rd party adapter when it makes sense.
In this scenario, we could decouple the main package from the adapters, providing base adapters, but letting anyone who wants a sendgrid adapter use that one without actually requiring any code besides the configuration.

@flovilmart

This comment has been minimized.

Member

flovilmart commented Feb 8, 2016

The mail adapter should also provide a simple send method that would take standard parameters.

@drew-gross

This comment has been minimized.

Collaborator

drew-gross commented Feb 8, 2016

That seems reasonable, they would really need to implement that in order to make the other functions anyway.

@corbanb

This comment has been minimized.

Contributor

corbanb commented Feb 16, 2016

Are there any ideas on when this will be merged in for us to start working off of? Seems like its gone quite here for a little bit.

@flovilmart

This comment has been minimized.

Member

flovilmart commented Feb 16, 2016

@corbanb there are multiple concerns about the mail sending architecture and actually adapter architecture in general: in #290.

@rendragon83

This comment has been minimized.

rendragon83 commented Feb 24, 2016

Is this still being worked on or ready? I have been going through all the conversations about this and it looks like all of the other ones have been closed except this one.

@jamiechapman

This comment has been minimized.

jamiechapman commented Feb 24, 2016

@rendragon83 not sure, not much discussion has happened for a couple of weeks regarding this side of things. I guess we probably need to reach a decision soon so we can ensure that password resets etc are working for standalone API server(s).

@taylorstine

This comment has been minimized.

Contributor

taylorstine commented Feb 24, 2016

Let's hop on the green button express with one of these two #250 #583

@corbanb

This comment has been minimized.

Contributor

corbanb commented Feb 26, 2016

+1

@maruthi-wal

This comment has been minimized.

maruthi-wal commented Mar 4, 2016

@flovilmart @gfosco

If any one did the password reset functionality, Please provide me the steps??

I need to implement this feature with my local parse server.

Thanks,
Maruthi.

@drew-gross

This comment has been minimized.

Collaborator

drew-gross commented Mar 4, 2016

Hey, @maruthi-wal, Parse Server 2.1.4 has experimental support for sending password reset emails. Because it's still experimental, it's not documented and could change in the next version. I wouldn't recommend using it in production just yet, but if you want to help us test the feature before marking it as non-experimental, you can set verifyUserEmails: true in your Parse Config, and add an email adapter such as our SimpleMailgunAdapter.

@drew-gross drew-gross closed this Mar 4, 2016

@dcdspace

This comment has been minimized.

dcdspace commented Mar 4, 2016

I use Sendgrid with custom email templates for transactional email via cloud code, so would I be able to send password reset/email verification emails using Sendgrid as oppose to Mailgun? It would be great if I could simply access the url to the reset page and pop that in my email HTML. Thanks!

@drew-gross

This comment has been minimized.

Collaborator

drew-gross commented Mar 5, 2016

That is coming and will be possible by the time password reset becomes non-experimental

@432player

This comment has been minimized.

432player commented Mar 5, 2016

Verification and reset emails not working since migrating my Parse app's MongoDB

I've completed step 1 of my Parse migration by moving to my own MongoDB server. Everything is working fine except emails sent by Parse.com. Again, I've only migrated the DB so the cloud code (and Parse REST API) are still being hosted by Parse.com.

Clicking on any email verification or password reset email link ends with the "Invalid Link" error page. I've confirmed the token and username in the emails are correct.

My only thought is the Parse.com hosted email verification handler is not able to communicate with the external MongoDB server I migrated to (but the the Parse.com REST API is working fine so that doesn't make sense).

A CLUE THOUGH:

I've noticed that the reset link sent to my email worked fine before the migration, and a minute after the migration it creates a new link with a new _perishable_token in the mongoDB and is the same in the new link sent in the email but is an Invalid Link. And the funny part is the link before the migration to mongoDB STILL WORKS. It's like the old _perishable_token before the migration is somehow cached in the Parse server and allows me to even reset the password as many times as I like (each time same old token before the migration) but the new tokens being generated are not being checked in the request_password_reset Rest API function I guess.

Any ideas? Is this happening to anyone else?

@flovilmart

This comment has been minimized.

Member

flovilmart commented Mar 5, 2016

@432player how did you configure parse-server?

@432player

This comment has been minimized.

432player commented Mar 5, 2016

The Parse Server is still running on Parse.com. We havent migrated to our own Parse-Server. We've migrated only the DB to our mLab mongoDB

@hshinde

This comment has been minimized.

hshinde commented Aug 30, 2016

yes, we have tested it with Mandrill. It's working without any issue.

On Tue, Aug 30, 2016 at 9:40 PM, Juan Camilo Guarin Peñaranda <
notifications@github.com> wrote:

Hello. So, is the email verification working by now?


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
#275 (comment),
or mute the thread
https://github.com/notifications/unsubscribe-auth/ABDbL-fn7WMhXCQdAKYiHsir8Go28ngZks5qlFXYgaJpZM4HUxNv
.

@flovilmart

This comment has been minimized.

Member

flovilmart commented Aug 30, 2016

It should be working by now.

Follow the documentation in the wiki if you have any doubts.

@artonragsdale

This comment has been minimized.

artonragsdale commented Aug 30, 2016

I'm no longer on that project so I'm not certain, but I believe it was
fixed.

On Tue, Aug 30, 2016 at 12:09 PM, Juan Camilo Guarin Peñaranda <
notifications@github.com> wrote:

Hello. So, is the email verification working by now?


You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
#275 (comment),
or mute the thread
https://github.com/notifications/unsubscribe-auth/AADYe_dVaV0A6YLAXKQJjn3Obhfel9J5ks5qlFXXgaJpZM4HUxNv
.

@alarrosa14

This comment has been minimized.

alarrosa14 commented Sep 12, 2016

For those looking for custom templates for password reset and verification emails, go to parse-server-mandrill-adapter. v1.2.0 of that adapter supports Mandrill's templates.

@rowntreerob

This comment has been minimized.

rowntreerob commented Sep 30, 2016

FWIW : native parse-server && std-parse-mailgun-adapter working fine in localhost / express testing..

mongo connected to DEV instance on mLab's cloud ( NOT localhost/mongo )

Details of node config ( using heroku's $HOME/proj/.env ) to inject local env...

NOTE: - check for inmail in 'spam' folder.

env:
DATABASE_URI=mongodb://me:34@ds0.mlab.com:13931/beacontst
SERVER_URL=http://localhost:1337/parse
PUBLIC_SERVER_URL=http://localhost:1337/parse
index.js:
new ParseServer({
  databaseURI: databaseUri || 'mongodb:..',
  serverURL: process.env.SERVER_URL || 'https://mighty-id-65221.herokuapp.com/parse',
  verifyUserEmails: true,
  publicServerURL: process.env.PUBLIC_SERVER_URL || 'https://mighty-id-65221.herokuapp.com/parse',
  emailAdapter: {
  module: 'parse-server-simple-mailgun-adapter',
  options: {
    fromAddress: 'no-reply@yayatv.tv',
    domain: 'sandbox2babd8b07fca4fe81e.mailgun.org',
    apiKey: 'key-f16d78'
  }
@gowridev

This comment has been minimized.

gowridev commented Dec 21, 2016

Can we send mail invites using cloud code which uses mail adapter? If possible,could you share sample cloud code?

@majidhassan

This comment has been minimized.

majidhassan commented Dec 22, 2016

@gowridev I'm not sure what exactly you meant with "send mail invites". But I send regular emails using the Mailgun adapter. Here's some sample code:

var Mailgun = require("mailgun-js")({apiKey: mailgun_apikey, domain: mailgun_domain});

function mailgunSend(data, promise) {
    Mailgun.messages().send(data, function (error, body) {
        if (error) {
            promise.reject(error);
        }
        else {
            promise.resolve();
        }
    });
}

var promise = new Parse.Promise();

var data = {
    from: "Some Email <no-reply@somedomain.com>",
    to: "receiver@somedomain.com",
    subject: "Hello",
    html: "<html><body>Hello</body></html>"
};

mailgunSend(data, promise);

Env:
parse-server-mailgun@2.1.12
parse-server@2.2.25-beta.1

@flovilmart

This comment has been minimized.

Member

flovilmart commented Feb 15, 2017

There is a default form for password resets, as long as you provide a mail adapter, this will work

@valdezm

This comment has been minimized.

valdezm commented Feb 15, 2017

Awesome, yeah I see that now, Thanks @flovilmart I appreciate it! My mistake was that I didn't set the following correctly:
publicServerURL: 'https://example.com/parse',

That really should be specified more accurately to be:
publicServerURL: 'https://thestandaloneparseserverURL.com/parse',

I thought it was just what the companies website was, not the actual endpoint that has the form which exists on the ParseServer through that project....

Appreciate your help though, much appreciated!

@funkenstrahlen

This comment has been minimized.

Contributor

funkenstrahlen commented Mar 3, 2017

The parse server guide still says mail verification is not available.

This is not supported out of the box. But, you can use a beforeSave to send out emails using a provider like Mailgun and add logic for verification. Subscribe to this issue to be notified if email verification support is added to Parse Server.
https://parseplatform.github.io/docs/parse-server/guide/

This should be updated.

@Neilpoulin

This comment has been minimized.

Neilpoulin commented Apr 9, 2017

Hi, I have a custom email adapter that uses Amazon's SES for sending emails, and it has been working great for months for password resets. I now want to implement email verification, but am having trouble getting the email to trigger.

I saw one comment from @drew-gross about commenting out any beforeSave or afterSave triggers on the _User object, and tried it. That got the mail to trigger and work as expected. However, I'm hoping that I don't need to remove any before/afterSave hooks to get this feature working. Does anyone have any thoughts on how to get verification emails to send out when using other beforeSave triggers?

@flovilmart

This comment has been minimized.

Member

flovilmart commented Apr 10, 2017

Can you open a specific issue so I can have a look?

@acinader

This comment has been minimized.

Member

acinader commented Apr 10, 2017

@Neilpoulin any interest in open sourcing you're ses adapter? that would be useful for the community.

@Neilpoulin

This comment has been minimized.

Neilpoulin commented Apr 10, 2017

@flovilmart, sure thing, i'll get a separate issue opened to track this specifically.

@acinader, I think that's a great idea. I'll start working on breaking it out into a standalone module.

Thanks for the responses!

@flovilmart

This comment has been minimized.

Member

flovilmart commented May 6, 2017

@Neilpoulin sorry for the late response. Did you open another issue or found what you were looking for?

@ghost

This comment has been minimized.

ghost commented May 9, 2017

Mail verification and password reset are available or not ?

@flovilmart

This comment has been minimized.

Member

flovilmart commented May 9, 2017

Yes they should be, all endpoints are available, configured when your provide a mail adapter.

@ghost

This comment has been minimized.

ghost commented May 9, 2017

Because it tried to add this to my ParseServer configuration in index.js

verifyUserEmails: true,
publicServerURL: process.env.SERVER_URL || 'http://localhost:1337/parse',
appName: 'Parse App',
emailAdapter: {
    module: 'parse-server-simple-mailgun-adapter',
    options: {
        fromAddress: 'MYMAIL',
        domain: 'MYDOMAIN.mailgun.org',
        apiKey: 'APIKEY',
    }
},

And when I reset a password I have this error (node:17) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 2): Error: Forbidden

@ghost

This comment has been minimized.

ghost commented May 9, 2017

I need to add another module ? in package.json

@flovilmart

This comment has been minimized.

Member

flovilmart commented May 9, 2017

Can you provide the logs when running with VERBOSE=1?

@albaqawi

This comment has been minimized.

albaqawi commented Sep 4, 2017

hi @flovilmart and @drew-gross I am following your works here and trying not to drown as I am very new to Swift3 and Heroku/Parse backend..... as many others I want to enable the reset password feature call within parse with (requestPasswordResetForEmailInBackground:block:)

I have my Heroku hosted on node.js platform and not sure what I need to do, as I see many recommend to use mailgun....

the close to a complete answer is @FeleciaGente in post #1063

and I am waiting for @flovilmart response on it...

I really appreciate if you can guide me to a step by step tutorial or how to guide.

thanks

@fadwafb

This comment has been minimized.

fadwafb commented Sep 18, 2017

Do anyone used the simple-parse-smtp-adapter? because it's not working for me, i didn't get any e-mail.

@flovilmart

This comment has been minimized.

Member

flovilmart commented Sep 18, 2017

@fadwafb reach out to to maintainer of this adapter. We don’t maintain it.

@fadwafb

This comment has been minimized.

fadwafb commented Sep 18, 2017

Thank you so much @flovilmart for the answer, so can i use the SendGrid adapter? if not tell which adapters are working?

@flovilmart

This comment has been minimized.

Member

flovilmart commented Sep 18, 2017

I think so, all adapters on the parse-server modules org should be properly functional.

@Abderezai

This comment has been minimized.

Abderezai commented Sep 19, 2017

something is wrong with the simple mail adapter. I tried using my mailgun credentials on an older project that was runing parse + mailgun and the mail was sent no problem. On this new project those credentials are not working.
"express": "^4.13.4",
"kerberos": "~0.0.x",
"parse": "1.10.0",
"parse-dashboard": "~1.1.0",
"parse-server": "2.5.3"

error:
'An appName, publicServerURL, and emailAdapter are required for password reset and email verification functionality.' }

Parse options:
appName: 'Example App',
serverURL: process.env.SERVER_URL,
publicServerUrl: process.env.SERVER_URL,
emailAdapter: {
module: 'parse-server-simple-mailgun-adapter',
options: {
fromAddress: 'noreply@example.com',
domain: 'mailgun.example.com',
apiKey: 'key-####',
}

I tried parse-server-mailgun and same issue

@flovilmart

This comment has been minimized.

Member

flovilmart commented Sep 19, 2017

@Abderezai publicServerUrl seems to have a typo

@Abderezai

This comment has been minimized.

Abderezai commented Sep 19, 2017

Thank you man. And damn dyslexia.
Is there an editor out there that would catch something like this?

@Nes-si

This comment has been minimized.

Nes-si commented Apr 3, 2018

@flovilmart

This comment has been minimized.

Member

flovilmart commented Apr 3, 2018

@Nes-si feel free to open a PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment