Tutorial: Email System (Forgot Password + Email Verification) with Next.js V13 (APP ROUTER) + Resend

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hi everyone so in this video we're going to take this web application where we've got a homepage dashboard uh authentication uh setup the whole skeleton of uh authentication and users we're going to take this and add email functionality to it we're going to be using something called resend to do this um now after we've implemented uh integrated with the resend so that we can send emails on our web application to all of our users uh we'll be adding a reset pass password option uh if people have forgotten their password and we'll also be adding an email verification uh an email verification process flow uh for new users that are being signed up okay so first of all I want to just say that the code will be in the description so if you'd like to check out the code and just use that and copy it and use it right now you'll be able to do that and follow the steps to get everything set up um if you're wondering how we got to uh this point with the signin um and the you know the dashboard the full authentication system this is something uh we covered in a previous video called uh full off system with nextjs version 13 with the app router using all of these different libraries uh so you can go and check out that if you want to set up the login system um anyways so the first thing we'll be doing is getting the domain and resend set up with each other so we'll uh go to the place where we've got our domain part so I've got mine on Square space so I've got modern webd development.net right here and if I want to connect that to resent what we'll just do is go to res.com you want to create an account here I just created my account and if you go on the left side here click domains and click add domain what you want to do is put in your domain so I've got modern webd development.net pick whichever region you'd like I'm going to pick this one and now we've added the domain so the next thing we need to do is head over to the uh domain website where we can add the DNS records that we need to uh to set up on the domain so that we can tell recent that this is uh that this is uh something that's allowed to be done um with sending the email so if we just click on domains here and inside of here I'm going to click edit DNS and I have no custom record set up so we're going to just add those recent DNS records so there are three DNS records we need to set up uh the first one is an MX type so I'm just going to put MX inside of here put in the host name really just copy pasting everything here value is this the priority is 10 save and we'll add the next one that's a txt also called bounces and it has that value which we'll just copy in very simple guys we've got txt here as well copy this in and copy in the value like so there we go all right so we've just added all of the DNS records that we need to add on to our uh domain so we can go ahead and close down the domain we don't need that anymore um I'll press the uh verify DNS records button in the top right here and it's going to start it's going to say pending okay so the NES records if you don't already know they take a little bit of time to propagate can be a few minutes can be a few hours depends on the on the place that you've hosted on where you've packed your domain so if you have any TTL values or time to lift values that you can modify try and set them to the lowest possible value so that you'll be able to get these propagated as fast as possible so I'm just going to pause the recording now and get back to it once we've got this verified all right so that took about 5 minutes after I uh after I pressed the button so now the domain is verified so the next thing we'll go ahead and do is go to the recent documentation so we'll go to the uh you can just get this by do sl/ introduction it's in the top right just over here and click next JS um quick start as you can see we need to create an API key so we'll just go ahead and do that so on the left side here we need to create the API key just do um just do I'll just call this demo all domains add and we'll just copy this API key and inside of the environment variables we'll just go ahead and put resend API key very simple hit the save button and we'll close that down head back over over to uh the quick start guide we'll just copy in this command npm install resend like so and while it does that we'll just create an email template step two so inside of this we'll just copy the code like so we can use this just to test and I'll create a folder called email templates you can structure this in whichever way you find most convenient test email. CSX and inside of here we'll just copy that okay and finish installing yep it did cool um excellent yeah so now we'll go ahead and copy the functionality here we'll actually do this one and as you can see this is created for the Post uh like the routes inside of the app router uh we'll actually use server actions for this so if you don't already have server actions enabled and you'd like to follow along you can go ahead and go to the next config.js and copy this just to enable server actions so we'll go ahead and create a new folder in the actions folder we've got create emails and put send email. TS and we'll start this out by saying new server because it's on the server side and we'll just instantiate resent using the API key that we have just set so I was pretty sure that was recent API key and we'll just import that from the library then we'll export const send email so this is the server action and inside of the parameters here it'll be create email uh options and and we'll also have an options field which is optional and this can be create email request options type it can also be undefined it can also be not set at all and it's a very simple function will'll just have cons data equals wait resend. emails. send payload comma options like so we'll just log to the console as well saying that the email was sent successfully and return the data back to the caller like so now if you just go into the components uh fold fer what we'll just do is create a uh test email button just to make sure that this actually works so we'll create this and use the client because it's a client side we'll do con handle submit async and inside of here we'll just do send email and we'll just leave that for now send test email and and we'll do onclick handle submit like so okay so we got a very basic button set up here so the parameters of this uh is uh we need a from so this is the cender so for this purpose we'll just do admin and we'll do the email so we'll do admin atern webd development.net make sure that this is the this matches the domain that you just registered and then the next thing will do is to this is a list of all the people that you want to send an email to so I'll just send it to my own email so modern web development YT gmail.com and now we need to set the subject and this can just be test email okay and um the next thing we can do to send emails is you can either use one of three things so you can use text you can use HTML like this or you can use react okay and so this is text and this is HTML if you want text based HTML based emails now recent has a nice feature uh with the email templates that allows us to have emails defined like a react component and then we can import those directly uh when we actually sent the email so the way that we do this is we take the email template component we import it and then we set the uh props as the parameter of the um of the all of the component like so so this meets a first name so we'll just do John and we also need to cast this to react. react element um just to get the types right cool so if we just put this into the Navar here and test email button like so just to make sure that this works all right we can do NM run Dev and if we just quickly connect connect to this and refresh it's compiling there we go if we press the send test email click that button I can go over to my Gmail and see that admin sent me a test email saying welcome John it's from admin atod webdevelopment Donnet so we've actually just set up the uh email integration with the resend so um if you're not interested in continuing on with the reset password functionality or the email verification functionality you can go ahead and stop watching just now this is how you set it up so that you can send emails to your users um and now we're going to go ahead and move on with uh reset password so in order to reset the password we first need to go into the uh the schema the database schema where we Define our user so we need to add a couple things so reset password token we're going to generate a token that allows the user to uh basically receive an email containing a link with this tokens inside of it and then they can change the password after and this needs to be a unique token because we need to be able to identify the user with this token and then we need to also have an expiration date because if you want to deploy this in production you don't want these tokens to hang around for for all of time so we'll add a reset password token we'll add a reset password token expiry which is a date time and um now we just need to go to users and add a an action that allows the user to basically call this from the from the front end to reset that password and so we'll have a reset password use server because it's a server action then we'll export this and all it takes is an email do Arrow based function um yeah we can log to the thing anyways let's get the user first the first thing we need to do is actually verify whether this email is even a user right so if we uh attempt to find a user and the email uh leads us to an invalid user and this needs to be an async function like so then uh this is not going to work throw new error user not found okay um and now we know that the user exists okay so the reset token reset password token this should be equal to um and now we're going to import a library called crypto we'll import crypto from crypto this is a built-in library inside of node so you should be able to just import this you don't need to do npm install anything and we want to Generate random bytes we'll just generate a 32 32bit bite and this is going to be two string and we need to set this to base 64 URL and the reason why it has to be this is because um we want it to be a string that's safe for the browser when we put it in the URL so so that it'll be able to be say Local Host SL offret password and the token should be uh you know it'll be something like this right um and the base 64 URL um the two string on that just make sure that this is uh safe for your URL and it's not going to be encoded in a way that's not can't be parsed uh then we need to set the uh expire date so we'll just get today and we'll get expiry date and this is going to be exactly what GitHub co-pilot is suggesting here uh we'll just plus one on the date okay then what we'll do is update the user with Prisma and we'll just use id user. id and inside the data we'll simply put um reset password token and reset the two these two and these should be equal to these values like so okay and we also just need to push this to the database the changes we made in Prisma and we'll just say yes to this this is something old all right great so now we've got the reset path password token and we got the expiry date as well we just set that and this is set to 24 hours from now you can modify this in whichever way you want but we're just going to have it so that have it be so that the token expires after 24 hours um so that they don't hang around for too long um the next thing we need to do is actually send an email to the user right so reset password email and we'll just go ahead and copy the test email in and change the name to reset password email template and we'll put email as one uh property and also the reset password [Music] token and these should be given like so in the props and we'll put reset password for the email you can you can structure this in whichever way you'd like and I guess we'll have a paragraph to reset we'll copy that in and have a the H ref should be um this should match the domain um where where you're going to be hosting the web application right so this is just Local Host so you want to substitute this with the um with the actual real URL and we'll have it under sloth SL reset password and we'll have the token set to the Token that the user gave us that we've been given in the in the props reset password token like so okay and then we'll be able to use search params um on the page to get it click here to reset password like so and now we'll be able to use this inside of reset password to send the email so if we just go ahead and copy the same function that we made here do reset password and we'll await this Le set password email template and what we want to do inside of here is obviously have the email and also the reset password token because those are the fields that we need to provide in the properties and we'll remove this reset um your password we'll we'll call it the same thing as here um two so we're going to send this to whichever email was given so the users's email so that they can receive that and press the button and what we'll just do now is return some kind of yeah some kind of success message um now we've got the functionality we just need to set the uh create a uh form that allows the user to reset their password so reset password [Music] form and this uses the client client side component that is string so we want to have the email be an input we'll have a message as well just for some feedback like this and we'll put div inside of here we'll just do Flex Flex call G four just so we have some spacing um and um yeah I guess we'll just use what suggested like so except for the onclick here so const um handle submit is an async function and that'll be what we'll calling handle submit there we go cool so we've got reset password we got handle submit um what we want to do now is constant message equals reset password and this is going to be the email and we want to await this and so this is going to be a string so we'll just set the message to the message and then we can uh see that on the users side now under the uh off folder we'll create a reset password folder and that includes a page inside of this we'll create the page component so reset password page and this should have search params and if we just Define [Music] this it is not defined like so uh we can get those from the next uh documentation so inside of the page. JX documentation we can see that the search prams can get type from that like so and then just have it be a little cleaner like that there we [Music] go now we're going to check if that's a token or if that's not a token and if there is a token we'll have another component called change password change password what would we call it form and this should we'll create this in a second but this is going to take uh the users ID we'll just have that be on display so we can have it there change password form const user equals wait so if there's a token inside of the URL we want to get the user and then we want to show them the change password form okay so we'll just get the user where and since it's a unique um field it's a unique string we'll be able to find a unique user based on the token and this is using the reset password token and this is a string okay we just change that to return like so and we'll of course we'll modify the page so that it's async um what else do we have yeah so obviously people will be able to put in anything as the token search parameter so maybe it's not going to lead to an actual user so if there's actually not a user uh found what we'll be able to do is yeah we can just return invalid token like so okay and if not we have a valid user and we can put user ID and that is going to be equal to the user's ID and then they can change the password and we'll we'll uh set that up in a second now if the token is not set inside of the URL what we'll do is return something else which is the reset password form which we just set and uh this is invalid because we handle all cases like so so this is basically the reset password page so if we go ahead and do npm run Dev on that we'll be able to navigate into that into that page o slash uh reset password and that's going to compile for a second and as you can see we've hit the case where it's going to shows the reset password form so we're inside of this now and we have the email field so if I put uh actually let me just sign up with the user first uh if I don't just making sure modern webdevelopment it gmail.com test Okay cool so we have a new user now and now we'll go back to reset password and we'll try and reset the password for uh this email that we just created and I'm just going to go ahead and get the emails here again reset password if I press the button here we can see that the password res reset email has been sent and if we go ahead and see this right here we have the reset password if you uh notice in the um bottom left hand corner you can see that there's a token and if I click on this um we have the change password form okay so this means that since we see the change password form right here um it means that we're right here that means that it found the user and if I just go ahead and change the single thing so this is an o if I put this to I it's going to say invalid token okay it can't find the user so I'm going to change this back to O and now we just need to make it so that you can uh input the [Music] password so we'll just do password we'll also have a um confirm password uh that we have a message set message this is just going to be strings all of these const uh handle submit like so and what we'll just do here is have a very basic setup I think GI co-pilot is going to give it to us yeah here we go and we obviously want to use use client for this see we got a couple errors for not using client H so let's go ahead we got the input for the password for the confirm password and uh the button to um to have the um handle submit okay so this is perfect and the message as well so when we submit first of all we want to say if password is not confirm password will return first of all we're also going to set the message saying passwords do not match okay we need to make sure that the passwords match right and actually one thing we'll just change here is actually use the reset password token uh as an input to this because what we'd like is to make sure that this is safe so reset password reset password [Music] token this is search ps. token string like so now we have the reset reset password token and we'll be able to essentially go ahead and call the reset password uh well the change password uh action once we've created it so we'll go ahead and create another action called change [Music] password and this is going to be a very simple [Music] function async and what it takes is a reset password token string and it also takes um the password okay and so we'll find the user make sure that the user exists of course if the P if the user doesn't exist that's no good we'll throw a new error now we can get the user uh the the uh reset password expiry okay this is very important because now we're going to make sure that the the expiry hasn't hasn't been uh hasn't been passed so uh const today equals new date and this is a date value so first of all if the recent password token expire has not has not been created uh we'll just assum assume that it's expired it shouldn't be null at this point and we'll also check if today is uh later than the expir date in which case it's also been it's also expired otherwise it's just fine so what we'll go ahead and do is have the hashed password and we'll hash the password exactly the same way that we do in the signup function here import bcrypt from bcrypt so we'll use the library bcrypt so if you bcrypt JS so if you have not gotten this Library go ahead and do npm install bcrypt JS this is something we used to set it up in the previous video to Hash the passwords and now we can just go ahead and update the user okay so we'll do wait Prisma user. update where id user. id and we'll have data and now we first of all we want to set the password hash and we also want to set the reset password token to null because this should no longer be usable and the expiry should also not be usable we want to reset this completely so this is how we're going to do it and then we can say password changed successfully like so excellent now we can go ahead and go back into the change password form and simply call this function and we'll just say call all let's we'll call it a message change password and reset password token is the first parameter and then we have the second one which is the password like so and then we'll just set the message to message so that the user has some feedback and if we go into here first of all we got the recent password token if I change this it's invalid we just go back and now now what I'm going to do is enter the password so I'm going to just do 1 2 3 4 1 2 3 and if it's don't M if it it doesn't match the two password inputs um then it's no good we can change the password so I've put in 1 2 3 4 and now the password changed successfully so what I what's going to happen now if I refresh is that it's going to be an invalid token right because we just reset it so if I go ahead and sign in again modern web development yt@ gmail.com 1 2 3 4 this works totally fine cool so now we've set up the whole flow for resetting our password that's awesome now what we're going to be doing um is setting up email verification okay so this is a very common thing you want to verify that the users emails are valid make sure that they are um use useful to to to have so we'll go back into the Prisma database schema here and put uh email verified and this is a Boolean and it defaults to false and email verification token is a string and this is also a unique token because we want to be able to just like with the res reset password functionality we also want to be able to identify the user based on this okay so the first thing we're going to be doing is um creating the email that we're going to send to verify the user when they sign up okay so we'll have verify email email I guess and this is going to be similar to this so similar to the reset password so we'll just copy that and we'll have verify email email t template little messy should have maybe named it something else but you get the point uh it's not a reset password token anymore it's a verify email token cool and verify email for email and we'll just say to verify your email click on this link nothing else and we'll add that to off but we're going to have verified email and have the token be the same [Music] thing like so very simple so now we have the email now um in the project we already have the um function the server action to sign up users if you have a different function to sign up the users you just want to put this the following code we're going to add inside of there so uh inside reset password we'll just copy a few of these functionalities right right cuz uh this is very similar so inside a sign up we'll have and I'm pretty sure that this should return the user so on upon creation so we can actually get the user like this um we'll just call it something different created user and this should be a user yes cool and now we'll be able to use all of this we need to import crypto not cluster crypto like so uh encode it again with a random URL make sure that it's base 64l on the two string uh we're not going to have an expired date email verification is not something where you change the password or anything so we're not going to add an expired date in this case you can do that if you'd like but we're not going to be doing that we're not going to be doing that in the in this tutorial you don't need to do that um so we create the user once the user is created we'll have the reset password token uh which we're going to rename to verify email token email verification token we'll just make sure that the names are correct here I'll just change that inside of the email as well to keep the consistency uh we want to do npx Prisma DB push to generate the new types on the client and we'll just say yes to this now we've got the types have been resolved and we we'll send the email saying verify your email address we'll import send email and we'll also say um verify email email template which takes the email and the token that we just generated right like this um the ID should be the created user. ID we don't need today so upon creation of a new user what will happen is we'll um we'll send the email so I need to delete my user now for us to test this so I'm going to go inside of npx Prisma studio and inside of here what'll happen is we got the user users and I got it couple emails I'm just going to delete everything from here all right that's cool so now we don't have the user I can create it again and we can we can make sure that it's correct on the uh email so I'll go back into the system uh click sign out to clear the clear the cookies oh we just need to do MPN run Dev and we'll go back in here yeah we want to clear the cookies so we'll stay on SL sign out sign out like so and we'll just do sign up so modern web development YT so the email I'll just put test and that's successfully been created so if we go back in here we have verify your email address it's just been sent awesome click this and we can see in the in the bottom left here that the token has been given so we've got a token but we don't have the page chat so what we'll just do is add this to off verify uh I think it's verify email right that's what we called it yeah verify email and inside of here I'm just going to go ahead and copy page. CSX uh from the reset password page and we'll just rename all of this um if you're wondering how I'm selecting all of this I'm just doing a control D I think it's a Windows Windows D on Mac um which just allows me to select all of these at once so we'll call this verify email page uh we want to get the search prams token and this is not the reset password token but this the email verification token okay if we can't find the user it's invalid and if we do find the user we want to say await Prisma user do uh update where the email verification token is equal to the Token we've got and then we'll flip the switch on the email verified we'll set that to True we'll also set the email verification token to null because this is no longer useful and we'll just have a short little div with an H1 maybe saying a email yeah email successfully verified have the exclamation mark after like so uh and if there's no token available um what we're just going to go ahead and say to the user is um um no token found check your email like so have some capitalization on there and we can have email verified set to true and now we can go ahead and click the link in the email okay so we'll put a click here to verify your email and I think we have yeah we got it all up and running so this should be good and now we can see that the email is verified from Modern webdevelopment yt@ gmail.com awesome that's great if I modify one character on here to Q from from G for example it's an invalid token and if I ALS also do it on this one it's still invalid so if I just go ahead and inspect the database with npx Prisma Studio we can now see that the email verified field has been set to True okay and you'll just be able to use this anywhere so if you want to verify them make sure that they don't have access to a certain amount of features until they're verified you can just use Prisma or whichever um whichever Library framework you're using for your databases uh to access the database you can just use that to access the user but um that essentially concludes uh this tutorial so we went ahead and set up let me just go ahead and do this so we went ahead and set up um the entire web application with a resend so that'll allow us to send emails with the right domain and then we proceeded to uh generate reset password emails and also with the token and expiration dates and then lastly what we just did is um of course with the verification of emails we just set that up as well so please hit the like button and subscribe if you want to see more content like this if you have any questions or any issues with this tutorial please leave a comment down below and um yeah thank you so much for watching have a great rest of your day bye
Info
Channel: Modern Web Development
Views: 7,524
Rating: undefined out of 5
Keywords: next, next.js, nextjs, next js, approuter, app router, resend, forgot password, email verification, email verify
Id: 0KHkIJwRoLM
Channel Id: undefined
Length: 40min 18sec (2418 seconds)
Published: Sun Sep 24 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.