ASP.NET Core Identity with .NET (Web API) and Angular (Part 1/3)

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hello and welcome to asp.net core identity with angular JWT email confirmation my name is Cheyenne wage and I will be your instructor for this course in this course we are going to build a complete real-world application from scratch we will be using svnet core identity using.net7 web API as a server side and angular 15 as the client side and then we are learning about JWT authentication and authorization with roles and policy we are learning about acnet user manager role manager and sign-in manager and we are making use of Entity framework core to create our database and apply migration and finally see the database we are going to do a full implementation of user registration login email confirmation forgot username or password and reset password then we are going to learn how to sign up and sign in using third-party applications such as Google and Facebook account we are going to develop our client application using angular components and we are going to learn about form validation Interceptor npm package installation angular service and ngx bootstrap then we will be using angular off guard and role-based restriction in order to prevent any unauthorized user to access to some certain point of the angular part and then we are going to implement admin panel to create and edit members launch and unlock members and finally we will be deploying and Publishing the end product of our application to Azure and our application will be live and accessible to the internet let's talk about Technologies and applications we are going to use in this course in this course in terms of Technology we are using dot at 7 web API and angular 15 and in terms of applications we are using from visual residual the community version and visual studio code SQL server and Microsoft SQL Server management and we are making use of Postman in order to test our apis and finally we are making use of azure portal in order to deploy our application let's have a demo of our end result of the application so this is the application that we are going to create in this course first of all if I try to log in then we can see form validation here and we have to populate the form in order to be able to login so I populate my four and if I put invalid password then I can see invalid username or password so I make the correction for my password and I try to log it and I have been logging as a player and the player can see play button over here and once they click here they can see only authorized user can view players and if I log out then this time I'm going to login as an admin so I try to log in and when I click on login then I have been logged in as an admin and as an admin we can see an extra button over here so if I click admin then the admin is capable of managing all the members and the admin can create a new member or edit an existing member so for example if I click on edit for the player at example.com then I can see updated member and I can assign different roles to this player so I can make this player as the manager and change the first name to Tom and if I hit update then I can see player at example has been updated and over here I can see the rules for player at example.com is player comma manager and the admin also can launch a user so for example if I log player then I can see play here at example.com member has been locked and then if I log out from admin and I try to log in as a player then I can see your account has been locked you should wait until some certain time in order to be logging so the player account has been locked and he has to wait until this time in order to be able to log it so if I try to login back as an admin then I can go to admin panel and unlike my player so I can see player at example.com member has been unlocked and if I log out and I try to log in with player then I can now log into my account and if the player tries to access to the admin panel so if I type the admin panel over here inside the URL then I can see admin area leave now so we are using Arts card for making restriction for user base roles and I'm going to log out from my player and then let's try to create an account so if I hit create an account then we are going to have form validation for our registration and then I have to fill up all the information then if I hit create account I can see your account has been created please confirm your email address so whenever a user is trying to register they have to confirm their email address otherwise they cannot log in so if I hit OK and I try to log in with the account that I created then I can see please confirm your email because this email has not been confirmed yet and then if I check my inbox then I can see identity app confirm your email so I have received an email hello Adam Jackson please confirm your email address by clicking on the following link so if I click on the following link then I can see email confirm your email address is confirmed you can log in now and if I click OK and login then I should be able to login so any user is trying to register to our application they have to confirm their email address and I can click login and if this user has forgotten his username or password then they can click on login and there is a link over here forgot username or password so the user has to put their email address over here and if I click on send then I can say forgot username or password image sent and if I check my inbox so I have one more inbox and I can see forgot username or password and if I open I can see hello Adam Jackson username is this in order to resell your password please click on the following link so if I click on the following link then I have the ability to change my password and I'm going to change my password from here and in addition to creating an account using our application so if I create account and this time I'm trying to sign up with Google using my own Gmail account then if I click on sign up with Google Now I need to log in with my own Gmail account so now I use another account and I'm going to put my email address and as soon as I have been authorized by Gmail then I can see an access token over here and this access token is coming from Google authorization now I can see creating an account using your Google so I can complete the registration by putting first name and last name then I hit create account and I can see hi teacher so if I log out and if I click on login again and this time I'm going to sign in with the Google account that I have been registered with so I click on sign in with quicker and I choose the account that I have created my account then I can see hi Peter so I have been successfully logged into my application using my Gmail account and if I click logout and this time I'm going to make a user Facebook so if I click on Facebook now I need to provide the email address for my Facebook account so I have been logging with my Facebook account and if I try to log in then I have been successfully authorized by Facebook and I can see the access token that has been returned back from their Facebook and then I need to fill up the first time and lesson in order to complete my registration so I hit create account and then I can see High bed and I'm going to log out and then I try to log in with the Facebook account that I have created so if I click on Facebook then I can see high band and this time I have been logging through my Facebook account so I'm going to log out and I'm going to log in as an admin and I'm going to display the admin portal so I click on admin and I can see all the members available to my application and I can remove any members that I wish to do so for example I'm going to remove this account if I hit delete then I have to click on yes and once I click yes then I can see deleted number of crazy8546 gmail.com has been deleted and this application has been published to Azure portal at the top I can see identity app udemy.azurewebsite.net okay we have done the application demo then let's talk about what are the prerequisites for taking this course in order to take this course you need to have at least one year of web application programming experience with spnet API and angular and you need to have experience with Entity framework as well and you need to have some basic SQL Server knowledge this course is not designed for an absolute beginner but if you don't have one year of experience and you are still willing to take this course then sure go ahead and take this course as I am starting from scratch and explaining everything as detailed as possible and let's talk about who is this course for so this course is for individuals who are interested in leveraging their knowledge of dotnet core and angular to develop an application that simulates a real world user registration and login scenario and this course is also for those who are seeking into learning deep knowledge about asp.net's identity and use tools in their own programming career or their own web application project and this course is also for those who are interested in gaining Knowledge from my own programming experience which I acquired through years of industrial experience I am super excited to be your instructor and teach you some practical knowledge thank you for checking out this course and I hope to see you in my course you can download the course content from from section 1 and from resources so if you click on here and you can click on course contents then you can download the course content available for this course let's start to develop our app by creating a project so we open visually City 2022 and then we click on create a new project so from here I'm gonna choose web API I select this one so make sure to select S3 net core web API and then I hit next then I choose my folder and for the project I name it as API and for the solution I name it as identity app then I hit next and I choose.net7 standard term and with all these settings I hit create okay my project has been created so I can start my project here and if I start this so I can be pop up so I let's click on address and accept a list and continue because it is https then if I hit get and try it out then I can see the weather forecast is coming up so I close this so we're not going to use weather forecast so I remove it right away and from the controller I'm gonna remove the forecast controller as well then I double click on API in order to go to the Cs part so I'm not going to use any nullable enable or implicit using so I make both of them to disable and I save the file and then I save this file I'm gonna have some error so if I open my program.cs I need to print the namespace so I put my cursor on web application and then I hit Ctrl Dot and then it prompts me using Microsoft SV net Builder so I do that and then for the any other red messages I'm gonna do the same so I need to bring the proper namespace for those things as well since I have removed or disabled my implicit usings then after this I open my properties and launch settings so this is where we are going to see the URL of our application I'm not going to use any https for development so for the development we are going to use only HTTP to make everything as simple as possible so I grab this and I remove https and for our application we're not going to use Swagger we're going to use Postman to test our apis so I'm gonna just make this fast and once I save my files I can see my https has been changed to http and inside the drop down I have only the option of HTTP is Express and WSL so I don't see https in here anymore and we're going to run our application using HTTP only and I close all the tabs and just from the beginning I would like to push my application tool GitHub in order to make our application save on a Repository so I navigate to my GitHub account and from here I click on new I need to choose a repository name in here so I name it as identity app the same as the solution name and I'm going to make it public and then I create repository so from here I need to follow up these commands so I open my command prompt inside my projects I navigate to my project and from here I click on here if you're using Windows and then I type CMD before following these commands I would like to create a net git ignore file so in order to do that I just type that net new it ignore and this will go ahead and create my git ignore file so if I open my project from the folder I can see it ignore has been created and if I open this giving your file I can see all the folders or extensions that are going to be ignored in order to be push to the GitHub okay let's push our project to GitHub so I open my command prompt from the folder and then I type git delete in order to initialize the repository then I type git add dot so when I put git add that it's going to add all the files inside this directory or folder and then I type it commit minus M API project created then I hit enter and then I type git branch minus M mean then I'm going to copy this and I paste it in here and then I copied the last command and I paste it in here and you might sign in with your browser so I can see authentication succeeded and then if I navigate to my GitHub and I if I refresh I can see my project has been pushed to my git repository so I don't see it over here so in order to see my GitHub is already in here I can just close my visual studio and open it again so if I close and I open my identity app solution once again now I can see my project has been linked to the GitHub I should see main over here as well in order to begin we need to install some packages for this application we are going to use asp.net core identity I right click on API project and then I choose manage nuget packages and I click on browse from here I'm going to install the first package that is Microsoft Entity framework code.square server so for our application we're going to use SQL Server as a database so I choose this one so if you don't see it in here just search for SQL Server and from the menu you can see Microsoft that Entity framework called the SQL Server I hit install the next package is tools so if I search for tools and if I look for Microsoft Entity framework called tools I can see this package in here so I hit install and this package is going to be used for adding migration to our database I click OK and I accept next package is JWT better so we're going to use Microsoft SP netcore authentication.jwt barrier in order to authenticate the user so I select this one and I install this package and then I'll hit OK the next package is JWT so if I search for JWT I can see system.identitymodel.tokens.jdability and I choose the latest version and I install and the last package that we're going to install in here is identity Entity framework core so I type identity and I should look for Entity framework core so from here I can find microsoft.asp.net core dot identity dot Entity framework core so I choose this one and I select the layers version and I install and just one thing about this versioning since I am using dotted 7 as my.net version so from here I can see a DOT N7 is my version of the data that I'm using for this application and this has to match exactly the first number of the package you're going to install for example if you're using dotted 6 then this should be selected from sixth version not the seven version so I select this one and I install so if I navigate to my CS brush file I can see the packages that I have installed so just a quick comment about this this package is going to let us to authenticate the user using JWT and the next package is identity Entity framework core so this package is going to let us to derive our DB context from Identity DB context and the next package is Microsoft Entity framework or SQL Server this package is going to let us to connect to our SQL server and create our update table inside our SQL Server and the next package that we have installed is Microsoft Entity framework core tools and this package is going to let us to add migration to our SQL Server and the last package that we have installed is tokens.jwt this package is going to let us to create token and validate the Json web tokens okay if you format everything and then I hit save after installing our packages then we need to create our user model so I'm going to create a new folder and I name it as models and I have a user class so I created a c-sharp class and I name it as user and my user class is deriving from Identity user which is from Microsoft asp.net identity so I need to put my cursor and control dot in order to bring Microsoft HP net core identity this class has been defined by Microsoft asp.net core and it's going to have some properties inside so if I navigate to that if I right click and go to definition I can see it has some properties such as ID username normalize username email so everything that has been configured by Microsoft so our user is deriving from this class and I'm going to add more property into that so I'm gonna do prop and I'll press tab tab and the first thing is first name and the second property is last name and the last property is date time date created and I'm going to assign it to daytime.utc now and I'm going to make this property required so I put required data annotation on top of first name and last name since they are both stream so whenever there is a string property it can be not but I want I want them to be not known so I put the required data annotation and since this is a date time it is going to be required by default after creating our model then I'm going to create my contacts so I create a new folder and I name it as data then inside data I'm going to have a class and I name it as context so my context is deriving from Identity DB context where this derives from identity because this because this is a base class for The Entity framework core database context used for identity and since we are using Microsoft ASP net identity so I need to derive from Identity DB context rather than DB contents and for here I'm going to provide the type and that the type is going to be the user so basically it takes the user model and since I have a user class and which is deriving from Identity user I need to pass it over here then I'm going to have a Constructor and inside my Constructor I have DB context of options and I pass context and I name it as options and I pass the option to the base then the next step is to configure our database inside our service so I open my program.cs and below this line of code I'm going to have Builder Dot Services dot at dbcontacts and I pass my contacts and then I'm going to have options and inside options I'm going to have use SQL Server since we are using SQL Server as our database and then I'm going to pass the connection string so the way we do is builder.configuration.getconnection stream and I name it as default connection and I put semicolon at the end so we need to provide a default connection inside our app settings so since we are in development mode I'm going to choose app settings.development.json I open this file and in here I'm going to have another section called connection strings so be careful after naming this has to match connection strings with plural then put the curve breast then I have default connection and in here I'm going to have server equals localhost so my default connection string is server as localhost and the database that we're going to use is identity app so in here I have trusted connection string equals true then I have multiple active result sets equals true and Trust server certificate true in order to get their server name we need to open our SQL Server management studio and whatever you're seeing in the inside server name that's going to be your server name so I need to copy this and instead of localhost I need to paste whatever that's from here so you need to be able to connect with your server name so if I press connect I can see my I have been connected to my database then with this I'm going to add my first migration so I save everything and then package manager console and inside here I type add migration and I name it as adding user to database then I'm going to Target into new location so I put Dash O then data and forward slash migrations so I'm going to put my migrations folder inside my data folder so I press enter and we can see migration has been created inside data folder and this is the table that is going to be built after we update our database so we have asp.net users and these are the three properties that we have added extra to our asp.net users and the rest is all default Microsoft ASP net tables such as SB net claims HP net logins so all these classes are coming from Microsoft asp.net core identity and after this I'm going to update my database so I put update database so this will go ahead and create our database for us so if I open my SQL Server management and if I refresh here and I can see my identity app has been created so I can see has some default Microsoft identity core tables such as SB net users HP Networks in this video I would like to add my identity core services to my program.cs so I open my program.series and after my DB context then I'm going to add builder.services Dot add identity core and then I pass the user class that I just created so I'm going to bring the namespace and then I open parenthesis and then options and inside options I'm going to configure the password requirements so for example we have options.password.required lens six and then I have options dot password that require digit false then I have options dot password that require lowercase false and as soon as I have options.password that require uppercase false and I have password dot require non-alphanumeric false and I have options DOT sign in dot require confirm email and this is going to be true then I put the semicolon in here so this is defining our service so this is for defining our identity core service and these are the requirement for password so if I don't specify all this then by default it's going to have some default password requirements such as it requires a digits value it requires a lowercase it requires uppercase so based on your application you can configure your password configuration but I'm going to make it as simple as possible so I set everything to off except the required password lens we're going to accept minimum six characters for our password and layer in this course and later in this course we are going to have email confirmation so that's why I have options DOT sign in require confirm to true then after here I'm going to have ADD roles and the class is identity role and I need to bring identity rule from Microsoft A3 net core then I have ADD role manager then I have Road manager identity role then I have ADD Entity framework stores and this is going to be context and then I'm going to have ADD sign in manager and I pass sign in manager and this takes a type and the type is user then I have add user manager and user manager and then we have user as a type and the last thing is ADD default token providers so the first thing is allow us to add rules the second one is allowing us to use to make a use of role manager in order to create rules and the third one is providing our context for identity core and the first one is to make a use of sign in manager in order to sign the user in and the fifth one is to get us to make a use of user manager in order to create users and the last one is in order to create some tokens for email confirmation I like adding our identity core as a service I have added extra services in order to make a full use of Microsoft HP net core identity so I have ADD roles manager I have sign-in manager and I have user manager and then I'm going to make a use of some token creation for email confirmation so it's time to create our JWT services so I right click on API and I create a new folder and I name it as services then inside here I'm going to create a new class and I name it as JWT service so in this class we're going to have public stream create JWT and this takes a argument which is user so I need to print my API dot models I name it as user and if you change a string which is rjwt but before that we need to inject some configuration so I create a Constructor and in here I have I configuration and I name it as config then I'm going to initialize my config so I over here I press Ctrl Dot and then I hit this one create an assign field underscore config if you could not find this option so that's because you need to add that into your visual studio so in order to do that you need to click on tools and options then from here choose text editor then choose C sharp and choose code style and then choose name it then in here you need to click on manage naming stars and then hit plus then in here name it as private field and then inside require prefix just put underscore and then use camera case and hit OK so since I already have that this is what I'm going to have so I have a private fields and underscore and this is channel case and hit OK and then hit OK as well and then you need to add a new specification so you have to click on Plus and then from here choose private or internal fields and from here choose whatever you have name it or created just right now and then make it as suggestion so since I have it already here I'm going to delete this one at the end once this is done it's okay and after you have followed those instructions then if I put my cursor over here and I press Ctrl dot then I can see create an assign field so this is going to create a private read only and it puts underscore inside my private Fields property then I'm going to have another private read-only field so I type private returny and this is going to be symmetric security key and I name it as JWT key and my jwc key is going to be new symmetric security key encoding so I need to bring the system.txt .utf8 dot get bytes and then I put underscore config and I'm going to have JWT section and I take the key so I'm going to take my key from my app settings.development.json okay now we need to create our JWT key so I open my browser and inside Google I'll just type random key generator and the first link I'm gonna open this then from here I'm gonna select this one from two five six bit key generator so any random key is sufficient so I copy this one and I navigate back to my visual studio and I open my app settings.development.json and then after here I put comma and I type JWT then column and I put curly brace then key colon and I paste that random key that I copied then I have expires in days so for development I put 15 days and then issuer color and for the issuer we need the URL for the API so I open my launch settings.json and from HTTP I copy this this is the URL of our development API and I head back to my app settings.development.json and I and inside quotation I paste their URL so if I open my JWT service from here I can see we are going to take the key from app settings.json and since we are using development so it automatically takes from upsetting.development.json but from production it's going to take from app settings.json that's why we have specified our values inside app settings.development Json since we are doing our development for now and then it's going to look for JWT section and from that section it's going to look for key section so from JWT section then inside JWT section it's going to look for key section from the key session it's going to take this whatever the value is inside here so it's going to paste that value in here and get bytes is taking a string as an argument then it converts to byte array and this symmetric security key is taken by the array that's why we are using encoding WTF 8.getbytes so basically this transfer my string of K into byte arrays and then symmetric security key is going to create a key for us and it's going to put it inside out underscore JWT key and with this JWT key we are going to both encrypt and decrypt the Json web token and after here I'm going to have War user claims equals new list plane and then I'm going to assign some claims inside there so I open and close calibrates the first claim I'm going to have is new plane claim types dot name identifier then user dot ID so I'm gonna copy this two more time and the next one is going to be email and this is user dot email and the next one is going to be give any so this is going to be first name and the last one is going to be a surname and of course it's going to be the last day I removed this extra line and then I put some color and then I'm going to have our credentials equals new signing credentials and then I'm going to pass my key so it's going to take a key and the algorithm so for my key is underscore JWT whatever we have populated over here and then I put comma then we have security algorithm dot hmaxia512 signature then we are going to have our token descriptor equals new security token descriptor then I open and close query price so for the subject we are going to have new claims identity and I pass my user claims that I have assigned here so I copy and paste over here then I put a comma expires is date time dot UTC now dot add days and I'm going to have its dot parse and I pass my config and from config I'm going to have again JWT section and expires in days then I put comma then we have sign in credentials its credentials and we have issuer is again underscore config JWT and issuer and I put semicolon over here and after this we are going to have War token Handler is new JWT security token Handler then we have wire JWT is token Handler dot create token and we pass the token descriptor and finally we have returned token Handler that's right token and the passage JWT now I would like to explain what I'm doing over here so at first I'm going to have a Constructor and inside my Constructor I'm going to have a configuration injected inside this class then inside my contract there I'm going to have a JWT key provided by whatever values we have put over here so we are going to have JWT key and this key is going to be used for both encrypting and decrypting the tokens then inside my create JWT method I'm going to receive an argument of type user then I'm going to have some claims inside my token so whenever we are creating a JWT token we are going to have some planes inside that token what kind of claims are we going to have inside that token the first one is the user ID and we place it inside name identifier the second one is email and the third is given name and the force is surname and we simply can create a new claim like this so if I put new claim and if I want to have my own name I'm going to have my own crazy and whatever value you would like to put this is the value so for demo I'm going to display this but I'm going to remove it later on and after this we are going to have the credential so this credential is new signing credential and this sign-in credential is coming from system.identitymother.tokens.jwt the package that we have installed and this sign-in credential is going to take a key and then the algorithm So based on what algorithm is going to generate our credentials so we passed the hmaxia 512 so this is the most secure algorithm so far to generate a credential and then after that we are going to have token descriptor so this is basically our description of our token so inside our token description we are going to have a subject and this is going to take claims identity and this claims identity is going to take user claims so this user claims is list of claim and they have assigned 5 frames inside our tokens so inside our subject we are going to have all these values then our token will be expired in some days so we have specified over here so we said daytime.utc now dot add days and then we get the value from our upsetting to development.json I have that value over here expires in days and this is going to be 15 days for development since that is in string we need to pass it to integer that's why I have used in dot parse so this will convert string into integer then we have a signing credential and our signing relation is whatever we have specified over here based on the JWT key and the algorithm and then we have our issuer so inside our token we are going to have an issuer and and the value for the issuer is going to be taken from upselling.development.json and from issuer section and for the issue section we have have just put the URL of our API application that's why I have copied this our API URL inside our issuer and then inside our JWT service I'm going to retrieve that from my app settings.development.json but for the production we are going to look for app settings.jsons rather than answering the development.json then we are going to have a token Handler and we are going to create our token based on the descriptor and we are going to return our token to whatever is going to call this method so now we need to provide our JWT service class inside our program.cs in order to be able to do dependency injection for rjwt service so I open my program.cs and after my video.service.dbcontacts I'm going to have Builder dot Services dot at scope then I pass my JWT service class and I close by semicolon so by this line of code we will be able to inject our jwc service inside our controllers and I save everything and finally we need to implement the authentication Service inside our program.cs so after my Builder that sells ad identity core just after here I'm going to have Builder dot Services dot add authentication then in here I'm going to have JWT error defaults and I need to bring from Microsoft SP net core authentication.jwt better the package that we have installed earlier then I have authentication scheme and after here I'm going to have a DOT add JWT Bearer and we are going to have options and I open and close query press and inside options we are going to have token validation parameters is new token validation parameters so I select this one and then I open and close carry brace again and then we have validate issuer sign in key is true and then we have issuer sign in key is new symmetric security key then we have encoding dot utf8 dot get bytes and then we are going to take our string value of keys inside our app setting the development.js some once again by using Builder dot configuration and then inside configuration I put bracket and JWT column key and after here we are going to have valid issuer is Builder dot configuration from JWT section and issuer and we have validate issuer is true then we have validate audience is false and I put semicolon at the end of these two so first of all we have added this line of code in order to authenticate our user by using JWT token in order to authenticate our user using JWT and we are going to authenticate the user using Bearer so if I hover over here we have better inside here so we are using add authenticate what type using Bearer then we have ADD JWT Bearer and we have options and inside options we have options the token validation parameters is new token validation parameter and inside the token validation parameter we are going to have validate issuer signing key so we are going to tell that we need to validate our token using the JWT key that we have provided so this line of code is telling we are going to validate token based on the key and then we are going to tell where to find the key so if your signing key is new symmetric so again we are going to generate that key based on and whatever we have over insert our app settings.development.json so we are going to use Builder configuration and this builder.configuration is the same as whatever we have over here underscore config so if I navigate back to my program.cs we have billiard.configuration and from the JWT section look for key section so inside our app setting the development JWT section look for key section and this is the key that we are going to use for both the tripling iron in encrypting tradability so we pass that key and and based on that key we are going to validate whether this JWT is valid or not and then we are going to tell validate our issuer over here and we are specifying the valued issuer is the URL of the server and we have specified the URL of the server inside over here JWT issuer and for the validate audience we set it to false so we're not going to validate any audience the audience is going to be our angular application so after this we are going to add the pipeline so in order to do that inside our configure the HTTP request Pipeline and just before app.use authorization we are going to have app.use authentication so by adding this python we will be able to authenticate the user an authentication should come before authorization so by the terms of authentication we verify the identity of a user and by the term of authorization we determine their access rights by using use authentication we are going to determine that whether they have logged in or not and by the term of authorization we are going to determine and what type of permission they're going to have to access to different routes and we are going to use that later in this course and then I save everything okay after we configure our authentication inside program.cs then it's time to create our very first controller so I right click on controller and then inside here I select controller then from this menu I choose API and API controller empty and I hit add and for the controller name I'm going to name it as account so make sure this is account controller and I hit add the root of our controller is going to be the URL of the application forward slash API forward slash the controller name and in this case is account so I'm going to inject some services so in order to do that I'm going to create a default Constructor then the very first service we're going to inject is JWT service the service that we have provided and I name it as JWT service and I'm going to initialize this so I control that and create an assign field underscore jwc service and I put comma and then the next service is going to be sign in manager and then I pass our user as a type and then I name it as sign manager and I'm going to initialize this as well and the next service is user manager so I select user manager and I pass user and then I name it as user manager and I'm going to initialize this as well so I bring this into a new line our signing manager is responsible to sign the user in and the user manager is responsible for creating the user and they both are taking the type since we're using user and this is derived from Identity user so we are passing that user class inside the type then I'm going to have a private API method so I'm going to specify this region private and per method and then I end the regions so this is basically like a comment it doesn't do any coding so it's just for credibility for the developers and then inside here I have private user dto and create application user dto and we are going to receive a user class and from here we are going to return new user dto we don't have the user detail at the moment over my API project and then I create a new folder and I name it as dtos WhatsApp dto a DTR is data transfer object and this is the class that is going to be passed to the user or the client if you're coming from NVC background so this is like a view model The View model that we are going to pass to the client so inside my DTR I'm going to have another folder and I name it as account so this account folder inside details is representing any details that we are going to use inside our account controller so inside my account folder I'm going to have a class and I name it as user dto the same name that we are specified over here so since we already have created that so I can bring the namespace so if I put my cursor over here and I press Ctrl dot then I can see using api.d to use that account and the error goes away so for my user dto I'm going to have prop string first name prop string last name and prop string JWT so I head back to my account controller inside here I'm going to have the first name is user DOT first name last name is user.lass name and JWT is underscore jw2 service that create token and I pass the user object there as well then above region I'm going to have my very first endpoint which is logging so I use HTTP post since we're posting a model to this method and I name it as library and over here we have public async task action result and user dto and I name it as a login and we have login dto and we have to create that model as well so I name it as model and I open and close the curly brace so inside my account folder I'm going to have login details also I'm going to hit add and class and I name it as login dto the login detail will have prop of string username and pop off screen password and both of them are required so I put required attribute on top of both of them and then I head back to my account controller and this error has gone whenever the client is trying to hit this endpoint they are passing a model and that model is based on login DQ and that model really contains a username and a password which is here then over here I have our user is await underscore user manager that find by name async then I pass my model dot username So based on the username that the user is providing we are trying to retrieve the user object from our database and then if this user object is not then we simply retain unauthorized so I say if user is not then return unauthorized and for the message I say invalid username or password and I put a semicolon then I'm going to check for the email confirmation so I'm checking if user email confirm is false then I return unauthorized again and I say please confirm your email and I put semicolon then I'm going to have a VAR result is a rate signing manager dot check password sign in async and this takes a user object and the password so this is model.password and for the third argument this is going to be lockout on failure so we put it fast for now and then I put semicolon then I have if not result that succeeded so if the user has failed to provide the proper password then simply return unauthorize again and we say invalid username or password so we try not to be clear for the user whether they have input the wrong username or password so that's why for both message we have invalid username or password and if the user has successfully input their username and password and their email confirmation is true then we return create application user dto and be faster user so this is going to hit our private helper method and this private helper method is going to return a user dto and that user detail contains first name last name and jwdt and the JWT is being populated by the service that we have created in their previous videos so a little explanation for here we are using user manager to find a user this find by name async is coming from Microsoft SB net core identity and then this will take a user learning and based on the username it's going to fetch the user from the database and provide our user object over here and if could not find the username that means the username is invalid so that's why we return unauthorized and then we're checking again if the email confirm is false that means the user has not confirmed their email password so we return unauthorize again please confirm your email and then we have bar result and using this time from sign in manager and we're checking for the password and this check password sign in async is going to take a user again and the password and for the third argument if the user has input the false password so it's going to lock out the user but for now we are just simply say don't lock out the user even though they input the wrong password and then this result will contain some value and if result that succeeded is false so that's why I put this question mark then simply return and authorize again invalid username or password and if the user has input the correct password then create the application user detail and for the register method so I'm going to have HTTP post once again and I name it as register so this is when the user is trying to register an account for our application so I have public async task and this time I'm going to have our action result and I name it as register and we are going to receive a register PTO and we name it as model and I open and close the curry press so we are going to create this registered detail so I copy the name and inside my account I'm going to have another class and I name it as register dto for the registered detail we are going to have four properties the first one is first name the second one is last name the third one is email and the last one is password so we are going to use the email for both username and email so that's why I have only one email property over here I don't have username so this email is going to be used for both email and the username and I make all of them as required so the user has to provide all these properties for their first name and last name I'm going to set some limit for the how many characters the the user can input so the way I do I say string length and I open and close parenthesis and it's going to be 15 and Min length is 3 and for the error message I'm going to have first name must e at least and maximum characters so I'm trying to say that the first name has the maximum of 15 character and minimum of three characters so anything below 3 or above 15 if the user has input for the first name then they see this error message and this tool is referring to 3 and 1 is referring to 15 over here then I copy this and I'm going to have the same data annotation for last name so instead of first name I specify last name and I'm gonna have for the password as well but for the password we are going to have for the minimum length we are going to have 6 and over here I'm going to specify password must be at least 3 and maximum 15 characters for the email I'm going to use a regular expression so the way I do I say regular expression and then I open and close the parenthesis and I put a quotation over here and this is going to be my regular expression and just after closing the quotation I'm going to have error message and I simply say invalid email address in order to have a regular expression for email I open my browser and I navigate to rejectsleep.com then inside here I put email and if I search then this is going to give me some regular expression for email verification so I'm going to pick the easiest one so I copy this regular expression and I head back to my register detail.cs and over here I paste that in here then I head back to my account control.cs and over here we are going to use from another private method so I have private async task and this retains a Boolean and check email exist async and this takes a email address and we are going to make a use of user manager so I say a great user manager Dot users.ne async and we have expression so X goes to x x dot email is email.2 lower and I put semicolon so there's a typo so I put check email async and this private method is going to make a use of user manager from the user class we are going to return a Boolean whether true or false if this expression is true and if this finds any email address then it returns true if it doesn't find any email address then it returns false we are going to check if the user going to register with the same email address that has already been register so over here I'm going to have if a rate check email exists async and a pass model dot email if that's true then return a bad request and we say and inside here I'm going to use string interpolation so I put dollar sign and I put the quotation and in here we have an existing account is using and I put the carry brace and inside the bracket I'm going to put model dot email then I put comma email address please try with another email address and I put semicolon so I'll simply return this message and I say an existing account is using the same email address that the user has posted to this method and please try with another email address if the email does not exist in our record then we save our user to add is new user object for the first name we are going to have model DOT first name and for other properties we are going to convert to lowercase so if the user has some uppercase for the first name or last name we are convert everything to lowercase and for the last time we have model dot less number two logo and username is Mother dot email dot to lower and the email is Mother dot email dot two lover again we are using the email address for both username and email address and for now we are going to have email confirmed is true because we are going to handle email confirmation in the upcoming videos but for now we simply say the email confirm is true and then I put semicolon then I'm going to have our result is a weight user manager dot create async and we pass the user to app and model dot password so we are going to create a user based on the object that we have created and the password that we have then we check if not succeeded the result then return match request and this simply pass result dot errors and if everything goes well then return okay your account has been created you can log in so with this our register method has been finished if I open my SQL management if I open my identity app database and inside ASP net users if I hit select a thousand then we don't have any record at the moment but if the user is providing some value over here and this method is going to create a new row inside my spnet users now it's time to test our API controller so I run my application and I'm going to open my Postman then inside here it's better if you log in inside the postman application and you can see whether you have login or not over here and then inside the collection I'm going to use a new collection so I click on new and then I click on collection and for the collection I'm name it as my application identity app and then I open here and then I'm going to add a folder my folder is going to be account so this account is representing our account controller for the first request I'm going to add a request and I have register this is a post method so I select post for the URL I'm going to copy my URL from launch settings so I copy this and inside here I paste it over here and I put forward slash API account and then forward slash register then for the body I click on body and I choose raw and from here I choose Json then we have to provide a Json body so and that Json body is going to represent our register dto so if I might open my registered DTR we are going to have first and last name email and password so for the first name we have John and for the last name we have Smith for the email we have J Smith at example.com then for the password you have one two three four five six and if I put a breakpoint inside my register and if I send try to send then I can hit my breakpoint and if I hover over my model I have are the properties that I have provided and I'm going to step forward so I use this button and this is going to check if the username is exist so this retains false so it continues and if I continue it's going to create a user object and provides those property based on the model that we have received and in here we are going to create our user inside our spnet user table and this result is succeeded so it continues and it returns okay if I continue I can see your account has been created you can log in and if I open my database once again and for the asp.net users if I execute I can see my journey space has been created with the password that we have provided I would like to try with some bad register models so I open my Postman and inside my register I'm going to use some longer name so I put more than 15 characters so I copy this John and I paste it over a couple of times and if I try to send then I can see first name must be at least three characters and if I do the same for my last name 95 sand I can see these error messages last name must be at least 3 and maximum 15 characters and if I add some invalid username I have an embodied username so if I send I can see invalid email address and this is going to compare against the regular expression but that we have added I put everything back to whatever it was I try to save and I'm going to log in with Johnny Smith so inside my account I'm going to hit these three dots for the here I'm going to add a new request and I name it as login and this is going to be a post method as well and for the URL I'm going to copy this URL and I paste it over here and we have API account login and we are going to click on body and from the raw Json we have username and password so I head back to my Postman and for the username we are going to have whatever username we have created over here so I copy this and I paste it over here and for the password and for the password we are going to have one two three four five six and if I send I can see a body that contains the user video that we have created inside our login method and this is the JWT token so if I copy this and if I navigate to the browser and I paste it inside jwp.io I can see these are the values that we have provided inside rjwt so we have the name ID we have the email address even name family name and this is my own claim name that I have provided inside my JWT service so this is basically that my own claim name and the value is this is the value if I see this is the value and the expiry date and issue date and the issue and the issue is our API URL whatever we have is specified over here this is the issuer so since I'm here I'm going to remove this it was for the demo purpose and I'm going to remove this as well and I save and if I press hard to reload then this is going to apply the code changes for me without trying to restart the whole application so if I send again and I'm going to remove this breakpoint I'm going to continue then I'm going to have a new Json web toolkit if I copy this Json web token and I paste it over here then I don't see that custom claim type that I just created earlier so I'm going to try with a bad username or password so I put one over here if I try to send then I can see invalid username or password and if I correct my username I incorrect password then I can see the same error message embedded username or password and inside my Postman I'm going to save these two inside my collection so if I control S I can see this has changed to the post request and for the register I'm going to save it as well in this video I'm going to create another endpoint and that is going to be refresh user token so I start my application and just above login I'm going to have bracket authorized since this endpoint is going to be accessible for only authorized user only and then I have HTTP get and I name it as refresh user okay and for here I have public async task action result and user dto I name it as refresh user token so I have this spell over here so this is refresh user token and then this is going to receive nothing then inside here I'm going to another user is away user manager dot find by name async and this is going to look for the username if I have it over here this is going to look for a username and how do we retrieve our username since this is a authorized method then the user has provided the JWT better and inside the JWT better we are having the username inside one of the claims I'm going to retrieve by user dot find first plane types and I need to print using system security.claims dot name I put question mark since this might be another and then I put value and from here we are going to return create application user dto and we pass the user object once again if I try to test this endpoint I'm going to run my application and inside my Postman I'm going to have another request and this is going to be HTTP get and the name is is a refresh user token and for the login I'm going to have the API URL so I put over here and then API account and refresh user token if I try to hit this endpoint without anything I get unauthorized because I'm only allowing the authorized user to access this endpoint if I put a breakpoint over here I'm not going to be caught to this endpoint I'm only seeing 401 unauthorized we need to have a proper JWT inside our authorization so I click on an authorization and from here I'm going to choose Bearer token and inside my token I need to have the proper token so I'm going to log in once again in order to get a new token so I send and I'm going to copy this token and I head back to my refresh user token and I paste it over here and if I send now my user is authorized so that's why we can see we are getting part in this breakpoint and if I step over so this is going to and we have received a system argument null exception and this is what happened so we are trying to retrieve username from our case but we haven't provided that claims inside our JWT service so if I look for my claims I can see only we have provided the email and the name identifier and given name and surname what we haven't provided for example claim types that name so in order to do that we can simply add another claims inside our claim types or we can retrieve the username from the email address since they both are the same so I'm going to use the second option instead of claim types that name I'm going to use email and if I save and I hit hot reload and if I send this request once again I'm going to set forward and then in this time we are going to have a user populated inside here based on the user manager find by name AC and this is going to hit my private method once again and it generates a new token for us so if I continue and if I see my personal I can see this is the response that we have received from our API so for my Postman instead of copying and pasting the application URL I would like to add a variable inside my this collection so inside my identity app I hit these three dots and if I click on edit then inside my variables I'm going to have URL and for my URL I'm going to use the same URL that we are using over here so I copy this inside here for the initial value I'm going to paste it over here and for the current value also I'm going to place it over here and I'm going to save it then I close this and inside my login instead of this hard coding my URL I'm going to have double query Place URL and I close my double kill replace and as well as for my register so I'm going to use URL inside here as well and if I say and save this as well then we are going to have a proper API collection for ourselves and I save it over here if I try login then I can see the response and another thing that I would like to do whenever we are trying to login I would like to save my token inside a global variable so inside my login request I click on test and then I use the following code so I'm going to have cost user and this is going to look for the response and then from the response I'm going to have pm.groupals.z JWT and user.jwt so this user is going to be the value that we have received from the API and from that value we are looking for user.jwt which is here there are token that we are seeing over here and this will set the JWT variable based on whatever we have over here inside our Global variables so if I save this and I can access to that JWT variable inside my refresh user token so instead of copy and pasting the talking manually I'm going to remove this and I'm going to have JWT over here and if I save so if I log in then I'm going to have that JWT provider over here and this JWT if I send then I can see I'm getting cut in this background so if I remove my background and if I continue I can see a new JWT has been created and I can save this new JWT over here as well so if I open my login and from the test I copy this and for my refresh user token I do the same so I click on test and I paste that over here as well so this is the end of this section I'm going to push my changes into GitHub so I start my application and I click on git changes I make it common as zero tool this represents our section number two API project setup asp.net core identity added and I commit all my changes and I push to GitHub in this section we are going to set up our angular project so first of all we need to install node.js and after that we need to install angular CLI you have two options to install node.js for the first option you can navigate to node.js after you navigate to node.js then click on other downloads and from here I click on all downloads and I look for 18.10 so if I double click on two dots and then I can see 18.10 over here this one and then based on your operating system you can install that node.js but there's another alternative way if you want to have multiple node.js then there's another alternative Way by installing NVM so you can install NVM based on your operating system but since I'm using Windows I show you how to install NVM on windows so search nbm install Windows before installing NVM you need to uninstall any current version of node.js from your machine and after uninstalling then search for nbm install Windows and click on this GitHub link and from here you can choose or click on download now and from here you can click on NVM setup.exe then you can install NVM and after you have successfully installed NVM if you open your command in as administrator then you can verify that by doing NVM list so right now I have three node.js installed on my machine but I'm going to install node.js version 1810 so the way I do NVM install 1810 0. now this is going to install my node.js for my machine and I can choose NVM use 1810 0. so now if I do node version I can see my node version is 18.10 and if you are having another application using another node.js so this is the alternative way to have multiple notches rather than uninstalling and installing another node version after this we are going to install angular CLI so if I do Ng it says NG is not recognized so we need to install that so the way I do I say npm install minus G at angular CLI at 15. we're going to use from angular 15. and if I do NG version I can verify that by running this command so I can see my angular Sierra is 15.2.5 my node is 1810 and npm is 8 19. so after we have successfully installed both node.js and angular CLI then I navigate to my app folder and from here I type CMD in order to run command prompt inside this folder then I say NG new and I name it as Client app and I press enter and you ask for would you like to add the angular routing I say yes and then we are going to use from CSS and this takes a while okay after installing my angular project I can see inside here Client app so I can navigate to my client app so I say see The Client app and then I type code dot so I'm going to open my angular site from Visual Studio code so I say yes I trust the author and I can see my angular project has been installed successfully so I can open the terminal from here and I say NG serve Dash o in order to run the project okay my angular site is up and running and everything is working as normal in this section we are going to clean up our angular project so I close all my other tabs and I open my node.js and from here I open my source app and I open my app.component.html and we are going to delete everything and we're going to have simply identity app inside a P tag and if I save I can see identity app now I would like to install bootstrap and we are going to use from ngx bootstrap so if I search for ngx bootstrap and the first link so we're going to install ngx bootstrap version 10. so if I click on get it started so I can see at the bottom I can see version 10 is compatible with angular 15 and that's the same version as we are using so I'm going to make a use of that so I navigate to the top and we are going to install ngx bootstrap using NG add so I copy this and I open my terminal so from digital Studio code I click on plus button and this will open a new terminal for me so I can paste that over here and I'm going to specify the version so I put app and I put 10 over here so we are going to insert ngx bootstrap version 10. that's the same version as we are seeing over here I press enter and this is asking would you like to proceed I say yes and this has updated my package of Json angular.json and my app dot module so if I open my app that module it has added browser animation module and inside my angular.json I can see it has added these two line of code and also as well as the package.json so if I open my packet.json I can see ngx bootstrap over here version 10. and this has installed bootstrap for me elsewhere so the version of the booster we're using is five I can verify that my bootstrap has been installed since we have updated the angular.json files we need to restart our angular application so I press Ctrl C and I put NG serve once again and this time if I refresh I can see a different format for my P tag so this verifies that bootstrap has been installed inside my angular application in this video we are going to create a bunch of components and folder structure our angular project so I close all the tabs and from the app folder I right click and I hit new folder and I name it as shared so this is going to include every shared components or modules that are going to be used among the entire application and then I navigate to SRC app and share and I create a module so I say so I type NG GM shared and I make it as flat so this has created a shared module for myself and then I right click on share and I create a new folder and I name it as components and inside components so I navigate to components and from here I create another folder and I name it as errors so this is containing their error components so I navigate to arrows as well and in here I'm going to create two components so I say NG GC and the first one is not found and I skip the tests so this is the not found page for my application and then I'm going to create another and I say NG GC and I name it as validation messages and I skip test as well and this is the validation messages that we receive from the API so we're going to deal with these two components later on and then I navigate back to my app folder so I say I put a bunch of dots to navigate back to SRC app and in here I'm going to create a component called navbar so I say nggc nav bar and I skip test since we're not using any testing for angular project so if I minimize my shared I can see navbar over here and then I'm going to create footer and as well as home and we are going to have account folder as well but that account folder is going to contain bunch of router links so the way I do I say ngg and I name as account so if I press enter inside my app folder this is going to create account module and it puts into a folder called account and that account is representing for my account controller inside my API so if I see I can see account module over here so I navigate to account and I'm going to create another module for routing so I say NG GM and account Dash routing and I make it as flat if I don't do flat then it's going to create a camera thing inside a new folder but if I do flat it's going to put it inside the same folder and then I'm going to create the service for my account so I say NG GS and account and I skip tests and I'm going to create two components one of them is login and one of them is register so I say NG GC and login and I skip test and I do for register and if I open my account module I can see login and register are declaring inside declaration in this section we are going to lay out our website so I open my app.component.html and first of all I removed my P tag and I'm going to replace this app nav bar so we are going to have a navbar at the top of the page and after here we are going to have div dot container dot margin top five so I'm using bootstrap class container and margin top 5. and I'm going to give it aside mean height 700 pixel and inside here I'm going to have my router outlet and after here I'm going to have my footer and if I save I can see now for works and footer works so this is a little too long so I'm going to remove 700 and instead I'm going to have 500. so I can see navbar works and footer works but I don't see the home page over here so we are going to create our routes inside our app routing module so I open up routing module and inside routes I press enter and I'm going to give the first one path and for the default we are going to use home component and I put comma and then for path not found we are going to use from not found component and another path for any path that is not assigned over here so we put double asterisk and we're going to navigate to not found component as well and we put path match full if I save the app routing module and if I open I can see home works over here because this is going to put our home components inside the default path and this is a default path and for the not found if I copy this and I put forward slash not fan you can see not found over here and for any other path that is not defined so I put one two three and not fun will appear as well because because that is going to be triggered by this code so any path that has not been assigned we are going to forward it to not found component and I'm going to assign my account routing module as well so the way I do I say const routes of type route so I need to import angular routes so I can see that has been imported equals and we're going to have path and for the login we're going to have login component and for the register so I copied this and I paste it down here so we are going to have register and this is going to be register component and then we're not using any common modules inside our account routing module so I remove that and instead we are going to have router module and for child we are going to pass the routes that we have assigned over here and since we are inside another routing module we need to export it as far so I say exports and router module and then we are going to import router module inside our account module so I copy router module and inside my account router and inside my account module I'm going to have imported as well over here so I control that and add the import in this way we are going to import account routing module inside our account dot module and then we are going to open app routing module and we are going to use lazy loading so the way I do I enter over here and I'm going to have a new path and this is account and load children and we have a callback function import and we are going to import the account module so I'm going to go inside account and account module and then we have then option and module and module dot account module and I put comma over here so with this we have implemented the lazy loading so if I put a comma so this will load my account modules whenever we are going to navigate it to account route if I save and I open my browser so instead of this I'm going to have account then I have forward slash login so if I do this I can see it login is not appearing so there must be some misspelling so the error was inside my account that module we need to import account routing module instead of account module so that was a mistake there so I removed my router module from account module but instead we are going to import account routing module and if I save and if I navigate back to my browser so now I can see account and if I put login so I have been navigated to login components and I can see login works if I do register I can see register works so in this video we're going to code our nav bar so I open my navbar.component.html and we remove the existing and we started header then we have now so we have nav with the class of nav for number expand large now bar dark and BG primary then we have div.container and after here we have a and we remove the href and for here we have IMG SRC assets images logo .png and we have class of me3 and ALT is logo inside this section we have a logo.png file so you can download that and after you have downloaded there so you're going to copy and paste that inside our asset so I'm going to create a new folder and I name it as images um and this is the logo that we're going to use so I drag and drop over here and this is a simple just a PNG file and this is our logo for our application and if I save and I open my browser I can see identity app over here so I have Mrs spelled container this should be container so if I see I can see this has been pushed a little forward and after here we have a button and inside our button we have spam so this is a hamburger button for open and close our navbar for mobile devices or a smaller screens then we have div Dot and inside my div we have UL Dot and then we have Li dot nav item and for the first one we have a DOT nav link and we have home over here and I copy this and I paste down here and we have play if I take a look I can see home and play over here and then we are going to have another UL and inside here we are going to have a li.nav item and here we are going to have a tag dot BTN Dot for the a type we remove the href as well and here we have create account and I copy this and I paste it down here and for here we are going to have login and I removed the MX2 as well so if I save everything I take a look at my browser this is their page that we have currently so we're going to design our footer as well so I open my footer and footer.component.html and from here I remove the existing code and I say footer and after here we have div Dot and here we have H6 so we are going to create our current year inside our computer.component.ts so I copy this and I open my footer.component.ts then over here we have current here equals new date dot get full here and if I save and I open my browser I can see copyright 2023 identity app okay let's set up our navigation for example if we click play home or create account so we want to navigate to those URLs so first of all I open my share that module and then we are going to import router module so I press enter and say router module and then we need to export this as well so I say export and I put router module over here and inside my app router module I need to import my shared module so we are going to import share module inside our app module over here and inside our shared modules since we are going to use this shared module inside other components that's why I have imported browser module inside my shared module and by importing router module we will be able to use from browser link and then I open my navbar.component.html and inside here I'm going to have rafter link and forward slash so this is the default route for my home component and that's representing over here so I navigate back to my HTML and for play I'm going to have rather link for Slash play we don't have the play component yet we're going to create very soon for my create account I'm going to do the same so we are going to navigate it to account and forward slash register and I copy this and I paste it over here and instead of register we are going to be navigated to login so if I save everything and I navigate back to my website so if I click create account I can see register work if I click login I can see login works if I click on home home works but play doesn't work because we don't have that at the moment so I'm going to create that over here so inside my second terminal I navigate back to my app module and in here we are going to create our play component so NG GC and play and I skip this so this play component we're not going to touch in this course but this is going to be only visible for any authorized user so that's why I have created a dummy play component and but we're not going to touch it anyway in this course so I have to open my app routing module and I have to create another path for my play so I copy the first one I paste it down here and IN Zip we have play and for the component we have play component so if I say and if I click I can see play component works so now I would like to add the active link and instead of white I want to be brown I open my nav bar Dot component.html and in here we are going to have router link active and I pass active class so I copy this for every router that we are going to do a pastel over there for the active we are going to create a class inside my neighbor.component.css so we have active and color is simply Brown and this needs to be important so I put question mark and importance if I select important then this will overwrite any other classes that has been defined inside bootstrap so now I can see if I click in any of the link that is active I can see active cloud has been applied but for the home I can see it's even though we are inside the create account I can see that has been selected as well so in order to fix that issue we need to have another option and that is going to be inside a square bracket we have router link active options for the options we are going to have exact colon true and if I format everything so we have to have this as well so if I save then that has been resolved in this video I would like to install a new template for my website so I navigate to boots watch and we are going to use from woodswash template for bootstrap so on top of our bootstrap we are going to apply a new template and we are going to make a use of this the first one so inside here I open a new terminal and I say npm install boots watch and I press enter and then I have to open angular.json and I copy this down and we are going to node modules and Boots watch and dist and then we are going to put another forward slash and inside here we are going to make a use of this so I copy the name and I put it here but instead of capital c i put it lowercase C and this has to be node modules boot wash and this we don't need CSS and the template and bootstrap Dot so I remove Min dot CSS so if I say and since we have modifier our angular.json we need to restart our angular application so I'm going to stop my angular and then I do NG serve after we have restarted our angular site if I refresh my website I can see the effect of the template that we have installed on top of our bootstrap and that is exactly the same template as we'll see if you would like to try another template you just need to Simply replace the name from here to any other template that you would like to see okay now we want to design our login and register page so I open my login.component.html and I close all other tabs and in here I remove the P tag and we are going to have div Dot then we have div Dot then we have Main and after here we have four and we don't need action so I remove that and I put enter and in here we have div Dot and inside my div we are going to have H3 and we have login and after my div we are going to have another div and inside here we have input and the class is form control the type is text and placeholder is username and after the input we have a label and I copy this and we are going to have another div of form floating and this is going to be password and the type is password and after this we are going to have div Dot and in here we have button Dot and the type is submit and we have log in and after my form we are going to have another div and in here we have a DOT BTN and we remove the href and inside my a tag we have H6 so if I save and take a look at my website if I navigate to my login I can see login over here so this has to be in the center so and after justify content we have Center so I can see login and this is the four and this is the password and this is the button for login so I'm using simple bootstrap classes the first one is D Flex so we're using deflex and justify content Center then we are going to have call 12 and for a smaller we have called five so for larger screen we have core five but for smaller we have called 12 so if I restart if I resize my browser I can see this is called 12 but if I make it as a larger so this is called five and these are all basic bootstrap classes that I'm not going to go over but we're using bootstrap in order to have a good looking application and inside my form we have a login so this is the login that we see and after that we are going to have a form group before it used to be form group but now we are using from form form floating so there is no more form group for boostra 5. so we are using form floating and we have the input and label and we have one for the username and one for the password and at the bottom we have login button over here so that's how we can see the layout of my login component okay I navigate back to my login component and so we don't have the username but we're using email as both for the email address and the username so I switch username into email and this should be email if I take a look so I can see email for my login page so we're using email in order to be able to like to the application and for my create account so I would like to update the HTML so I copy the whole thing from login component and then I navigate to my register component.html then I remove the existing P tag and I paste that over here for the login I removed this and I press enter and we have let's and for here we have email and password but before email we're going to have first time and awesome so I copy this div and then just above here I put two more time so we have for the first one we have first name and the four is should be first name and placeholder should be first name as well and the second one is last name so I copy this and I paste it over here and for the four we have the last name and if I save and I take a look at my create so we have first name last name email and password so instead of login we are going to have create account and we don't need the forgot username and password for registration so I removed this and if I save I can see my registration forms okay let's finish registration.ts so I openregister.component.ts then we are going to implement an image so I say Implement on init I put my cursor on the control dot so I Implement interface I'm in it then I'm going to have a Constructor and inside my Constructor I'm going to have private account series of type account service so I'm injecting my account service inside registration.component.ts and then I put the open and close very price and then I'm going to make a user form Builder so I say fire red or builder of type form Builder we are going to make a use of reactive forms in order to find our form and submit R4 so the way I do I'm going to have a register form at the top of type form group so we cannot see that because we need to import inside the shared module so I open my shared module and inside the Imports I'm going to import reactive form modules so it's reactive forms module and I need to import it from at angular.com we need to import reactive phones from angular form so I fixed the error and we are going to export reactive forms asserts since we are going to make a use of this inside shared module and we are importing shared module inside our icon module so I'm missing that I need to import shared module over here if I import shared module then I'm going to be able access to any Imports that we currently have inside the exports so we can make a use of router module and reactive forms inside my account module and if I go back to my register.component.ts and now I can update my import before I couldn't update because I had to import reactive forms and then it's new form group and we pass empty object as an initial value then I'm going to have a property called submitted and I make it false by default and error messages and this is the array of string and I initialize it to empty array so this contains any error messages that returns from the API and here we have initial allies for and inside here we have this dot register for is this dot form Builder dot group so for the properties we are going to have first name and this we initialize to empty string and for the validators we have validators that's required and we need to bring validators from an angular forms and the second validators is validators dot mean lens 3. and validators.max length 15. so the same validators that we are doing inside our details so if I open my details account and register detail so we have minimum of three characters and maximum of 15 characters and this is required so three validators for first name and we are assigning three validators for first name and I put a comma and I paste three more times so we're going to have the second one as the last name the same validators and for email we are going to have another validators instead of mean lens and Max lens so I remove these two and instead we are going to have make a use of regular expression so the same way as we have over here so I copied this regular expression from this all the way to the dollar sign I'm going to copy that and then inside here I'm going to have validators dot pattern so that's how we can assign regular expression validator inside my email property inside register 4. then the last one is password and for the password we have mean length of six characters and Max lengths of 15. and inside my NG on init I need to call my initialize form so I save this that initialize form in order to call this method and initializing my four so after I do this I can come back to register.component.html and find my form into the form that we have created over here so the way I do I put a 12 bracket and I say form group because register four the same as we have name it over here and then for the NG submit we call register and auto complete off so for the NG submit if the form is submitted by this button then this will call this function we don't have this function yet that's why we see red so I copy that and inside my register.ts I'm going to create that function then for autocomplete if we don't do autocomplete up then it automatically completes the form so we don't want that that's why we say autocomplete off and then for each input we are going to bind into our properties inside the form so for the first name and this is for the first name so we say form control name equals first name and when we do this then this input has been connected to the first name inside register four and I'm going to do the same for all of other so I copy this and inside the last name I'm going to paste and as well as email and for the password so I just make the modification and I open my register.component.ts and then I can say console.log twist.registerform.value and I'm going to save everything so let's take a look at what we have so far so if I create a account and if I open my console if I put a first name last name an email address and one four five six for the password then if I create if I open my console right then I can see my Register phone values so email first name last name and password so I close this then I head back to my register method so inside here we are going to say this dot submitted is true so we know that the form has been submitted or the create button has been clicked and then we say this that error messages is to initialize empty error messages so why I'm doing this because I would like to print out any error messages that we see from their API and after this I'm going to call my account service but we need to create the register method inside my account service so I open my account service and inside my Constructor I need to inject HTTP client so I say private HTTP colon of type HTTP client and we don't see that here because we need to import HTTP client module inside our shared module so I open my shared module and inside Imports I'm going to have HTTP client module and if I control dot I cannot see any fix so because I think I have a capital l and if I try one more time everyone see that so I'm going to manually import that so I copied this and in here I have import HTTP client module from at angular forward slash comma forward slash HTTP and we need to export that as well so if I do this then I can see add import from at angular common HTTP so we are using HTTP client in order to make a API call and then in here I'm going to have register method so register and this takes a model of register and we need to create our models as well and then this has return this dot HTTP dot get dot post and we need to provide the URL and the model so this is the app URL and I put comma and then we have the model so first of all I need to create my register model so I'm going to do by navigating to shared folder and then I right click and I create a new folder and I name it as models and inside here I'm going to have my register that TS so I right click and I click on new file and I name it as register dot yes and inside here we have export interface register and we have first name of type string then I copy three more time last name email and password so the same model as we have inside register.dto then I head back to my account.service and I'm I can make a import for my register model so add import from uh it goes to the path of this model that I have created inside shared folder we are going to have our app URL inside environment.ts so inside angular 15 we don't have environment.ts anymore but we can generate that very easily so if I navigate to the angular side there's a command of NG generate environment so I copy this and inside my tab inside client I'm going to paste the command and hit enter Then This has created my environment.ts and environment.development.ts and it's as updated my angular.json so we can make a use of that so this new folder has been created for me so I open environment.development.ts and inside here we are going to have the following properties so the first one is production and we say false so we defining that the production version is false and then we have app URL and this is the URL of my API so I can copy that from my API project and inside properties launch settings and this is the app URL of my API so I copy this and then I paste it over here and then since we are here we are going to have another constant variable that is user key and I name it as identity app user and we have to copy all these and paste it inside environment.ts as file so I open that and inside here for the production we have two and for the app URL we don't have but for the user key we have the same key so I'm going to explain user key later on in this section but since we are here I have put it over here then I head back to account.service and I can make a use of that app URL so my app URL I'm going to you make a use of backtick and I remove the existing and I have dollar sign and I open and close vertebrates environment make sure to bring from environment dot development then app URL then we have forward slash API then account then register and we are going to pass the model as well so this is fixed and we can head back to register.component.ts and instead of console logging the value I'm going to call the API so I save this dot account service.register and I'm going to pass my Register phone so I say this.registerform dot value and then we are going to subscribe for the subscription I open and close parenthesis and inside my parenthesis I have carry brace and we have next option and this is response and we have error option for the error I'm going to cancel that log my error and for the response I'm going to cancel like my response as well so I remove this console.like register that value you might wonder a register function inside the account service if I go to definition is expecting a model of type register that we just created earlier but we are passing the register form so that's the same thing because in my register form we have the same properties as we have inside the register model so it has first name last name email and password and inside my register.ts we have the exact same properties it takes exact same spelling that's why we can't do that so if I do this.register.value this is going to copy all the values that already in inside my register form and place it inside the register interface basically inside this model and then we are going to pass that model in to the API and since this returns an observable so if I hover over I can see this is observable of object and for every Observer we need to subscribe to The Observer so if I open my register.ts that's why we are subscribing otherwise it doesn't complete the action so we always need to subscribe to any Observer and let's try this so if I save and I open my angular and I have AAA ebb and AA yahoo.com and one two three four five six and I open my console so I need to run my API project and I put a breakpoint over here so if I create I can see another error message and this is cross origin request block so we need to add course inside our API so the way I do I open my API project and inside my program.ts thus underneath of the services after builder.services ad authentication I have Builder dot Services dot add course and inside my pipeline just above everything I'm going to have so I enter after I configure the HTTP request Pipeline and just above all the pipelines I'm going to have app dot use course and we have opt then inside out we have up.allow any headers that allow any method that allow credentials start with Origins and then we have to pass the URL of my client application and the URL of my client application is localhost column 4200 so I copy this then I can do paste it over here or instead I can copy this URL inside my app setting.development and bring that from my appselling.development.json so I rather do that because we are going to need this client URL in multiple places so instead of the smart defined in all other places I would like to only modify in one place so I open my app settings at development and then inside jwlt I'm going to have another property and I name it as client URL and icon I put a column and then inside quotation I paste the URL of my client and then I head back to program.cs and instead of hard coding that I'm going to have Builder dot configuration and then and inside bracket we are going to have JWT colon client URL and I some put a semicolon at the required places so with this we are going to bring the client URL from JWT section inside our app settings and if I restart my API project and I'm going to do the same action one more time so my API project has been restarted and if I create then we are going to get caught inside this breakpoint and if I hover over then I can see all the values that has been passed and if I continue so this is the result that we have received okay now let's handle our validation for our forms so I open my register.component.html and in here we are going to do client-side validation and for the client-side validation that we have assigned over here so we have a date Thursday required and patterns so we are going to implement that inside our HTML so first of all I need to assign his invalid class which is a bootstrap class two if the four and four this input is invalid or basically has errors so the way I do I after here I put new line and inside the bracket I have class dot is invalid and then we have a condition and for the condition is if the form is submitted and I put double on percent and then register for then dot get and we have first name dot errors and this says object is possibly not so we put a question mark we get rid of the arrow so basically we are injecting is invalid class to the class if the form is submitted and we have that property over here submitted and it is initially false but if the the form is submit so we are going to cut register method and inside register method we are setting this submitter to true so if the form is submitted that's the first condition and if this first name inside register form has errors and what are the errors we have a specified requireds and minus and Max lengths if any errors then we are assigning is invalid class into our input class so basically we are going to have for example is invalid over here if these two conditions are true if I remove this and then after my label we are going to have 10 plus 6 danger and we have asterisk NG if and submitted and I put double dampers on registerform dot get first name question mark dot has error and required then we are going to have this following text message and we say first name is required and then I head back to register that component and inside here we are going to say if this dot register 4 dot is valid or valid if the form is valid then pass it with the API card otherwise don't press it so I don't want to just call my API at the moment so if I save everything and I open my browser and if I click submit then I can see first name is required why because we have specified over here so by this line of code and as well as this line of code and this is going to check if the form is submitted and this has the required validation and we have another validation for first name which is min lens and Max lens so I can do over here so I copy my span and just below that I'm going to have so after submitted and double Ampersand I it's a new line and then for here we have as error of mean lens or as error of Max lens then for the message I'm going to copy exactly the same message as I have over here first name must be at least and maximum so I'll copy this and then I head back here and first I must be at least for the first one is three and maximum is fixed 15. so if I save and I would like to test if I hit I can see first time is required but as soon as I put a character I can see the second option first name must be at least three and maximum 15 characters so I'm going to do the same for the last name so I copied these two done and I put it underneath and instead of first time we are going to have last name so I copy last name and for the get I'm going to have last name and I have Mr spell here so this is max length instead of mas and I paste last name over here as well and I make the modification for the message and we have last name and we have to apply the is invalid class to this input as well so I copy this just after here I hit a new line and I paste that in here and instead of first name we have last name so this is exactly matching or I can say these characters or spelling is exactly matching my last name we have lowercase L with capital case n and we have the same as over here and I'm going to do the same for my email address so I copy the is invalid and I paste it over here we have email and for this pan we are going to have the required so I copy that and I paste it so I copy this and I paste it just below a label and we have for the email and we can say email is required and we are going to have another additional validation for email which is validating the email address so I copy this spam one more time and here instead of required we have pattern so if the pattern doesn't match then we can say invalid email address and for the password we do just before testing we do the password as well so I copy the is invalid and I paste it over here and I have for the get you have the password and we are going to have the required as well so I copy this and I paste it down here and we have the get for password and we can say password is required and we also have the mean lens and Max lens for the password so I copy this one and I paste it down here and I just format my page then we are going to have registerform.getpassword win lens and password Max lens so if mean lens or Max lens is not satisfactory to the register form then display this message and this should be password must be at least 3 and maximum 15. but I believe for the password we have six characters so if I head back to register that component yeah we have six characters so I'm going to save everything and try to submit my phone if I hit submit I can see all the required feed and as soon as I put some characters I can see 3 and maximum if I go beyond 15 characters then I can see the same message over here and for the email I'm going to put some invalid email address and as soon as I put valid email address then this has gone and for the password we have to put six characters and if I satisfy everything then we are going to be fine and the error to submitter for this section we are going to implement the API validation error messages that we are going to receive by submitting therefore so first of all I'm going to comment out this line because I would like to see what type of error messages that we are going to receive so if I save everything and then I head back to my browser and I'm this time I'm going to open my console and if I submit so this is their error message that we receive these are the client-side validation but we would like to have the API site validation as well so for the API validation we have object and inside the object we have error and then inside there we have errors and inside the errors we see bunch of error messages so first for example the first name field is required the name must be 3 and 15 characters and so on so we would like to have those error messages lined up over uh just create account button so in order to do that first of our we need to flatten our API errors into the object and we can achieve that by modifying our services so I open my visual studio and I open my program.cs then inside my services after builder.services.ad course I'm going to have another service so first of all I need to set my API application then we have builder.services.configure and then we have API Behavior options then we have options then inside options we have invalid response Factory is action context and then we have War errors is actioncontacts dot model state DOT where X goes to x x dot value dot errors dot count greater than zero if we have multiple errors then let's select many and then we have X goes to x dot x value dot errors and then we are going to select X goes to x dot error message dot to array then from here I'm going to have War to return is I'm going to make a use of anonymous object so I just put new and then inside new we have errors is error and then I'm going to return new add request object result and I pass my to return and I put the following semicolons so if I run my API and we are going to see different error message over browser so if I submit so this is the previous error message and if I submit then we can see inside error and errors then we have flattened array of error messages so rather than having that inside a bunch of objects we have in a single array of strings and this line of code is doing that so basically it's going to the model State and if it has found some errors and the count is greater than zero then that means we have some errors then we are going to select many of those errors and inside those select many we are going to only select the error message so if I open my browser and for the error message these are all the error messages that we have for example the email field is required and for those error messages we are going to convert it to array and then inside my errors we have a string array of errors and then we are making an anonymous object that's why we don't have the type so it's only new and inside carry brace we are going to have our property called errors and these errors is going to be populated by errors and then we are returning our object that's how we can see Latin error messages inside here so we can make a use of that so I head back to my component register.component.ts then inside here I'm going to say if error that error that errors if we have error.error that errors that's that's basically this one error so the first one is error and the second one is error and the terrorist errors if we have that then we save this dot error messages is error dot error dot errors and I'm going to remove my console lock so I'm going to save and I try to submit my form so we need to pass those error messages inside our HTML to the child component of validation messages that we created earlier so the way we do I open my register.component.ts and after my last div of the form floating so we are going to have div Dot form floating and then I have a condition so asterisk NG if error messages dot length is greater than zero if we have some errors then we have app validation messages so we don't see that because we need to export that component inside our shared module so if I open my shared module then we have validation messages component but we don't have that inside the exports so in order to make a use of that we need to export it inside here as well if I'm done with this then I can see validation messages coming over here and this validation messages is expected to receive some input string and if I open my validation.validation Dash messages we are going to have at input then I need to import input from at angular core and error messages of type string array or undefined then I open my validation messages.component.html so I removed this and instead we have UL dot text danger then we have NG if error messages so if this error messages is not defined then we have a for Loop inside Li so I I put Li and then I have asteric ng4 and let error of error messages so I copy error messages and then I open a new line and then inside double carry brace we have Arrow so we are looping through error messages and we are going to display that and our validation messages is going to receive that error messages by input so we can pass error messages to the Chart components so if I open my register.component.html then we can pass that by using the bracket so I can say error messages e-course error messages so this error message is inside bracket is referring to the error messages inside the child component so if I go to definition this is coming over here if I head back and this error message is is inside our register.component.ts so with all this if I save then we are going to expect to see some messages over here so I close my console log and if I hit a create account then these are all the messages that we receive from the API and these are all the messages that we receive from the client so if I execute my SQL servers then I can see AAA yahoo.com has been registered so I'm going to try registering another user with exact email address so I copy this because inside my API project and inside register we are going to check if the email exists if the email exists then we are returning some bad requests so I put back the console log I want to show you another type of error so I put this this back and then I'm going to save and this time I'm going to register with the same username that we already have register because I would like to see this error message I head back to my browser and I put some random character for the first time and last name but for the email we are going to use the same email address that we already have registered once before so I put a password and I open my console log and if I create account then I continue then we have different error messages and this one and the error is not an object it's just a simple text message so we need to handle that as well so in order to do this after this ifs statement we have else and then we can push that error inside our error messages the way I do is this that error messages dot push error dot error why we are using is that error messages.push because because this is a string characters it is not an array of object so before it used to be an array of multiple strings but this time it's only just a single string so that's why we are just pushing in this case our bad request for this scenario is being handled by this line of code and if I save and I'm going to do register with the same email address and if I create account I continue then I can see the error message that I saw from my bad request and I'm going to remove my console lock and since we are they handle the error messages so we are going to put back in the if condition if the form is valid then bother calling the API and I save everything in this section we are going to handle the success message that we receive from the API so if I try to register with a boot username for the email I'm going to use something that I haven't registered yet then if I hit create account so I'm going to remove my breakpoint and if I continue then I can see object object so why do I see that because this is going to return a string but we're not expecting to receive a string so we can make a modification to our API and instead of returning a simple string so I cut this and then instead we are going to return new Json result then we have new Anonymous object once again and we can have title is account created and for the message we can have your account has been created so I remove the extra characters over here and I close the parenthesis so instead of just returning a simple string we are returning a Json result and this is an and this returns an object so if I restart my API application I try to register with a new user so this time I'm going to use Joe and if I try to create account then I can and see a result and this is the result that we just received and inside the value we have message and we have Tyler so exactly the same as we specified over here so title and message so we would like to show this message in a model or in a notification so the way we do we can make a use of ngx bootstrap so if I type in GX bootstrap and then if I go to the website and get it started and for the components we can make a use of models so if I open this and these are the models that we can make a use of or notification or pop-up so I'm going to make a use of this one so we need to create a component for this model and I'm going to create that inside my shared folder so inside my shared folders and inside the components I'm going to create another folder and I name it as models so I just think minimize my errors and inside components we have errors and we have models and inside my models I'm going to create that component so I need to navigate to that and in here we have NG GC notification and this skip test so we have notification model and this is going to be used for both success and error messages you can think of toaster notification like this so This notification is going to be a pop-up message that the user will see and that is going to have the following properties is success Boolean and initially it is true then we have title of type string and we set it to empty string a message and string and we have empty string as well then we are going to have a Constructor so I say Constructor and public BS model ref half type BS model ref we don't see that over here because we need to import that insert our shared module so if I go back to the ngx bootstrap and inside apis I can see we need to import model module in inside our modules so I copy this and I head back to my shared module then I paste it over here and then I copy my model module and for the Imports I'm going to have that over here and for the model module we are going to have four roots if I take a look we need to have model module dot for root then if I open my notification dot component.ts then I can import that from here and then I open my notification Dot component.html and I removed the existing code and instead I'm going to use the example that I just showed you so this is the second one with the components so I'm going to copy this line of code from the template and then I paste it over here and I try to reformat so inside my header I'm going to have NG class and I'm going to assign BG success if is success and assign BG danger if it is not its success so since we are having is success as a Boolean if this is 2 then apply VG success class otherwise apply PG danger so the header becomes green or red and then I remove this UL tag instead we are going to have message and then I have okay over here so we don't have that close button so we are receiving these properties from inside our components and we are and then we can have another series called shared service and that populates or triggers this model for us so the way I do inside my terminal I head back to to shared folder so I have to go two more times up and then inside my shirt I'm going to have NG GS shirt and I skip test so my shared service has been created inside my third folder then inside here we are going to have private model service of type BS model service so I need to import that from ngx bootstrap forward slash model then we are going to have a method called show notification and we are going to receive three arguments the first one is success of type Boolean the second one is title of type stream and the third one is message of type string so I have a extra forward slash then inside here we have const initial state of model options so we need to bring that and is very brace initial State balance and we pass those properties to the model and then we have this BS model left so we need to have BS model ref as a property so I say BS model ref FPS model ref and this has to be initialized and I need to bring my BS model ref and this has to be initialized so in order to get it after I can say this can be undefined so that's how we put question mark over here to get rid of the error message then I can say BS model ref is this dot model service dot show and we pass the notification component and we pass the initial state so all this code is coming from this example so we can have initial State and then we can pass those initials say to the component that we created so in our case is notification component and we have created this function inside our shared service because we can make a use of this function in any places inside our client application then I head back to my register.component and in here we can have this dot shared service so I need to bring shared service so I head back to the top and I can inject private shared service I've typed shared service then inside here we can say this dot shared service dot row notification the function that we created and this expecting three properties so the first one is true because this is a success message and then the second option is the title so I need to say that my response is of type any then I can say response dot value dot title and then I can say response dot value Dot message and then we can navigate back to the account logging so I can say this dot Raptor so I need to bring router so inside my Constructor I can have private router of type router and I need to bring my router and over here we can have this dot router.navigate by URL and just forward the user to the login page so you can say account login and if I remove my console log so let's try all this I'm Gonna Save everything and I open my browser and I'm going to register with a new user so I can see the notification that I just created account created your account has been created you can log in this is exactly the same message that we have over here okay I'm going to finish up this section with Computing login so login is going to be the same as register so we need to initialize the form so I copy this and inside my login.component.ts I'm going to have the method and then instead of register form we name it as login form and I head back to the register component and I'm going to copy the properties and I head back to login and I'm gonna paste them over here then I add all missing Imports then we are going to have the Constructor so I open register component and for the Constructor I copy this and I paste it over here we don't need the share service so I remove this then we need to have NG on in it so we have implements on init and we need to bring so I use add all missing Imports then we have to have entry on in it so inside my register component that yes I'm going to copy this and I head back to login. yes then I paste it over here and for the login form we have name as login form so I copy library form and instead of register form I just substitute with login for and inside our login we are going to have username and password so the form gets much simpler so we have username and the password if I remove this and last name and first name and for both of them we are going to have only the required attributes so I remove all the way this bracket and we have only one single validation which is required and I do the same for the password so I got this and I paste it with this then we are going to have a login method and again we cannot just borrow some code from register so inside my register method we are going to have this dot submitted is true then we can have if the login form is valid so I copy and paste then we can say login four is valid then go ahead and then hit register so we need to just rename it to login from account service and we don't have that login inside our account service so we need to create that so I open my account.series then just above here we have login and this takes a model of login and we need to create the interface as well so I'm going to create my interface inside share and models then I hit right click and hit new file and I name it as login.ts then inside here we have export interface logging and this has username of string so I make a capital of N and then we have passport of string then I head back to account.service and I can bring that interface and this time we have return this Dot http.post and we use backtick so I borrow this code and I put it over here and set up register we are going to hit the login endpoint and we pass the model and I head back to my login.component.us then we should pass the login for and for the next we are going to handle that in the next section but for the errors we are going to have the same code AS register now we need to bind our form into login form the way we do we open login.component.html then inside here we have formview and we name it as login 4 and we have NG submit is the login so we are going to hit the login method after the form is submitted and autocomplete as off and then I open my register to borrow some code so for the first one is form control name I copy this and inside my input for the email I'm going to paste it over here and the form control name is username and this is going to take the username of the user account and this is going to take a username of the user group inside the placeholder we can say username and for the or this is username and we can have the same message so I'll copy this and then I can follow another code from register component which is class is invalid if I copy this and if I go back here then I can paste it over here instead of register form we have login form and for the get we have username for the span of fixed danger so we can borrow this quote I copy this then inside my login form I'm going to paste it after the label and we are going to check if the form is submitted and it's login for and the Gate of username as error off required and if so then we can say username is required and we can do the same for the password so I copy this I paste it over here and for the form control name you have to do for the password modification and we are binding the this into our password property inside login for this spam we have the required as well so I up in this and it's danger if the form is submitted and logging form and password as the error app required and say password is required and once again I head back to register component and for the validation that we receive from the API I'll copy this on floating GIF error messages and then after the last form floating I'm going to paste it over here just above my login button I believe this should be sufficient so if I save everything if I open my login form so I'm I try to log in with a bad username and password so I execute so for example I'm going to copy this and for error and for the username I paste it over here and this is a bad username or password and this is the error message that we received from the API invalid username or password I removed then I can see the client-side validation and if I comment out this if a safe man in order to be able to see the API site validation and I'm going to save and I submit my form without anything so these are the validation that we received from the API site so over here we can see username field is required because this is the default message that API controller is going to place so we can make a modification if I open my visual studio and inside my login detail then we can have parenthesis and error message then we can say username is required if I save start my API application and if I try to log in once again you can see username is required so that was the end of this session and in the next section we are going to under the login functionality and storing and purchasing the login to our local storage so I commit my changes so I have my API application and inside git changes I'm going to type 0 3 comma client project setup fit registration I commit all my changes and I push to GitHub in this video we are going to handle purchasing the user and storing the user detail inside the user's browser local storage so I open my visual studio and inside my account service I'm going to have a private helper method so I I private user and this set user is taking user model of type user so we need to create user.ts so I open my shared and models inside my mothers I'm going to create a new file and I name it as user.ts and this user.ts is going to have exactly the same properties as we have inside user dto in our API so we're gonna have first name last name and JWT so I type export interface user and then we have first name last name and JWT then I moved back to my account service and I'm going to import my user model then we are going to have local storage that set item in order to store our user inside local research and this set item is taking a key and value for the key we are going to have environment dot user key that's what we created earlier so if I open my environment and this is the user key identity app user and for the value we are going to have Json the stringify and we convert our user into string by using json.string file and then we need to store this inside our replace object so just above here I'm going to have a private user source is new replace object of type user or not and we set the size only with one so only one user can be stored into user source so what is a replay subject replace subject has an internal buffer that will store a specified number of values that it has observed so so you can think of this as an observable and we can subscribe to this and then we are going to have user dollar is this that user source just as observable so user dollar contains the user Source value and it will contain this as an observable so we can subscribe to user dollar anytime inside this application and we can get the user out of that so that's why we have put dollar sign by convention because we are telling that this is an observable so you can think of that user source is the property but the kind of observable property and we can assign a user inside that or remove the user from the and this property has the index of only one value and this property is an array of Replay subjects with index of one value which means the size of this user source is only one and that one is either none or user object and user dollar is referring to that user source as an observable so we can get the value of user Source by subscribing to user dot that's why user dollar is update and we don't have private before because we wanna access to user Source inside our entire application by this user data but user source is only visible to account service that's why we have added private before that then I head down to my private Health per method then we're going to have this that user source dot next and we pass the user basically we are storing the user inside a local storage in one place and also inside our angular application inside this third user Source why do we store into local search because whenever the user is trying to refresh the page that local storage will contain our user object inside the local storage but why do we install it inside our angular because we want to tell if this user has some value then that means the user is logged in so things gets better makes sense as we complete this section and inside my login before I return I'm going to use a pipe and map function because I would like to do something with my response before returning to the whatever is calling so I use pipe and then I use map from rxjs and then inside map we are receiving user of type user and then I the error function and I am going to check if user is not now then this that set user will pass a user to our private helper method so this is complaining because we need to specify the return type of our API post function so inside here we have returned this.http.host but we can specify what kind of type we are expecting to receive from this function or basically from this API call so we can specify by we can specify inside our angle brackets and we can tell that we are expecting to receive a model of type user and the arrow goes away so a little more explanation for here so we are going to return an observable but before returning the observable we are trying to do something with the value that we receive from the API that's why we have used from type and map and then inside my login Dot component.ts I'm going to cancel a log my response I put back in the if condition for the validated form so we make sure that only validator form that gets passed and I try to reformat then I save everything I'm gonna check my database so I'm going to try to log in with this username so I copied this and I head back to my browser and I open my console log as well we receive undefined from our console log and where was that the reason was because we didn't return our user from inside this map function so if we try to return the user and since we're not returning at all the phases so I need to return none here so if I try this and I save my account.service and if I try to do one more time I'm going to receive the user because we have returned the user inside our map function and if we don't try to return anything then we're not going to receive that inside whoever is subscribing to that function so in our login.component.cs we are trying to subscribe and inside the response we're expecting to have some response but if we don't return from inside map then we're not going to receive the PVP only accessing to that user object inside this map function that's why the editors are undefined so we try to use from python map anytime that we want to do something before returning to the whoever is subscribing to so in our case we're not interested to return our user or return not we are only interested to be subscribed so that's why we're not using that because if we don't want to do anything inside our next object inside our login.component.ts we want to do our actions inside only this function inside our account.service so that's why I just removed those return values and after this we can access user object inside our nav bar and we can determine if the user has logged in or not so the goal of this section is to display create I can unlock it if the user has not logged in and remove play if the user has not logged in but display play and log out whenever the user is logged in so I open my nap or DOT component.ts first of all I need to inject our account service so I'm going to have Constructor public account service of type account service and then we can access to that user donor inside our navbar.component Edition and we are we can subscribe to that inside here directly but before trying to show these steps I would like to show you how to subscribe to user dollar so at this stage we know that we have the user dollar especially when we are sitting there you this that set user so I'm going to go to this definition and over here after we have set the user source so we can subscribe to user dollar and the way we do is this the user dollar dot subscribe and then we are going to have the next value and response and I'm going to console the like the response in order to show you how to subscribe to user dollar so if I try this and I save everything and I'm going to remove this console log from my login.component that yes as well because I don't want to mix this with another console like that we already have so they have commented out this console log and inside account service we have added this this user dollar inside our set user and if I try to log in then this is the response that we received from this console so this is how we can access to this dot user Source by subscribing to user dollar and we're trying to do the same inside our neighbor.component.html and we try to achieve the same thing insert our number.component.html how do we do that first of all we need to inject the account Service as a public and then inside our network.component we want to hide the create account and login button if the user has logged in so I'm going to make a use of NGE if and then inside parenthesis I'm going to have account service dot user daughter and I use pipe and I use async and then if this is not then try to display this UL tag for me as soon as I say let's see what happens so at the first time we don't have the user object so I'm going to remove my console log I'm going to log in one more time as soon as I log in then we're going to have a user object then we're going to have that user inside our user source so that login button has gone because we are trying to check if the user donor is not if it is not then display this URL tag for me but since we have logged in and we have populated that user Source by this line of code and we're trying to subscribe to user dollar uh the same way that we have done over here for the demo we're trying to subscribe to that and we're trying to retrieve the value from that so it's going to have some values that's why this is not become not and if this is not known then it doesn't show this based on this if condition so I try to demo this I'll do how we can achieve our user by subscribing to user data and this line of code for subscribing to the user dollar is exactly done but this line of code insert our number dot component.ship to insert our HTML we use from this but inside any TS file we use from this type of code so I'm going to remove this from my set user because we are not using that and it was for demo purpose and then I head back to navbar.component.html and then I'm going to add another div tag so just below my URL I'm going to have d Dot and then inside here we are going to check if the user dollar has some value so the way we do I copy this and I paste it down here and instead of equals to no we try to check if the user dollar has some value by this type of if condition and then we can receive the response type by storing into a custom variable the way we do by typing as user and then we're going to have a tag Dot and then I'm going to remove the href and instead we are going to use a style and then I have text decoration as none and cursor pointer and inside my a tag I'm going to have a high and I have a span of class H3 text warning and I'm going to have user DOT first name and I'm going to use a pipe as title case so if I try to reformat and then I'm going to bring this down and underneath of this we are going to have another a of class ptn BTN secondary and MS2 to have a margin start of two and then we have a click and log out and we name it as log out so just underneath of URL we have another D and in this Steve we are trying to do exactly the opposite of this one so if the user has logged in we try to display these two attacks and one of them is hi the first name whoever the first name is and then we're going to have another button for the logout so whenever the user would like to log out from the application and we have to create this method inside our number.component.ts so I'm going to create that over here so the error has gone and let's try our application so I save everything and I try to log in this time I'm going to blog in with something that has some proper name so I try to log in with JSP I copy this into my clipboard and then I paste it over here and I try to put the correct password and as soon as I log it I can see I John and log out but if I refresh my page then we have lost our user so we're going to deal with a refreshing page in the next video in this video I'm going to solve the issue that we are having at the moment whenever we refresh the page so for now we have saved the user object inside local storage so if I try to open my local storage from the browser so I navigate to storage and inside local storage inside this I have identity app user and this is exactly the key that we have specified inside our environment.ts identity app user and this has a string of value so whenever the user is trying to refresh the page the local research Remains the Same so we can access through this local storage inside our angular application and if this local storage does exist then we can populate our user Source based on whatever we are receiving or retrieving from the local search so first of all we need to get the JWT from the local storage so just above set user we're going to have get JWT and inside here we have const key and is local storage dot get item environment Dot user key So based on this key if key is not now then we have Advanced user F-Type user is Json dot parse key so we are trying to convert the string of values into an object of type user and install it into user then we can return user.jwt and for the else we can return now so over here we try to stringify the user but over here we try to do the opposite from the string we try to get the object so that's exactly the reverse of this functionality and whenever the angular application gets started the only the very first thing that you can think of as a main function if you're familiar with other programming languages so is the inside app Dot component.ts and over here we try to do increments on any and I fix the issue by implementing the interface and over my NG on in it I try to call this dot refresh user and we need to create this function just below here so we have a private refresh user and then we're going to get the JWT so I say cons JWT from this dot account service so I need to bring my account service so just above here I'm going to have a Constructor and inject my account service I said private account service of type account service and I put the curry brushes and then I say this dot account service dot get JWT and if JWT is not known then try to call another function from account service and I need to go back to my account service and I create that function so just above my login I'm going to have a refresh user and this is expecting a JWT as stream or not and over here we check if JWT is null then just empty out the user source so we say this dot user source dot next not so basically we're setting not into the only element that is available into user source and then return an observable off so we need to bring off from rxjs so I click that undefined if the JWT is not null then try to do the following so we say let headers is new HTTP headers so we need to bring HTTP headers from at angular common HTTP and then we say headers is headers dot set authorization comma Bearer and we need to provide a space plus JWT and then we say return this.http.get and we expect to receive user as a return type that's what we provided inside angle bracket and then we try to call our API endpoint and we try to use from Patty then the other Sun environment that API URL forward slash API account refresh user token and that's exactly the same as we have specified over here so inside my API project account controller and we have one endpoint and that is authorize and that the name is refresh user token and since it is authorized it is expected to receive a jwc token that's why we have provided the JWT inside authorization header the bearer and with very important space so if we don't put this space then this doesn't work and then after here we have the headers and we are going to make a use of pipe and map function once again and then inside another parenthesis we have user response of type user and we have a callback function if user then this dot set user and we pass the user so this refresh this user is trying to call the API endpoint of refresh user token and it tries to pass the JWT inside the authorization header and from the response value which is the user of type user then it tries to set the user that's exactly the same thing as we did for logging so we used from pipe and map and we have called this dot set user and this that set user is trying to set the user into the local storage and also populate the user source so with all this then I head back to app.component.ts and if we have the JWT then we save this dot account service dot refresh user and we pass the JWT and we try to subscribe and then for the next since we're not returning anything so I put underscore and then we have just empty curl brace but for the error if we have received some error from the API then I'm going to call another method inside account service which is logout so this is going to build this dot Account service.log app and we don't have that method at the moment so I copy log out into my clipboard and then inside the account service just below logging we have another function called logout and then inside logout we have local storage you have to remove item environment dot user key and then we are trying to set the user source to null so we save this user Source dot next not and then we have this dot router and we need to bring the router inside our Constructor so I'm going to have private router type route and just inside my logout we are going to have insta router dot navigate by URL and navigate the user to the home page or the default page basically and then if I head back to my app.component then the error has gone and I'm going to remove this title inside my app.component because we are not using that and just to finish up this video then inside else we have this that account service that refresh user and we pass now to the refresh user method inside account service and we try to subscribe then I open now for that component.ts and inside my logout I'm going to call this.acan service.log app and then I save everything and I try to try my application so I open my browser and I log in with a proper user then I can see hi John over here and as soon as I refresh then hijung will persist because we have tried to retrieve the JWT from local research and then try to call the refresh user endpoint over here and this endpoint is going to call Api account refresh user token and it pass the headers with the authorization barrier to our API endpoint and over here we are trying to return a user detail from here as well which contains a new JWT and after that we are trying to set the user one more time the same as we have tried inside logic so that's how we have persisted the user even though the user is trying to refresh the browser and if I click on logout then I'm going to remove my local storage and as well as I empty out my user Source over my account service so I'm going going to set not into user source and that user dollar will not contain anything and will contains now so inside my nav bar then this condition won't work because the user dollar is not by this I and then we are going to see create account and log it so I'm going to log in one more time and this time I would like to navigate the user back to their home page if they have logged in so right now it stays in inside the logging component but I would like to navigate back to the home compo so the way I do I open my login.component.ts and inside here instead of this comment I'm going to have this the router dot navigate by URL and I pass to the home component and also I would like to not show the login page if the user has already logged it so the way I do inside my Constructor I press enter and inside here I'm going to have tested account service dot user dollar dot pi and take so I bring take from rxjs and I'm taking the first element which is only available inside our user source and then I try to subscribe then I put Curry brace and inside next I'm going to have my user of type user so I need to bring user model and the user is either of type user or not and then I'm going to have an arrow function and a curly brace and then I say if user so if the user is not now then we start router dot navigate by URL to the home page as well so I'm going to save everything and let's see so my user has already logged in so I cannot navigate to login so even though if I try to navigate to login page redirects me back to the home page and if I try to log out then I can now see login page over here in this video I'm going to create another controller and the name of the controller is play and that is only available for only authorized users so I sub my API application and I create a new controller and I select API and I select empty and then I name it as play and just above here I'm going to set authorize so only authorized user is available to access this controller then I'm going to have the endpoint HTTP get off get layers and we have public eye action result and players and then we are returning OK new Json results new message is only authorized users can real players so I need to remove objects so we don't have that so we have only return okay new Json reserve and the message is only authorized user can build players and this controller is for testing purpose in order to call this controller with our JWT token then I restart my API application and then I open my visual studio code and then I'm going to create another series inside my play component so I open my terminal Tab and I navigate to my play then I'm going to have a service called play and I skip this and I'll open my play dot service then I'm going to inject private HTTP of type HTTP client then I'm going to add the following method get players and inside here we return this Dot http.get and then I use tactic and then dollar curabase environment so I bring from environmental development then dot app URL then I'm going to have forward slash API play forward slash get players and I put a semicolon and then I open my play.component.ts inside here I'm going to implement on init and I fix the error by implement the interface and I'm going to inject my Play service inside Constructor so I have Constructor and inside here I am going to have private Play service type Play service and inside NG on in it I'm going to have list.playservice.getplayers [Music] then subscribe and I'm going to have next inside next we have a response of type any then I'm going to have this third message is response dot value Dot message and I put a comma and for the error I have error and I just cancel log there so I need to create a message so just above here I'm going to have message of type string or undefined and then inside my play component.html I'm going to have a P tag and then I'm going to have NG if so I put asterisk in gef message if the message is not empty then just display the message and if I try to save then I head back to my parameter and I try to log it once again so I open my console log and if I click on play then I'm going to have unauthorized because we're not passing our JWT along with our headers so we need to pass our JWT along with our headers so if I open my Postman and just inside the identity app I'm going to have another folder and I name it as play and inside play I'm going to have a request it three years inside the URL I'm going to have URL format slash API forward slash pay get players so if I send then I see unauthorized because we need to pass the token along with our authorization better so the way we do we need to login with one of the proper user and when I log in then I'm going to save my token inside JWT so inside my get players inside authorization if I select better token and then I need to provide my JWT and if I save and this time if I send then I can see only authorized user can deal players so I fix this typo from here so I'm going to replicate this scenario inside our angular I open my visual studio code and inside my shared folder I'm going to have a folder called cards so I click new folder and I name it as car and then I navigate to my cards so I go back and I go to share and I go to cards and then I'm going to create a guard PS5 so I say ngg R and I name it as authorization and I skip tests and from here I have can activate and I press enter so this has created my authorization card inside my guards folder so I open that and inside here we no longer need to implement can activate so I can remove this and then I'm going to have a Constructor and inside my Constructor I'm going to inject my account service I'll type account service and as well as I'm going to inject shared service for displaying a notification and then I'm going to inject route of type router then I open and close the current press and from here we are going to return a Observer of Boolean so we don't need this URL tree I remove this and then we can remove all this as well so we are only returning Observer of Boolean and inside my return I'm going to have this dot accountservice.user.part to access to the user dollar and we use from map as well so I need to bring map from rxjs and then inside map we have user of type user or not and then we have if user is not Norm then return true otherwise else return pause so in order to get rid of the error message just before returning false we have this dot shared service dot show notification and its success is first this time then we say restricted area and for the message we say leave immediate and then we have this dot Raptor dot navigate and then inside the bracket we have account forward slash login and so we try to navigate the user to like page and then we have query params column and return URL state DOT URL and we put the same color in order to return the URL to the login page and then I open my app drafting module and for the play we are going to use from can activate if the authorization card has been passed so I'm going to comment this out and instead we are going to have Cherry brace and then path is nothing then we have run cards resolver and this is always and then we have can activate and inside bracket we have authorization card the authorization card that we just created and then we have comma children and inside children we have I put Curry brace path and play and then component is play component and I put a comma over here so basically we're trying to make only authorized user be able to click on a component so if I save everything and if I open my browser right now we can click on play but as soon as I log out and if I click play I Can See restricted area leave immediately so that means we have not passed our guards and the guards is checking if the user has been populated if the user is populated then we can click then and we return true and if it returns true then we will be able to see the play component otherwise we are being navigated to account login and we are going to receive the return URL as well so in order to finish this tutorial I'm going to navigate to login.component.js then I'm going to have else then I'm going to access to the return URL that we have been passed over authorization card so in order to do that I'm going to inject activated routes so I put comma and then I say private activated type activated route and then inside else I'm going to have this dot activated route dot query prompts map let's subscribe then we have next and inside next we have prams and the primes of type NE then we have iframes is not null then we start returning URL is proms.get dot inside single port return URL and I put semicolon and I need to create return URL of type string so just above here I have return and of type string and return urine is up type string or not and I set it as not then inside my login I'm going to check if this dot return URL has some value then navigate the user to the return reorder so I say this dot router dot navigate by URL and navigate to the return URL otherwise so I say else navigate to the home page so if the rectangular is not null and has been passed by the authorization then navigate the user to the return URL so if I try to save everything and I open my browser so I refresh my client app so I click on home page and this time I click on play component but this it says a restricted area and this is containing my return URL so if I click OK and if I try to log in then I will be navigated to the play component because of that return URL but we still see the other unauthorization error message because we have an entire tweet passing the JWT along with our headers so we're going to do that in the next tutorial so in order to pass the JWT we need to create an Interceptor so I'm going to create a folder inside my share and I name it as interceptors and then I navigate to my interceptors then I'm going to create an intercept by using ngg Interceptor and I name it as JWT and I skip tests this has created a JWT Interceptor and I opened that and inside my Constructor I'm going to inject account service so I say private account service applied account service and just above return next dot Handler so I'm going to have this account service dot userdaughter dot type and then we take the first one first element and we need to bring take from rxjs and then we need to subscribe and inside next we are going to have a user and inside here we say if user is not known then then we try to clone from the coming request and add authorization header to that then we have request equals request dot clone and inside clear brace we have set headers then inside headers we have authorization and column then we have batik Bearer space dollar sign curve brace user dot JWT and I put the required semicolons so basically we are trying to inject error inside our authorization inside the headers along with every API request that we are trying to do if we have user populated so basically if the user is logged in so we try to add this barrier plus the JWT inside their authorization headers then I open my app dot module and inside providers I'm going to have a new line and then can replace provide an HTTP underscore interceptors comma use class and the class is JWT Interceptor and we have multi true so with this provider we are trying to make a use of our Interceptor and for each API request if we have the user populated or the user has been logging then we'll try to add the JWT inside our authorization header so I'm going to save everything and then I try to hit my play then at this time I can see only authorized users can view these players because we have set the JWT inside the headers so if I open the network and inside my get players if I open this and inside my request and inside headers if I scroll down I can see authorization better and the token has been applied to my API call so if I navigate to my home and if I come back to play then another request has been triggered and this API call is containing my authorization barrier and we can hit the player controller and get players endpoint over here because we are authorized open the register.component.ts and inside my Constructor I'm going to have this dot account service dot user dollar dot pi and then we take the first element and then we subscribe and inside the subscription inside next we have we have user of type user or not and we need to bring user and then we are going to have if user is not now then we start router dot navigate by URL and navigate to the home page so if I say and if I try to access to my register component then I will be navigated by two one component and in this section we have completed the user processor so I'm going to push my changes into guitar so I open my visual studio so I stop the application and inside my key changes I'm going to say I type section04 user Precision in angular and I commit my changes and I push to GitHub in this section we are going to implement email configuration and image sense setup and we are going to set up our email send Using mailchat first of all we need to create an account there so I navigate to mailjet.com and I click on get started then type your email address and password and click on sign up and we are going to choose a free plan then we fill up the forms and we click on next and complete order then you need to come back to your email and confirm your email address and activate your account then once your email is activated you can click on drop down and click on account settings from the accounts and things click on API Key Management from rest API and from here generate a secret key and you need to copy this API key and secret keys somewhere so I copy them in into my notepad plus plus and then open your visual studio and open app settings.json and after here put the comma and then we have main jet and copy and paste your API key and secured key there these are sensitive information so make sure not to push them into GitHub or if you are pushing to GitHub then you need to destroy those or you can use from user secrets and have your mailjet API key and Security in your secret key the way you can do is by right clicking it on API and click on manage user Secrets then in this case you are not pushing your secrets into GitHub and I'm going to destroy my secret key once I finish this section and the way you can do is by clicking on the Cognito icon and then you can click on reset key and you can type reset and reset your secret key so it depends on you whatever you're trying to do but make sure not to send your secret key into your GitHub or as he's destroyed the secret key that you have pushed to the guitar otherwise any other user can use from your secret and then just above mailjet we are going to have another section called email [Music] and from is the same email address that you have sign up for your main jet so I have used from Identity app 546 gmail.com then application name [Music] and I name it as identity app then confirmation email path and then we have reset password and these two are going to be used inside angular but since we're here we're going to type here or anyways and we need to put a comma over here so you need to section one is the email and one is a major and the mentioned has API and security and your email has from application name and confirmation email path and reset task and this is confirmed email paths oh make sure this is confirmed in your class and after that you need to install mailjet nougat package in your API project so right click on API and manage widget packages then search for mailjet and choose manager.api version 3. so I'm going to choose manager.apr and the latest version is version 3. then I'm going to save everything and a close nougat package and as well as app settings then open the services folder and create another class and we name it as inner service and inside your image service we have a Constructor and inside the constructive we are injecting our configuration in order to get access to the app settings then I initialize my config and we are going to have the following method and we have public async task of type Boolean send email async and this is receiving a image sent dto as a model and we need to create email send detail so inside my details folder inside my account I'm going to have another class and I name it as image send detail and inside here we have the property of stream 2 property of string subject and another property of stream body and I put my cursor in image send detail and I control that and then I select generate Constructor dot dot then I select ok so in this case we are going to have a Constructor to initialize our properties then I navigate back to my email service.cs and inside here we are going to have Main Jet client so we need to bring mailjet client and this is coming from major.player and then we name it as client is new mainjet player and we need to give the API key unsecretely so we have config and inside bracket we have mailjet Canon API key and we put a comma then we have config and mailjet colon secret key so make sure you don't have any spelling a mistake here so otherwise it doesn't work so you need to make sure that spelling is exactly the same as you have a specified over here so mainjet API key and Main gen security then I need to bring my image sent detail and after here we are going to have our email is new transactional email Builder and we have dot read from new send contact and if you have config email from so that's a from email address that you have specified over here email from and this is going to be the same email address that you have created your mailjet account and we put comma then we have config email application name then we have dot with subject and we have image send dot subject so the subject that we receive from our model then we have bit HTML part to image send dot body and then we have with two new send contact and then email send.2 then we have build and we put the same color then we have our response is debate client dot send transaction email async and we pass the email then we have if response dot messages is not not then we have give response dot messages and in the index 0 that status is called to success and return true otherwise we return parts then you need to open program.cs and provide your image Service as a service over here so just below JWT service we are going to have another Builder that services that has scope and we provide email service and then I open my accountcontroller.cs and inside here I'm going to inject my image service and as well as I configuration so I have image service and I name it as email service and then I initialize the field and I'm going to have eye configuration and I name it as configure I initialize this as well then I head down to register endpoint and be no longer are manually confirming the email so I remove this line so make sure email confirm is true as removed and I'm gonna comment out my return just before my return I'm going to have a try and catch and I have an exception here so I need to bring exception and for any exception do you have a written bad request and we have paid and then Inside My Tribe we have if a rate send confirm email async and the pass user to add if this is true then we are going to return a okay so I cut my commented quote and then I paste it over here and I remove the comment part and instead of this message we are going to tell your account has been created please confirm your email address so instead of you can log in we say please confirm your email address and we need to create this private method so I copy this and I head down to my private helper methods and over here just below here we have private async task up type Boolean and I paste send confirm email async and then this method is receiving a user object and we name it as user and inside here we are going to create a token using user manager so we save our token is a great user manager dot generate email confirmation token async and the password user and then we have token is the webencoders dot baseurl dot base64 URL encode and then inside the parenthesis we have encoding so we need to bring encoding from using system.txt dot utf-8 dot get parts and the password okay and we have our URL is we are going to use from string interpolation so we put dollar sign and double quotation and inside here we have a curry brace and we have config and inside my accounting we have JWT column client URL then after my curd brace we have forward slash then we have another carry brace and we have config and inside bracket we have email colon confirm email path so make sure don't have a spelling mistake or otherwise copy and paste from here so I copy confirm email path and I head back to my account controller and I paste it over here and then after the closing square bracket we have comma and we have token equals then I'll put another carry brace then we have token and then after here we have an email equals then we have another carry press user dot email and then we close our string interpolation by putting a semicolon then we have our body is then we use from another string interpolation so we have P tag and we end the P tag right here and just inside our P tag we have hello and then comma and then column space then we use from carry brace user DOT first name and space then another curly brace and user dot lastly then we add plus and then we have a string and inside string we have P tag and we close the P type and then we have peace confirm and then we have a plus and then we enter and in in the new line we have a string interpolation and we have a P tag and we'll just close the feedback right away because we don't want to make an incorrect HTML code there is no intellisense in here so make sure do not create any incorrect HTML tag and after here we have a hrefs and then I close my attack then we have a plus and inside a new line we have another string and inside the P type if you have thank you and then inside another string interpolation we have a br and then inside a curved brace we have config and inside the bracket we have email column application name so I go back to my app app settings.json and I copy application name and I head back to account controller and I paste it over here and then I put a semicolon to close my body so anytime I was using any C sharp core I use from dollar and quotation so that's called string interpolation but anytime that I'm using a simple string so I use from double rotation and this is the email that we are going to send the client so by saying hello first name last name please confirm your email address by clicking on the following link and this is a tag and inside the a tag we have the URL that we have created over here and the URL is containing the client URL so if I go back to app settings.development so we have client URL this is their client URL ah forward slash then we have email confirm email tab so my confirm email pass is account and for a slash confirm email and then if I go back then we have question mark and token and we pass the token and as well as the email address so this is going to be the URL that we are passing along the email that the client that the user is going to click and once they click they will be navigated to the angular site and they are going to confirm the email from there and that URL is containing the token and as well as the email address and after here we have our image send is new email send dto and we are making use of the three argument Constructor that we created so we have user.eman for the two and for subject we have confirm your email and then and for the body we pass the button I put the same color then the return a weight email service dot send email async and we pass the model so our send confirm email async has been completed then I go back to register endpoint and we have a error message over here if I hover over here it says not all code paths returns a value so that's complaining from here so I need to copy my batch request and I paste it down here as well so the error has gone and I'm going to start my API application and I open Postman and inside my account I'm going to register with a user account that I haven't register inside my application and this time we are going to put a valid email address that we can access to so I put and if I send then I can see your account has been created please confirm your email address so if I navigate to my this email address then I have received an email from Identity app and if I click I can see hello John Smith please confirm your email address by clicking on the following link and if I click then I have the URL of my angular localhost column 4200 forward slash account comfrey and email and we have a token and this is the token that we have generated and as well as we have the email address so we're going to handle confirm email next okay let's complete confirm email endpoint so I stop my API application and just below my register I'm going to have another endpoint and I name it as confirm email so we have HTTP Boot and we name it as configure Dash image and we have public async task of I action resolved and then confirm email and this is taking confirm email dto and we name it as model so we need to create confirm email details so I'll copy this and inside my details account so I'm going to create another class and I name it as confirm email dto and inside this class we have a property of stream talker and as well as string image and we are going to use from data annotation so we'll put required on top of both and for the email we are going to use the regular expression so I open register dto and I copy this regular expression and I come back to confirm email dto and I paste it down here and then I navigate back to my account controller and inside my confirm email we are going to have our user is the rate user manager dot find by email async and we pass model.e map so we are going to fetch the user using user manager find by email address and then we are going to check if user is null then return unauthorized and we say and then we are going to check if user dot email confirm is true then we return bad request and we say your email and then we use try and catch block once again inside my try we have one decoded token bytes is web encoders dot basically for URL decode and we pass the model dot token and then we have bar decoded token is encoding dot utf-8 that gets streamed and we pass decoded token bytes then we have one result is away user manager dot confirm email async and we pass the user and decoder token and we check if result succeeded then we return okay and inside okay we are going to have new Json result and if the result is not succeeded so we return a bad request and we say invalid and we copy the bad request and we put it inside our catch also so why are we using try and catch because this confirm email might show some exception if the token is invalid or the user has provided some invalue token for example the user has removed some of the characters and try to confirm their email using this URL so that's why we have put inside try and catch for any exception we say invalid token and you might wonder why we are encoding and decoding the token so inside our send confirm email async they are trying to create a token using the user manager and that user manager is creating a string of token but they are converting our token into base URL in code and this space URL link code is taking a byte array so we are converting our token into a byte array and converting that button ever into base 64 URL in code basically we're trying to encode the token and we try to encode the token underway back to the client and we try to decode the token on the way back to the API so inside here we try to use from decoder token and we use from base URL decode and this is taking a string of input and that one is our model.token and then we have decoder token using encoding.utfa dot get a stream so this decoder token has been converted to byte array and then from here we are trying to retrieve the token by converting the battery into a string so basically inside send confirm email ASM we try and call the token so this token has been encoded and once we receive the encoded token from our mother we try to decode it okay and then we are making use of user manager from confirm email listing and confirm email addressing is taking the user object and as well as the token and based on the token and the user object and if both of them are valid then the result will be succeeded so this is going to confirm our email inside the user property so for example if I examine my database inside asp.net users for example I have created my second user and the email confirm is zero but if this is succeeded then it is going to automatically update my database and for that record it's going to confirm our email and email confirm will become one or two and if that is succeeded then we are returning a OK response otherwise we are returning that requests and we have put both of them into try and catch because this might throw some exception and for any exception we are trying to return something to the client so I start my API application and from the URL that we clicked over here so I'm going to copy this into my clipboard the whole thing and I open my Postman and inside my account I'm going to create another request and we name it as confirm email and we have the URL forward slash API for a slash account forward slash confirm email and the type is put since we have a specified HTTP put over here and I click on body and raw and I select Json and inside my Json we are going to have so if I open and I open my config email detail we are going to have a token and email so we have a token and colon then inside my quotation I paste the whole thing and I put comma and we have email and I put colon on a quotation so from this URL I'm going to cut the email address and I paste it over here and for the token so we need to make sure we are only having the token so the whole HTTP URL on the way to token equals should be removed and as well as we have to remove the and person and email equals so the my token is going to be this so make sure to have put a value token and I'm going to save my request and then I'm going to put a breakpoint inside my confirm email and if I send then if I hover over I can see I have my email address and the token and if I step forward so I retrieved my user object using user manager and if I step forward so it is going to check if the email is confirmed so in this case the email address is not confirmed so it passed this if it's statement and then it goes to the try and catch and then we are trying to decode the token and if I step forward then I can see my decoder token has been converted into a byte array and if I step forward one more time then I can see this is the token that we have generated before inside our send confirm email async and then this is going to check the user object and the token so if I step forward then I can see the result is succeeded so at this stage and this should become one so if I execute one more time I can see email confirm is one so it has updated my database and then if I continue then I can see email confirm your email address is confirm you can log in now and if I try to send the request one more time this time I'm going to step forward and then I can see the email is confirmed before and if I continue then I can see your email was confirmed before please log into your account and I'm going to manually set email confirm to false so I say update identity app dbo.asp.net user set email confirmed to zero where ID is so I'm going to set the email address to Fox for this id address and then I'm going to remove some of the characters in order to make some a bad requests and I try to send so if I step forward then the succeeded is fast because we have passed some bad forecast and if I continue I can see invalid token but if I put those characters back in and if I try one more time so I can see the email confirmed okay let's try to create another endpoint and we name it as recent email confirmation link for example if the user has not received the confirmed email and they try to resend the email confirmation link so they provide that feature for the user so I start my API application and we are going to have HTTP post and we name it as recent Dash email Dash confirmation link and we are going to receive an email from URL so I have forward slash email and then we are going to have public async task or action result then we have resend email confirmation link and we are receiving a string of email from the URL so inside my endpoint we have our user a rate user manager dot bind by email async and we pass the email and before this we are going to check if the string is not or empty and we pass the email then return bad request and we say invalid image then after my bar we are going to check another if the user is null then return unauthorized and we say this then we are going to check if user dot email is confirmed is true then we return another bad request and we say your so we do a couple of checks if the email is empty and if we're not retrieving the user or their email address is confirmed before but if all of the checks has been passed then we are going to have a try and catch block once again and inside my try you are going to have if a rate send confirm email async and we pass the user so we are making use of our private helper method once again so that's why I have created inside a private helper method and then if that is true or this returns true then we are returning an okay response so inside my register I'm going to copy this and I paste it down here so inside my title I can say I can confirmation [Music] link sent and then I can remove this and I make it as capital please confirm your email address and if that is gone wrong so we return a bad request and we say and then I copy my badge request again and I paste it for my exception so I'm going to try this I start my API application and I open my database and I'm going to select everything and I can see my second account is email address is confirmed so I try to set the email confirm to false once again because I don't want to hit my one of the checkpoints so I set my email confirm to false and then I open my Postman and I'm going to create another request so I added a new request and I name it as recent so this is going to be a post so I select post and I select URL forward slash API account forward slash then I open my visual studio and I copied the whole endpoint and inside my Postman I paste it over here and I have a forward slash and then I'm going to put my valid email address so my value email address is going to be this one so I'll copy my valid email address and then I paste it inside my recent email confirmation and then I try to send then I send then I can see confirmation links sent please confirm your email address and if I open my email address once again and inside my inbox then I can see confirm your email then I can see that I have received another email to confirm my email so resend income stream email is complete and if I click on click here then I can see the same URL with some different token but we're not going to test this token because we have tested before okay now let's create another endpoint and we name it as forgot username or password so for example if the user has forgotten their password or their username so we are going to handle that situation for the user so I stop my API application and underneath recent email confirmation I'm going to have another endpoint and this sum we are using from HTTP post and we name it as forgot username or password and we are receiving an email using the URL and we have public async class by action reserved and we name it as forgot username or password and we are receiving an email then once again I have our user is the way user manager dot find by email async and we pass the email address and just above here again we can check this one so I copy my if this stream is null or empty and just above my computer so we are checking if if the user has not provided the email so we just simply say invalid email address and after here we are checking if user is not then we return unauthorized and we say this email address has not been registered so I can copy the text from here and I paste it over here and then we are going to check for the confirm so I'll copy this and I paste it down here and then we are going to make a use of a try and catch because we are going to call email service and that email server might throw some exception so that's why we are putting in try and catch and then we say if a rate then forgot username or password email and that is going to receive the user if that's true then return okay and we have new Json result and we have new and for the title we have and we put a semicolon and for any files so this is returning true or false so if it was false then we are returning a bad request and we say hey and for exception we try to send the batch request once again so I'm going to create this helper method just insert my private helper method section so underneath send confirm email I think I'm going to create another private helper method so I say private async task and it returns a Boolean and we paste the name send for God username or password and then this is going to receive a user and then I copy these three line and I paste it down here and instead of generate email confirmation token async I'm going to make a use of generate password reset token and then we are going to encode the token and for the URL we have jwc client URL or slash config email and confirm email path should be replaced by so I open my app settings.json that should be replaced by reset password path so I copy this and instead of configure event task we have reset password and that reset password path is using another endpoint so it has account for research reset password inside R angular and then we have the token and as well as email inside our URL then I'm going to copy the body and then I paste it down here then we have hello first and last name and inside my P tag I'm going to have username column so I need to make a user stream interpolation so just before here I put the dollar sign to convert this stream into stream interpolation and then we have user dot username so in case they have forgotten their username so we're passing the username and then after here we have another string and inside my string I have a P tag and inside my P tag I have in order and I put a plus over here and then we have the click here as well and we have thank you and application name then we have War image sense so I copy these two line and I paste it down here so our email and we are going to send another email to the user so if I navigate top and the error message has gone and I'm going to check this endpoint right now so I start my API application so first of all we are checking if their email has been confirmed so they have to confirm the email address so if I examine my database I can see the email is not confirmed so I'm going to manually confirm my email in order to pass this checkpoint so right now I have confirmed my email address then I open my Postman and I create another request so I save my previous request in order to be available here and then I create another request and I name it as forgot username or password and I say we are expecting to receive an email and then inside my URL we have URL for a slash API account and I can copy and paste from here just forgot username or password and then we are providing the email address so I can copy the email address from here and I paste it down paste it over here and this is going to be HTTP post so I select post and I say into my API collection and then I try to send this request and once I send I can see your email address was contribute for please log into your account so where we have made a mistakes so we are checking if the email is confirmed so this has to be false and instead of your this message we can say please confirm your email address email address first [Music] so we're not trying to send for God user or password for any user that they haven't confirmed their email address so this has to be checked against false if their email was not confirmed before then we're not trying to send the email so I restart my API application and then I try this one more time so I send my request and then I can see forgot username or password immersion please check your email so if I open my email address then I can see confirm your email and if I open then I can see hello John Smith's username in order to reset your password click on the following link and we can see the click here and if I head back to my account controller and inside my the subject of the email should be changed to forgot username or password instead of confirm your email so for this image we are sending a bit another subject so if I restart my API application and if I try this one more time then if I check my email address then I can see I have received from Identity app and this subject is forgot username or password and if I open that it says hello John Smith username is this one and in order to reset your password click on the following link and if I click on the link then I can see the path is different from confirming email so you can see reset password along with the token and all the way with the email address at the end so we are going to finish this section by completing the reset password endpoint so I start my API application and just underneath my forgot username or password we are going to have another endpoint and this is going to be HTTP put because we are trying to reset the password that's why we are using from put and put means updating so we try to update the password and we name it as reset password and then we have public AC task by action result and we name it as reset password and we are receiving a reset password ETO and the name as model so we need to create our reset password detail I copy this and inside my account folder I'm going to create another folder and I name it as reset password detail and inside my reset password detail I'm going to have 4K email and new password so I can make use of copy and pasting so inside my computer image detail I copy this to properties and inside my reset password detail I'm going to paste tools as well and after here we are going to have property of stream new password in case the user has tried to reset their password and this reset password is going to be required as well so we name we put required attribution at the top and then we are going to check the minimum and maximum length of the password so if I open my register dto then we are going to copy this and inside my reset password detail after here we are going to paste it over here so so we can say new password must be at least six characters and maximum 15 characters and then I head back to account controller and we are going to have one user is await user manager find by email async and we pass the model dot email and if user is none then return unauthorized and we say this email and we are going to check if user dot email confirm is false then return a batch request so this has to be double records and we say please then we are going to make another try and catch and then inside my try I'm going to borrow some code from confirm email so I copy all these line of codes and then inside my thank you reset password I'm going to paste those over here and then we are going to decode the token and for the result we are going to make a user reset password async so we try to make a user another function from user manager and that is reset password async and this is expecting to receive a user object token and as well as new password so we have provided user and token and then we can say model dot new password and if the result is succeeded then inside title we can say password reset success and inside the message we can say your password has been reset and for the bad request we can say invalid token please try again so I copy this and for any exception I have the same message then I'm going to try this endpoint so I start my API application and I open my Postman and then I'm going to create another request and this side we name it as a reset password and this is going to be HTTP input so I select that and we provide the URL and forward slash API account forward slash reset Dash password and inside body we select raw and Json then we have a token and we have email and we have new dashboard then I open my browser and then I click here we can see localhost 4000 account reset password so I copied the whole thing into my clipboard and I paste it inside my token then we cut the email part and we paste it inside the image section and then we are going to just provide the token so I remove all these from my URL so make sure only you provide the value token so you need to delete the equal sign as well and as well as at the end you need to remove the Ampersand and email equals so everything should be removed and this is a value token and for the reset password I'm going to reset it to six five four three two one then I'm going to add a breakpoint over here and I try this end point when I send I can step forward so my user has been found and the image is true and then if I step forward I'm going to decode the token and inside my result I'm going to pass my user and token and the new password and then if I step forward then the result is succeeded then if I continue I can see password research success your password has been reset and I'm going to save this request into my Postman then I try to login the user with the new password so I copy the email address inside my login inside the body I'm going to paste that over here and if I try with the old password then I can see invalid username or password then if I put the correct password then I can see the proper result so at this stage we have completed this section and we are going to push to the guitar so I sub the API application and inside my git changes I'm going to make a following comment section05 email confirmation comma reset password email complete and I commit all my changes and I push to GitHub but before pushing to the GitHub make sure you're not pushing your API key and API secrets so these are sensitive information but if you are still pushing to the GitHub you need to reset the secret key and that's how I showed you earlier so if you navigate to the main jet and inside your account you can click on this icon and click on reset secret key so I'm going to click here and then I select reset once I selected reset then the old secret key has been destroyed and I have a new secret key or you can make a use of user secrets and if you open your visual studio and if you rightly on API and you can click on manage user secrets in that case if you provide your API key and secret key over here then you are not pushing those into your guitar and that was the end of this section
Info
Channel: UnitK
Views: 2,587
Rating: undefined out of 5
Keywords: asp.net core, angular tutorial, angular tutorial for beginners, learn angular, jwt authentication, json web token, jwt auth, .net framework, what is .net, .net core, codequs, authentication, authorization, asp.net core identity with angular, asp.net core identity api, asp.net core identity tutorial, asp.net core identity with jwt, asp.net core web api, web api, asp.net core identity, asp.net core authentication, asp.net core authorization, jwt authentication and authorization
Id: zNj4Nc_2dBs
Channel Id: undefined
Length: 268min 9sec (16089 seconds)
Published: Wed Jun 21 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.