So in order to save the user inside of our database we have to find a way to encrypt the password. For that I'm going to be using a package called bcrypt. So let's go inside of our terminal here and let's do npm install bcrypt like this. And by default it doesn't come with types so we have to additionally install its types so let's write npm install dash d for dev dependencies at types slash bcrypt like this So now you should be able to import this in your project and let's just check it out. So inside of your package.json in the dependencies you should have bcrypt installed and inside of dev dependencies you should have types bcrypt like this.
So let's go ahead and let's import bcrypt from bcrypt like this and now we can use that we can use this to encrypt our passwords so let me just make sure that I am running the project so I'm gonna run npm run dev here and for now I'm just gonna refresh the localhost make sure you are on the register page right here so what we have to do after we confirm that the fields are not invalid we have to go ahead and extract the validated fields. So you can use validatedFields.data like this. And in here, you can get the exact email, password, and name which we have defined in our register schema. And which of course the user has to enter. So let's get the email, let's get the password and let's get the name.
And the first thing we're gonna do is we're going to hash the password. So const hashed password is going to be awaitBcrypt.hash password and give it some salt which is going to be 10 in my case. If you hover over the hash function here you're going to see different ways of using it. So if you want to you can generate salt differently and then you can store that in the database as well or you can simply pass in the salt rounds like I'm doing right here in a very simple way. Great!
So now that we have the hashed password, what I want to do is I want to confirm that this email is not taken. So let's go ahead and write, well first let's go ahead and import our database. So import database from add slash lib database which is this little util which we created and then in here we're gonna write const existing user to be await database dot user find unique existing user to be await database.user.findUnique where we have an email matching like that. And then we can say if we have an existing user that means this email is already taken so we're going to return an error saying email already in use like this and if that is not true we can continue and create our user so I'm going to write await db.user.create and I'm going to give it a data of name email and for the password field make sure that you pass hashed passwords. So this is very important.
Do not accidentally use the password like this. Make sure you're using the hashed password. You never want to store plain text password inside of your database. So make sure you're encrypting this first. Great!
And what I'm going to simply write here is I'm going to write a to do send verification token email. So we're going to do that later. For now I'm just going to write a success message user created like this. Great! So let's check this out now.
So I'm gonna refresh this. Inside of my NEON database I don't have anything inside of my user model here. So let's go ahead and give this a name of Antonio. Let's use emilexample.com and let's go ahead and give it a proper password and once I click create an account here I believe we should successfully connect our database and we should get the user created message right here so inside of my NEON database here if I refresh I believe in my user there we go I have an ID I have a name of Antonio I have an email I don't have anything for email verified because well we didn't verify the email I don't have an image and you can see that my password is a hash. So even if someone breaks into our database, there is not much they can do with this string right here.
So our passwords are encrypted. Great! Perfect! So Now what we have to confirm is that if I try and do this again, so find the email which you've used. So for me is mail at example.com.
So let's try this again. New user. Let's use the same email. And let's try creating a new account and there we go. We say email is already in use.
Perfect! So what I want to do now is I want to create a little util for this existing user here by email because we're going to be doing that a lot. So for that I want to create a new folder in the root of my application and I'm gonna call that data and inside of here go ahead and create a new file user.cs so this is going to be specific user data and let's go ahead and let's import the database from add slash lib database and let's export const get user by email to be an asynchronous function which accepts the email which is a string and then in here let's open a try and catch block. Inside of the catch here you can just return null. And inside of here you can get const user to be await database.user find unique where you have a matching email property like that and simply return the user like this and let's go ahead and copy and paste this and I want to create another useful util here get user by id and instead of email being the prop it's going to be the ID and we're going to be simply using the matching ID of the user.
So very simple and we're going to use that inside of our auth callbacks later where we need more information from the database. Great, so now let's use this inside of our register function here. So instead of this, it's going to be await getUserByEmail and we're going to pass in the email. So let's go ahead and import getUserByEmail using the addData user and the structure getUserByEmail. And here's a quick little tip for you.
Some people have reported that Bcrypt is causing them errors in the app. So if you want you can use an alternative version of Bcrypt. I'm going to install it and demonstrate it just in case you're having any issues. So npm install bcryptjs like this and just as in the previous one you also need to install a dev dependency of bcrypt types sorry of at types slash bcryptjs And I believe they should work exactly the same. So you can import from Bcrypt or Bcrypt.js and I think it should be exactly the same.
So let's go ahead and try this. If I go and npm run dev here, I'm going to create a new account here just to confirm that everything is still working. So new, new example, com. Let's go ahead and create an account. And there we go.
User has been created. And if I refresh this, I should have two users inside of my user model here. And there we go, you can see how they have, of course, different encryption, but the encryption is still fully working. Great, so now that we have configured that, what I wanna do next is I wanna start implementing our actual NextAuth setup, and then we're gonna come back to this to send the verification token email. So the reason I don't want to do this immediately even though it's very simple to do that is because I want to demonstrate to you how we can first log in and then how we can restrict users which have not verified their email from logging in.
Because it's one thing for us to disallow that for example in the login function here, right? So we can just simply check if the field from our Prisma schema called email verified doesn't exist. Okay, just break the function and don't allow the user. But keep in mind that this function is just a wrapper around NextAuth. So if somehow the user finds a way to log in, we need to tell NextOut directly never allow this user to sign in completely.
Instead redirect them to verify their password, to verify their email. Great, great job so far. So we're finally ready to add NextOut inside of our project. And for now, we're simply going to implement the login functionality the same way we just implemented the register functionality. Thank you.