In this chapter, our goal is to implement authentication. As you can see, we are going to implement this login screen and this register screen. You can see that the register screen will have this cool little feature, where it will be able to display the subdomain where the store will be available later on. But besides the UI, we're also going to have to modify the user's collection by adding the username field. And then we're also going to have to create some ALF procedures.
Thankfully, we are going to be able to leverage the payload ALF utils for that. After that, we're going to create this ALF screens, which I have outlined above. And then we're going to combine all of those to display some authenticated states. As always, make sure that you are on your master branch using git status, ensure that your branch is up to date. Now let's go ahead and do a quick bon run dev to ensure that our app is in its latest state.
And then what we're going to do is we're going to go ahead inside of source collections users and inside of here we're going to add a new field as you can see email is added by default because we are using the out true option so let's go ahead and add name username required true unique, true, and the type of text. Like this. So the name is referring to the name of the field, of course, right? And we're adding some rules here that it has to be required and unique. And immediately after you've done that, in your payload types, you should now have access to the username inside of the user interface, right?
The payload types are in the root of the source folder. If yours hasn't, a quick reminder that you need to, A, have your app running so that it can generate new types, but you can also run generate types with our little script here. So once you have the username field here, what we're going to do next is create ALF procedures and use payload ALF utils. So let's go inside of the modules and inside of here let's create ALT. Then let's create server and then let's create procedures.ts.
To help us get up to speed, we can just copy the procedures from the categories. So just paste it here in Auth. Let's rename this to Auth Router. And let's go ahead and clear up the GetMany here. Instead, what we are going to do is we're going to create a very simple session like this, which will be a base procedure.
And what we're going to do is we're going to get the headers using await get headers. And we are going to be able to import the headers. My apologies, headers from nextHeaders, but I like to use as getHeaders because we have to await that. I will rename this namedExport so that I can have this headers constant, otherwise it's a conflicting name. And once I have the headers, what I will be able to do is get the session using await context database.auth and pass in the headers.
And then I will be able to simply return that session to the front end. So if you're wondering where does this out come from, well, remember, I'm not sure where do I have to go, I think the init file. In here we created the base procedure and we extended the database with the payload object. So this is payload API that you're seeing here. So this is payload.auth.
So you can of course go to payload docs here. Looks like the site is not loading at the moment. But you can go to payload docs, and you can read more about the auth feature. But basically, this is how you fetch auth. Let me try one more time.
There we go. Now it loads. So I'm going to search for Auth here. There we go. Auth local API.
So this is how you get the Auth, by passing the headers. You can await next headers. There we go. From next headers. Basically the same thing we are doing.
And you can also then use login and register, which is all of those things we are going to use. You also have forgot password, reset password, a bunch of useful features here regarding Auth. Great. So now that we have this, what I want to do is I want to go inside of my TRPC folder routers underscore app and I want to add the auth to be auth router from modules auth server procedures. And now let's go ahead inside of the app folder, app route group home page.
And I think we can go ahead and just practice displaying the out state here, right. So mark this as use client here. And then let's go ahead and get the RPC from use the RPC from at the RPC client. And then finally, in here, we can get the data from use query from 10 stack react query like this. And inside of here, TRPC out session, get query options and execute that like this.
And then in here, you will be able to JSON stringify data null 2. So now, if you've done this correctly, on your homepage, you should be able to see if you are logged in or not. So Let me go ahead and find... So we have permissions. There's a lot of things here, but basically the user is what we are interested in.
As you can see, user null. So how about we go with data?user. Like this. So we are only focused on the user. So right now it's just saying no, because our data.user does not exist.
Great, so we just developed our first auth procedure where we attempt to get the current session. The problem is the session does not exist. So now while we are here, let's create the register mutation here. I think I've accidentally imported this, so remove that. Register will be a base procedure.
And then before we do the actual mutation, we are going to have the input. The input will take Z as Zod. So let me go ahead and do import Z from Zod. Z.object and inside of here we are going to do the following. The email will be a type of z.string.email.
The password will be a type of z.string. Let's give it some values, minimum of one. Or you can do whatever. Maybe it has some passwords. I don't know.
Basically, you can define the validation for the password yourself. I'm going to leave it as string for now. And now we're going to set the username. Now the username will be interesting because it won't be just a string. The username of the user will be what the domain will be.
So username.shop.com, right? This would be the domain. Because of that, it is important that the domain matches the structure that we want to allow for a domain. So, for example, we can't allow the username to be two words, right? It has to be one word.
It also can't be a dot. It can't include double... It can't end with a dash, right? Things like that. So, let's go ahead and first of all, make it a minimum of three characters.
So username must be at least three characters. Maximum of 63. And username must be less than 63 characters. And then we'll do a regex right here. So Let's go ahead.
I'm just going to paste it because it doesn't make sense that you watch me type this. So the regex, you know what I can do here? I can make it a little bit easier for you. So you can either access the source code and copy it, or you can just pause the screen and copy it here. Or you can go to the gist here.
You can see that in the comments, I leave some pictures and some useful tips. So I will add auth username regex, and I will just leave it here if you want it that way. Okay, so now you have the regex for this and the error message will be username can only contain lowercase letters, numbers, and hyphens. It must start and end with a letter or a number. So it cannot start and end with something else.
And we are also going to add a refine here to ensure that it doesn't include double dashes because consecutive hyphens are mostly used for preview URLs. So we want to protect against that, like this. And let's do transform value, value to lowercase. So we always use the lowercase version of whatever they typed. There we go.
And now that we have this, we can go ahead inside of the mutation here. So let's add an asynchronous method. Let's destructure the input and the context here. The input will basically be the Zod validation above. Now here, what we are going to do is we are going to do await context database create.
Collection will be users. And then data, email will be input.email. Username will be input.username. Password will be input.password. And you don't have to worry about hashing.
Payload handles that for us. So yes, you can safely pass the password here. This is hashed, right? This will be hashed. This won't be stored as a plain text, don't worry.
And that will be it for now. Later on, we're going to extend this. But for now, this should be enough. And now I want to go ahead and create the login procedure. So let's make this easier by just copying the register procedure here and pasting this login login will be simpler, given the fact that it doesn't have username, so just email and password.
And here's a little tip. I would suggest that you never add validation for the, I mean, like a minimum length password for your login. For register, absolutely, right? And force passwords in some way. But imagine this.
Imagine the first day of your website, you added a minimum of three, right? And then you have a bunch of users which created their passwords. And then a month later, you decide to increase your security and you change it to six. That's perfectly fine for registration because all new users will have to oblige by those new rules. And then you think, oh, well, I should do the same thing for the login, right?
Well, yes, except all of your old users now can't log in anymore. So that's an issue. So that's why I suggest that you don't do any validation regarding length or any special rules for the login when it comes to password. Because This is not anything that you're actually storing in your database anyway. Now, mutation here.
Let's go ahead and do the following. So the first thing we're going to do is we're going to attempt to log in. So const data will be await context database log in. Collection users, data, email, input.email, and password, input.password. Like this.
If there is no data.token, that means that we have to throw a new trpc error. You can import trpc error from at trpc slash server. In here, what's cool is that you get a list of codes so you always so you are consistent with your errors and you can also add a custom message failed to log in for example. Great! Otherwise, if we do have the token, we're gonna have to go ahead and set the cookies.
So besides importing headers, let's import cookies as getCookies here And then let's go back instead of the login here. And what we have to do here is do const cookies await getCookies and then cookies.set name authCookie value dataToken HTTP only true, path, this. There we go. And let's return data. Now there are a couple of things I want to change here.
I first want to go ahead inside of the auth module and create a constants.ts. So purely directly inside of the auth folder. And I want to export const out cookie payload-token or maybe call it funroad payload-token. I would suggest that you add a little unique value here just so it's possible that this name is used by some other websites. And if you develop some other projects with Payload, you might have a leftover token, and then you will be confused.
So I would suggest that you think of something unique, something like that. And then give this data token. A path here is true. And I would also suggest later on to do here, ensure cross-domain cookie sharing. So this will be important because later on, we're going to have, for example, funroad.com.
This is where initial cookie will be set. And then user will go to AntonioFunro.com and cookie does not exist here anymore. So they will appear signed out at that point. So we are going to have to ensure the same site here is set to none. And we're also going to have to set the domain here to our actual domain.
But we don't have these things yet. So that's why I'm just going to leave it as a comment for now. Okay. So that should set the cookie. And we should never use this as a string.
That's why I added a cookie here. So out cookie and import it from dot dot slash constants like this. There we go. So after you've set the cookie, you can go ahead and return the data. And now I want to copy this cookie feature and this login feature entirely.
And I want to go ahead and ensure that user gets logged in after they register. So just paste that entire thing here. And after you create the new user, immediately attempt to log in. Throw an error if the login was unsuccessful, and then set the cookie. That's it.
So yeah, it has to have the exact same code as this. Great. So those are our features. I think there's only One procedure left, which is very simple. Logout feature, base procedure, mutation, asynchronous method, const cookies, await get cookies, cookies delete, auth cookie.
That's it. That's logout. And now what I want to do is I want to find a way to use these methods because so far we only use the session one which displays null here. So now it's time for us to go ahead and create our sign in and sign up screens. So we're going to go ahead and go inside of our source app folder.
And instead of home, we're going to create a new route group called out and inside of here we're going to create sign in and let's create a page.esx file so this will be a page And let's return a div sign in page like this. You can copy the folder and paste it and rename this to sign up and display sign up page. And if you revisit your nav bar inside of your app, app route group home, you should have the start selling going to sign up and login going to sign in. So when I click this, it should lead me to the sign in page. If I click start selling to the sign up page.
Excellent. If you want to, you can add prefetch to both of this because we will be prefetching here the user so we know whether we should allow the user to see that page in the first place. Let's start with the sign up page as this one will be a way to create new users. So what I want to do is I want to go inside of the modules inside of out and I want to create the UI folder and inside of here views so I'm to go ahead and create this signinview.tsx. So previously, it was problematic for me to create components outside of the app folder because in Tailwind version 3, we had a config file which you had to manually write in to decide which folders Tailwind would look at.
So I was wondering, you know, now with new Tailwind there's no config file, how does it know where to use Tailwind? Apparently, they invented a super smart system which scans through the entire project and detects every place where we use Tailwind. So I'm pretty confident that we should be able to just create UI files outside of the app folder here. So let's go ahead and do that. Let's go inside of the sign-in view and let's start developing.
So export const sign-in view like this. Let's go ahead and return a div. And the div here will have a grid, cols1 on mobile, but the moment we hit a large breakpoint grid columns 5. Now let's go ahead and create those two columns. The first column will have a background of f4 f4 f0 a height of screen full width on large is going to take colspan 3 and it's going to be scrollable when needed.
So this will be form column. And then here, after that, we're going to have another div, which will be background column. This one will have a class name, height screen, with full LG call span 2 hidden on mobile and visible on desktop. So that's the sign-in view. My apologies.
We should have started developing the sign up view. Good thing is that they are almost identical. So we can copy and paste this and rename this to sign up view. Go inside of the sign up view and rename it to sign up view like this. It's exactly the same, right?
And now let's go inside of the app folder, app, auth, sign up page, and we're just going to return the sign up view from Modulus Auth UI Views, sign up view. And when you click start selling, you should see a separation of the form column and the background column here. So now I want to populate the background column. You can use any picture. In here I've created this picture thanks to Sora.
So you can go ahead and download it if you want to. So I'm just going to go ahead and throw it into a proper folder. It has to be inside of your public folder here. So let me just drag it here. There we go.
Once you have that picture, go back instead of source, modules, out, UI, views, sign up auth, UI, Views, Sign Up View, and go ahead and do the following. Style, and add the following. Background image, URL, and then the name of your image in quotes. So slash al-bg.png. And then you can add the background size, hover, and background position, center.
And then you can turn this entire thing into a self-closing div. And now when you go here, it should look something like this. And now we can focus on our form field. So in order to do that, we're going to have to import a couple of things. And We can also mark this as useClient because it will be a client component.
We are going to need form, control, build, item, label, and message from components UI form. You should have this installed because when we run our app, we used chat-cn. I'm not sure what was the version, I think it was Canary. Yes, this one. And we used add-all.
If you haven't, you have to do add-form. And that will be true for all other components. So I suggest that you just do all to have all of them so you don't have to worry whether you have them or not. So you should have all of these components and besides that, we're also going to need the input and the button right here. You should also have this installed.
This comes installed with that chat-cn package, right? Hook form resolvers, you can see them right here. And you should also have use form installed from react-hook-form. So now let's go ahead and let's prepare our schema here because I think that's the first thing we should do. So I'm going to go ahead and do const form use form like this and in here I'm going to do const form schema.
And for the form schema, what we can do is we can go inside of our auth procedures here and just copy the ones for the register like this. If you want to, you can also do this. You can go inside of out and maybe create schema, schemas.ts and export const register schema like this and just paste that entire Zod thing and import Z from Zod. And let me indent this. There we go.
If you want to, you can do it like this. And now you can reuse them here. So this would be register schema from dot dot slash schemas. It should still work the same way there we go from dot dot slash schemas and you can go inside of the signup view and do the same thing here so you no longer have to import it. What you can do now is just...
Let's import. So import register schema from ./.schemas. And then in here, you can give this a type. You need Z from Zod here as well. So you can give it a type of z.infer, type of form register schema, like that.
And then in here, resolver will be Zod resolver and pass in the register schema. And you need the default values here. So email, empty string, password, empty string, and username, empty string. There we go. So we just define our form element.
Now let's create the on submit method, which will do the z-infer again. So values will be a type of that. And just console.log the values so we can see what we submit. Reminder to put useClient at the top if you haven't. And now what we can do is the following.
We can go ahead and add the form here with an uppercase F, meaning that it's this one from Components UI Form. And we're just going to go ahead and simply spread our form hook here, right? This. We're just spreading all elements inside. Now we need to add the children inside, and for that we use the native form element.
And in here, we go ahead and give it an onSubmit here. I'll form, handle, submit and pass in the onSubmit. This right here. What this is going to do is prevent this from being submitted, being called, unless we pass the validation matching this schema. So yeah, be careful of the password here.
I'm going to change this to minus three, right? Okay. I think I need to just save this file if you haven't. So I'm using register schema here. That's the only thing I changed so that I can reuse the register schema here in the form as well.
So it's easier. And now we're going to give this form a class name, flex-flex-column-gap-8, padding of 4, lg, padding of 16. In here, let's add a div with a class name flex-item-center, justify between margin bottom of 8 here. We're going to add a link to next link and an href to the root page. And we're going to add a span which will say fun road here.
So basically this will be kind of a redirect back to the homepage. Now I want to go ahead and visit my navbar because I want to import the Poppins font to Google, add it here, And I just want to copy this so that I have Poppins ready to use. And I'm going to move the link here so it's up with these imports. Now that I have my Poppins font ready, I'm going to go ahead here and give it a CN, which I can import from my lib utils. So let me move that to its rightful place here.
Once you have that, you can go ahead and give it some default classes, like a large font, and then font, my apologies, Poppins, class name. So Poppins is the name of the constant here. There we go. Now it looks like in our nav bar there. Perfect.
So After this, what I want to do is I want to add a button here and a link with text sign in and an href to slash sign in. And we can prefetch this as well. So now you have a big sign-in button, so let's go ahead and give this first of all an as-child prop, a variant of ghost, a size of small, a class name of text-base, border none, and underline. There we go. So you should now be able to get redirected to the sign-in page as well.
So now what I'm gonna do next is I'm gonna go outside of this div and add an h1 element with a class name text for excel and font medium now inside of here I'm going to add just some welcome text for example join over a thousand creators join over 1, 000 creators earning money on Fun Road. Just some selling point. I don't know, something like this. And now what we're going to do is we're going to add our first form field. So below this, go ahead and add a form field, which is a self-closing tag.
Give it a name of the field it's going to control. In this case, it's going to be username. And then give it a render. Go ahead and destructure the field from here. Add a form item, add a form label with a username label.
Give the label a class name of text base. Then let's go ahead and add a form control here, add an input, and spread the field property inside. What spreading the field property does is it makes sure that you have all the necessary values like onChange, onBlur, and all the other attributes. So instead of adding them one by one, we add them all at once. So this is how it should look like now.
So what I want to do now is I want to go outside of form control and add a form description. So make sure you import form description as well. I think we forgot to do that first. Now, form description will have a class name here, which is going to be dynamic. So it's gonna be hidden by default.
And then, this isn't gonna make sense now, but I'm gonna say true block. So by default, it will be hidden, but then later, this will be a constant. Right now it's hard coded. So we're going to fix this later. Now I'm going to go ahead and do your store will be available at, like this, and then we're going to add strong.
And for now we can just put, well, we have to find a way to actively observe the username field. So we can put that in a constant here, const username form watch username like this. And we can also watch the errors, username errors, form, form state, errors, username. And then const show preview can be if we have the username and if we don't have any username errors. But this will not work as it should right now.
So replace the true with show preview and change this to render the username. So if you try this now, this won't exactly show errors, as you can see. This is not a valid domain. Errors are not showing until you actually submit the form, until you press enter. So we don't want that.
So what I'm going to do is I'm also going to add form error at the end, my apologies, form message at the end. So this should now render the errors. And if you want it so that the errors are actively shown when you type, what you have to do is you have to go inside of the form, add mode, all. And now you can see that it's going to throw an error unless your domain is looking as it should. Great.
So what I'm going to do here is I'm going to add a little to-do here. To-do, use proper methods to generate preview URL. Because obviously, this is not a URL, but later it's going to be something username.shop.com, right? Or maybe like this. Yeah, so you can see the highlighted part.
Now let's go ahead and let's copy this form field here. And let's paste it below. Let's remove the description. We're not going to need it. And change this to email.
And this to email as well. So this is the field for the email. And one more time, this is for password. Password. The only thing we have to put here is give it a type of password.
I would actually suggest that... Actually, I'm not sure. I think it's smarter to spread first and then override whatever was spread. I think that's the better way of doing it. So now you should have your passwords here as well.
Great, so now what we have to do is we have to still inside of this form here add a button element which will say create account. There we go. And let's go ahead and give it a type of submit, size of large, variant of elevated, last name, background black, text white, hover, background pink 400, hover text primary. So now when you hover, you have this cool elevated NeoBrutalism effect. Great, So now we are ready to check out how it looks like.
So demo, demo.com, and demo password, and click Create. And you can see that these are the values we are going to submit, which is exactly what's OK with us. So let's go ahead and prepare our submit form here. So I think that we're going to need to do const trpc from use trpc from trpc client. I think that's the first thing we are going to need.
And then we're going to need use mutation here from 10 stack react query. So I think that now we do const register, use mutation, erpc, auth, register, mutation options. I think I'm not used to the new, we can call this register mutation if it's easier for you, or you can use mutate here. And then let's just call it register. I think it's easier.
So register. And then in the onSubmit here, we're going to do register.submit, actually, .mutate like this, and just passing the values actually. And you should have no errors here because the values should match exactly the register schema that we share between the two. And then you can disable the button here if register is pending. So if you try, you should now get errors.
But if I try, for example, Antonio, AntonioDemo.com, Actually, I'm not sure which email I already used. So we're going to see. Maybe we get back an error. We will get back an error saying email is taken. Let's try a password here, demo.
Click create account. It should automatically log me in if everything was correct. So if I go inside of application, cookies, I have to zoom out a bit. There we go. This is my fun road payload here.
So I think if I go back now and refresh, I'm still getting null here, but I'm not sure if That is correct. So my application here definitely shows the cookie. Interesting. OK, let's continue here. I'm going to come back to that in a second.
I want to handle one more thing, and that is an error, which is supposed to happen, right? So test, actually, Antonio, AntonioDemo.com, and demo. There we go, so this now throws an error because these things are already taken. So what we can do is we can go inside of our layout, so our root layout, the one inside of the app route group. And we can add a toaster from components UI Sonar.
And then we can go inside of the signup view we can import toast from sonar directly so this package you have it installed because of Shazzy and UI. And now, there are a couple of ways you can display an error. So I think you can do it here on error. What I like to do is do it here. I think this is now the place to do it on error.
There we go. And you can extract the error here and you can go ahead and do toast error, error message like this. So when you create an account, let me try and refresh. Maybe it wasn't registered that time. So Antonio, AntonioDemo.com, demo.
There we go. The following field is invalid email. So one, two, three here. There we go. And now it registered.
Now it says again that the following field is invalid. But one thing that I think is doing incorrectly here is my username. So my username should be unique as well. So I just want to confirm instead of my collections, I did set it to unique, okay. But I think that we have to manually do that inside of my out procedures.
We have to manually check that for the register here. So what I could do is get const existing user like this. Let's just call this data. ExistingData will be context await, context database, BB, my apologies. Find, collection users, limit will be just one, where, and then we're going to look at username equals input username, like this.
And then we're going to get the existing user from existing data dot docs first in the array. If there is an existing user, throw new trpc error, code, Bad request, message, username already taken. Like this. So I think that now, we got back an error, username already taken. So It doesn't matter if you have a unique ID, unless you change your username.
There we go. So only after you change your username are you able to do that. So now we can go back inside of the sign up view here. We can also add the router here. Do we already have the router?
Let me see. Const router, use router from next navigation. So let me just move that here. And on success here, we can go ahead and router push user back to the root page. So I'm going to do another john, johndemo.com, demo.
And after success, it should redirect me back to here. Great. So Now the mystery for us to solve is why does this display null? So I think the best way to find this out is just to finish the login screen, and then we can confirm that it's something with our script that we copied, right? So we can do this quite easily.
Go inside of the modules, auth, UI. Copy everything from sign up and just paste it entirely here. Rename this sign in view. Instead of register, you will be using the auth login mutation. Everything else can stay the same.
You are no longer using the register schema, you will be using the login schema. So we can go inside of our auth procedures here, find login. It's a very simple schema, so we can just move it to schemas here. Export const login schema, like this. Then you can go back inside of the procedures in the login base procedure, add login schema.
And there we go. Now you share both the login and the register schema. So now I'm going to replace register schema. Make sure you're doing this inside of the new sign-in view, right? Login schema.
And I'm just going to replace in all places and we don't need the username here. Login schema and this will be login.mutate. And we no longer have to watch for the username errors. We don't need this. This will say funroad.
This will say sign up and it will lead to sign up. And this will say welcome back to fun road. The username form field will not exist here, so we can remove it. The email and the password will exist, and this will be login is pending, and this will be login. There we go.
So now if you go ahead and go inside of login, we did not add this yet, so let's just fix that. We don't need form description here. We don't need Zod from the auth procedures because we replaced that with the reusable schemas. But what we have to do is go inside of app, app route group, out, sign in page, and we have to do sign in view right here. There we go.
And now I'm going to closely observe what's going on with my network tab. So I'm gonna log in into AntonioDemo.com with the password of demo. Looks like I'm logged in and inside of here we can definitely see my token and my user here. So I'm definitely logged in but something is going on with my session. Let's go inside of procedures, session here, and let's check what's going on here.
So I'm gonna go ahead and unzlog the session here and I'm just gonna refresh and see what happens in the terminal. So we do have some permissions. The user seems to be staying at null here. Now I'm also interested in the headers here. I'm not sure what all is displayed in the headers, but I do like to see it here.
Now let's see a bit. We have localhost here. And I seem to be having, this is a clerk cookie, which could be From my previous developments. So maybe that's why this is not working for me. What if I go inside of my application here.
And I just clear all of my cookies and then I go into login again and demo and login now I have the fun road cookie so now I'm definitely here but it's still displaying null here So now I want to refresh and focus on the out session here, so I can see what it does. So JSON, yes, the user stays consistently null, regardless of the headers I put in. So I'm gonna have to investigate why that is happening. We are definitely setting the cookie. The path is correct.
HTTP only is correct. The name is outcookie. Maybe the problem is with the cookie name. Let me check local API. Login.
This is the locale. Override access. Show hidden fields. The auth. Let's try with changing the cookie.
Maybe it's this. Though I doubt it. I highly doubt that it's that. So I'm just going to go ahead and log in. Log in and check my application here.
So now I have the cookie both here. So I'm sure, oh yeah, it looks like it has to be the payload cookie, the payload token. Once I've added it to be the payload token, it seems to be working as it should. All right, so I'm going to stop the chapter at this part. So there are some things we have to do next, which is use the authenticated state.
But it's fine because we can do that in the next chapter, and we can also wrap up some other things related to that area. So we modified the users collection. We've created the out procedures. We've created the out screens. And this is the only thing that we failed to do for now.
And now what's left is to push to GitHub. So let's go ahead and do that. So even if this doesn't work for you, I'm gonna explore what it is, and I'll tell you in the next chapter I'm gonna try to find the documentation but yes using payload token seems to be working for me as you can see now it's working so I am gonna explore why that is and how that works exactly. So my chapter name is 08 authentication. So what I'm going to do is I'm going to go to git checkout b08 authentication like this, or maybe what fixed it was me clearing my cookies I don't know let's 0 8 authentication git add git commit 0 8 authentication git push you origin 0 8 authentication and now let's go ahead inside of my e-commerce github create a pull request and don't merge yet let's see what our reviewer will say.
And there we go, the walkthrough. This pull request implements a new authentication feature by introducing sign-in and sign-up pages along with their corresponding view components. It also talks about how we implemented TRPC and React query dynamic session data here, and also new authentication constants, Zod validation schemas, and TRPC procedures. Great, and it also noticed that payload types have been revised, so it added that confirmation for us. As always, we can see each change that we did here.
And we can also see the sequence diagrams for logging in and for registering and you can also see how it noticed the username availability check here. It also detected a possibly related BRs which is true right this is similar to the one when we created the TRPC integration. It also added some useful comments but this is just you know demonstration purposes so no point in changing it to this even though it's completely correct in that case. In here, it noticed that we are missing the actual site URL, which is again correct, but this is just for demonstration purposes. In here, it suggested adding uniqueness check for the user's email, which is absolutely true, but we know that it's already being checked thanks to payload.
In here it gave a tip on using secure true later when we do the cross-domain cookie which is also a good tip. And same thing for the login. Great! So I'm satisfied. I'm gonna go ahead and merge these changes for our authentication.
I'm not going to delete my branch. I will just double check that I have it here. There we go. And now I'm gonna go ahead, git checkout, back to my main or master branch, pull my origin here, there we go, git status to confirm everything is okay, make sure you're on your main or master branch and confirm that your graph properly looks like this with detached for authentication and we merged it back to master excellent so now what I'm going to do is just mark this as complete as well great great job and see you in the next chapter where I will try and come with a confirmation about the ALF cookie so we know what's going on here.