‫So, we need to now send
‫the password reset token via email to the user.
‫And so in this lecture, we're gonna learn
‫how to send email using a very popular solution
‫called Nodemailer.
‫But before we do that, I actually wanted to show you
‫the effect of not having this option here,
‫because I actually never showed you before.
‫So let's cut it here, try it now, again,
‫and so now you see all these errors coming up
‫like please confirm your password.
‫And, actually, there should be more,
‫but, well, this is now the first one that you get.
‫Basically, because we don't have any value
‫on the password confirm field.
‫Okay?
‫And so again, that's because of the validation
‫and so again we can, of course, easily
‫turn it off with this option.
‫But anyway, let's now create an email handler function
‫that we can then use throughout our application.
‫So I'm gonna do that right here
‫in the Utilities folder, again,
‫and simply calling it email.js.
‫All right?
‫And before we do anything else,
‫let's actually install the Nodemailer package.
‫So that's the package that I mentioned
‫right in the beginning,
‫which we're gonna use to send email using Node.js.
‫So, as always, npm install nodemailer.
‫And in here.
‫All right, and now let's create that function here.
‫So constant email,
‫okay, and then in here,
‫we're gonna pass in some options basically.
‫So the email address where we want to send an email to,
‫the subject line, the email content,
‫and maybe some other stuff.
‫All right.
‫And so now we need to follow three steps
‫in order to send emails with Nodemailer.
‫So first up, we need to create a transporter.
‫Then second,
‫we need to define the email options, basically,
‫and then in the end,
‫actually send the email with Nodemailer.
‫Okay?
‫So, the transporter that we made in the first step here,
‫is basically a service that will actually send the email,
‫because it's not node.js that will actually
‫send the email itself.
‫It's just a service that we define in here.
‫Something like Gmail, for example.
‫Now, Gmail is not actually the service
‫that we're gonna use,
‫but let me just quickly show you how it works
‫with Gmail, because I know that many people
‫will be interested in this, okay?
‫So, anyway, we need to always create a transporter,
‫and that's always the same,
‫no matter what service we're gonna use.
‫So the transporter will be
‫nodemailer.createTransport
‫and then, of course, we need some options in there.
‫All right?
‫So we can specify the service
‫and we can say that we want to use Gmail.
‫So, just like this.
‫And there are a couple of well-known services
‫that Nodemailer knows how to deal with,
‫and so we don't have to configure these manually.
‫And so Gmail is just one of them.
‫But also there is Yahoo, or Hotmail, or many others, okay?
‫So that's the service,
‫and then we also need to specify the auth property,
‫so basically for authentication.
‫So we need a user and a password.
‫And so just like before,
‫we save that kind of stuff in our config.n file.
‫All right.
‫So email,
‫that's a username,
‫and now I'm not going to use a real Gmail address here
‫because, again, we're not using Gmail,
‫but just as an example here, all right.
‫Your password.
‫All right.
‫So here we're done, say,
‫process
‫dot end dot
‫EMAIL_USERNAME
‫the password process dot end
‫dot EMAIL_PASSWORD
‫and I hope I spelled these correctly.
‫Okay?
‫And so this is the configuration
‫for the transport in Nodemailer.
‫Then in your Gmail account,
‫you will actually have to activate something
‫called the less secure app option.
‫So let me write that down here.
‫And again, I'm not going to do it here,
‫but I know that many people
‫will actually want to use it.
‫And the reason why we're not using Gmail
‫in this application
‫is because Gmail is not at all a good idea
‫for a production app.
‫And so that's basically what we're trying to build here.
‫Okay?
‫So using Gmail for this kind of stuff,
‫you can only send 500 emails per day,
‫and also, you will probably very quickly be marked
‫as a spammer, and from there, it will only go downhill.
‫All right?
‫So, unless it's like a private app,
‫and you just send emails to yourself,
‫or, like, 10 friends,
‫well, then you should use another service.
‫And some well-known ones are SendGrid and Mailgun.
‫And, actually, we will use SendGrid a bit later
‫in this course.
‫Now, what we're gonna do right now
‫is to use a special development service,
‫which basically fakes to send emails to real addresses.
‫But, in reality, these emails end up trapped
‫in a development inbox, so that we can then take a look
‫at how they will look later in production.
‫All right?
‫So that service is called Mailtrap,
‫and so let's now sign up for that.
‫So.
‫Mailtrap.io,
‫all right?
‫So, and as I say, safe email testing
‫for staging and development.
‫So basically, with this service,
‫you can fake to send emails to clients,
‫but these emails will then never reach these clients,
‫and instead be trapped in your Mailtrap, okay?
‫And so that way you cannot accidentally
‫send some development emails to all of your
‫clients or users, okay.
‫So go ahead and sign up now.
‫I, of course, already have my account,
‫and so I will simply log in now.
‫So see you in a second, after you have created
‫your free account.
‫All right, so after creating your account,
‫it will probably look a little bit like this.
‫Now, you won't have any inbox for now,
‫and so let's just create a new one,
‫with the name of natours.
‫So, I already have one, but just create a new one here,
‫with the natours name, and then hit Create Inbox.
‫All right?
‫Then we can open it,
‫and you see we have no email at this point,
‫but what matters for now
‫is these credentials here.
‫So you see we have our host here,
‫we have the port, username, and password.
‫And so that's what we're gonna specify
‫in our transport in Nodemailer now.
‫All right?
‫So let's start with the host,
‫well, actually, with the username,
‫so these two, I just need to copy
‫so let's copy it to our config file,
‫so that's the username,
‫then that's the password,
‫and now we actually also need to specify the host.
‫Okay, and so that's because Mailtrap is not
‫one of these predefined services that comes with Nodemailer.
‫All right.
‫The port is 25.
‫So give it a save,
‫and then in here, let's get rid of this,
‫and what I need to specify instead is the host
‫so email,
‫host,
‫and, of course, the port.
‫So everything that we just saved before.
‫All right, then the authentication here
‫is the exact same.
‫Let's get rid of this as well,
‫and move on to step number two.
‫So basically defining some options for our email.
‫All right, and we could, of course,
‫do step two and three all at the same,
‫but I like to simply prefer these options here first.
‫Okay, and so here we specify
‫where the email is coming from,
‫so the name,
‫and then the email address like this.
‫Next up, we need the recipient's address,
‫and so that one, I'm gonna specify as an option,
‫okay?
‫So basically, coming as an argument to this function.
‫So this options object here,
‫is this one that we pass into the function.
‫All right.
‫Then actually the same for the subject and for the text.
‫Let's just duplicate these here,
‫So the subject and then
‫we just specify the text property,
‫and that one, in the options, I'm just calling it message.
‫All right, so this one is basically
‫the text version of the email.
‫But we can then also specify the HTML property.
‫Okay, and so we could now then convert this message to HTML.
‫And later, we're going to do that, but for now,
‫let's keep it simple and not specify the HTML here, at all.
‫Okay?
‫So simply leaving it at text.
‫Okay!
‫And then finally, at the end,
‫transporter, so that's the transporter object
‫that we created right here in the beginning,
‫and on that, we can then call sendMail
‫and into that we need to pass in our mail options, okay?
‫And now this actually returns a Promise.
‫Okay, so again, this is an asynchronous function,
‫and since we don't want to directly work with Promises,
‫let's use async/await.
‫All right.
‫So declaring this as an async function
‫and there we go.
‫All right.
‫We don't want to store any result here,
‫which we could, but I'm not really interested in that.
‫Okay, and now let's simply export it
‫as the default from this module.
‫Okay, looks good!
‫Now let's now go ahead and actually try this.
‫And so to start, we need to import it here, of course.
‫So let's just duplicate this here,
‫so this is email,
‫and the function is called sendEmail I think.
‫Okay.
‫So let's go back to our middleware function here,
‫and let's start by defining the reset URL.
‫So, ideally, the user will then click on this email
‫and will then be able to do the request from there.
‫And that's gonna work later
‫when we implement our dynamic website,
‫but still, we now want to create this URL here,
‫so that the user can simply copy it,
‫to make it easier to do this request.
‫Okay, so basically we need to recreate
‫this URL structure that we have here.
‫So this one is for forgot password
‫and let's actually save it here.
‫So, forgot password, and now the URL
‫that we're creating is actually for reset password.
‫So, remember, we actually implemented that one before.
‫Okay.
‫Let's just go ahead and copy it here,
‫so reset password, all right?
‫And that will then actually take the token
‫as a parameter.
‫Okay, so let's just put any random token in here for now.
‫So it doesn't matter at all.
‫Let me just save it here,
‫as reset password.
‫Okay.
‫And also, it's not GET, it's also not POST,
‫but it's PATCH, because the result of this
‫will be the modification of the password property
‫in the user document.
‫And so PATCH is the best one actually, okay?
‫So let's quickly change our route implementation for this.
‫So, it's here in userRoute,
‫so it's not POST, it's PATCH,
‫and we also want to specify a parameter.
‫So, remember how we do that.
‫So it's just like down here.
‫So another slash then colon, and then the name
‫of the parameter, which is gonna be token.
‫Okay, and let's build this now,
‫starting with the protocol.
‫So, HTTP or HTTPS, okay?
‫And we're basically gonna get that data from our request.
‫So that's stored on request dot protocol
‫then colon slash slash, and then the host, okay?
‫So we're basically preparing this one here to work
‫both in development and in production.
‫So, request dot get,
‫and then host.
‫All right, so this is how we get the host,
‫and then slash api slash version one,
‫and I guess it's not ideal to define a tier
‫hardcoded like this,
‫but again, this is something that we're gonna fix
‫a bit later, okay?
‫And I see that this is actually not correct.
‫These curly braces should be there.
‫So, now, users,
‫resetPassword,
‫and then yet another slash, and finally the token.
‫Okay, so, resetToken.
‫All right?
‫And as we discussed before, in the last lecture,
‫here we actually gotta send
‫the plain, original resetToken, and not the encrypted one.
‫All right?
‫We will then, in the next step,
‫compare the original token with the encrypted one.
‫So, again, just as we discussed in the last video.
‫Give it a save here now, and so that is our reset URL.
‫And now, based on this URL, let's quickly
‫create the message here as well.
‫So, Forgot your password?
‫Submit a PATCH request
‫with your new password
‫and passwordConfirm of course,
‫to the reset URL that we just created, okay?
‫So basically, giving the user some instructions here.
‫Then, on a new line, we also say,
‫if you didn't forget your password,
‫please ignore this email.
‫So that's kind of a common message,
‫and again, I'm sure you've seen it in some way
‫or another, all right.
‫So let's now, finally, send the email,
‫and remember that sendEmail
‫is an asynchronous function.
‫And so, therefore, we need to await it here.
‫Okay?
‫Because, of course, it's gonna return a Promise.
‫And remember now that the sendEmail function here
‫takes an object with some options.
‫So the email is user.email, right?
‫Or we could also say, req.body.email.
‫So that's exactly the same, actually, right?
‫Then the subject that we want to say is,
‫Your password reset token.
‫Let's say right away that it's only valid for 10 minutes,
‫so that the user knows that he has to hurry.
‫Okay, and then finally, the message, as well.
‫Okay.
‫So, we await that, and then after that,
‫let's also send, of course, some response.
‫Okay, so there always needs to be a response,
‫otherwise, as you already know,
‫the request/response cycle will never finish.
‫So we simply send a 200 code
‫and then a nicely formatted message
‫with a status of success,
‫and then just a quick message saying,
‫Token sent to email.
‫All right.
‫And, of course, we can not send the reset token right here,
‫by adjacent, right, because, then everyone could
‫just reset anyone's password,
‫and take over any account that they wanted.
‫And so that's the whole reason why we send it
‫to an email address, because we assume
‫that the email is a safe place,
‫that only the user has access to.
‫All right.
‫Whoo, so, this video, again is running quite long,
‫but we're still not done.
‫We're almost done, but not entirely,
‫because there might happen an error,
‫using this sendEmail, okay, and so in that case,
‫we, of course, want to send an error message to the client.
‫But in this case, we actually need to do more
‫than simply send an error message.
‫We need to basically, set back the password reset token
‫and the password reset expired that we defined, okay?
‫And so right now it's not enough to simply
‫catch the error and then send it down
‫to our global error handling middleware.
‫But instead we need to simply add
‫a try-catch block right here.
‫So again, because we actually want to do more
‫than simply send an error down to the client,
‫so we try basically to do this,
‫right, but in case there is an error,
‫then, of course, this block here is executed.
‫All right?
‫So what we want to do in that case,
‫well, we want to basically, as I said,
‫reset both the token and the expires property.
‫Okay.
‫So, passwordResetToken,
‫and set it to undefined, all right.
‫And the same for passwordResetExpires.
‫Okay.
‫And then, of course, just like before,
‫this only modifies the data, but doesn't really save it.
‫And so let's go add, grab this one,
‫and so to basically save the data in this case.
‫Okay, and then just to finish,
‫we, of course, then return with an error
‫to the next middleware.
‫So newAppError,
‫There was an error sending the email.
‫Try again later.
‫And in this case, the error code can actually be a 500.
‫So this is really then, like an error that's happened
‫on the server, and so it has to be a five code,
‫and 500 is just, like, the standard one.
‫All right.
‫So, let's now go ahead and try this out again, all right.
‫So this is quite a long one again, but, well,
‫we have to do it, right?
‫So, forgot password, with this email, let's check it out.
‫So this might not take a long time,
‫because of sending the email,
‫but actually it worked now, took like five seconds,
‫but we see Token sent to email.
‫and so, as we know, since we used Mailtrap,
‫it actually didn't send this email to hello@jones.io
‫but instead the email should be now trapped
‫inside of Mailtrap.
‫And, indeed, here on the left side, it now showed up.
‫All right.
‫So, that is the email that we specified
‫and here we get our nice URL.
‫Okay, so the one that we created with the protocol,
‫the host, and then also with the token.
‫So let's just take a look if this really
‫is our plain token,
‫so ending in 88df,
‫and, indeed, we have resetToken here, 88df.
‫And now in the database, we should have the token
‫ending in 1111.
‫So, let's confirm that, here in Compass,
‫give it a reload, and, indeed, here we go, okay?
‫And so again, this here is in 10 minutes from now.
‫Great, so we finished that part.
‫Next up, in the next video, we will then actually
‫reset the password,
‫based, of course, on the new password
‫that the user sends with the reset password request.
‫So, see ya there.