Express.js & Node.js Course for Beginners - Full Tutorial

# Building a Secure Authentication System with Role-Based Access Control in Express.js

## Introduction

In this tutorial, we will guide you through the process of creating a robust authentication system for your Express.js application. This system includes user registration, login, logout, form validation, and role-based access control using Passport.js. By the end of this article, you will have a secure application where only authenticated users can access certain routes, and administrators have additional privileges.

## Prerequisites

Before starting, ensure you have the following:

- Node.js installed on your system.

- Basic knowledge of Express.js and JavaScript.

- Familiarity with database operations using Sequelize or another ORM tool.

## Setting Up Authentication Routes

### Step 1: Installing Necessary Packages

Begin by installing the required packages for authentication:

```bash

npm install passport passport-local express-validator lodash bcryptjs connect-flash

```

### Step 2: Configuring Passport.js

Create a new file `passportSetup.js` in your root directory and add the following code to set up Passport.js:

```javascript

const passport = require('passport');

const LocalStrategy = require('passport-local').Strategy;

const User = require('./models/User');

passport.serializeUser((user, done) => {

done(null, user.id);

});

passport.deserializeUser(async (id, done) => {

try {

const user = await User.findOne({ where: { id } });

if (!user) return done(new Error('Invalid user ID'));

done(null, user);

} catch (error) {

done(error);

}

});

passport.use(new LocalStrategy({

usernameField: 'email',

passwordField: 'password'

}, async (email, password, done) => {

try {

const user = await User.findOne({ where: { email } });

if (!user) return done(null, false, { message: 'Incorrect email.' });

const isValidPassword = await bcrypt.compare(password, user.password);

if (!isValidPassword) return done(null, false, { message: 'Incorrect password.' });

done(null, user);

} catch (error) {

done(error);

}

}));

```

### Step 3: Defining Routes

In your `routes/index.js`, define the necessary routes:

```javascript

const express = require('express');

const router = express.Router();

const { signup, login, logout } = require('./controllers/auth');

router.get('/signup', signup.show);

router.post('/signup', validateSignupInput, signup.create);

router.get('/login', login.show);

router.post('/login', validateLoginInput, login.authenticate);

router.post('/logout', login.logout);

module.exports = router;

```

## Implementing Signup and Login Handlers

### Step 4: Creating Controllers

In `controllers/auth.js`, implement the signup and login logic:

```javascript

const passport = require('passport');

const User = require('../models/User');

exports.signup = {

show(req, res) {

res.render('signup', { title: 'Sign Up' });

},

create(req, res, next) => {

const { email, password } = req.body;

User.create({

email,

password: await bcrypt.hash(password, 8),

isAdmin: process.env.ADMIN === 'true'

})

.then(user => res.redirect('/'))

.catch(error => next(error));

}

};

exports.login = {

show(req, res) {

res.render('login', { title: 'Login' });

},

authenticate(req, res, next) => {

passport.authenticate('local', (error, user) => {

if (error || !user) {

req.flash('error', error.message);

res.redirect('/login');

} else {

req.login(user, () => {

res.redirect('/');

});

}

})(req, res, next);

},

logout(req, res) {

req.logout();

res.redirect('/');

}

};

```

## Validating Input

### Step 5: Implementing Validation

Create a validation middleware in `middleware/validate.js`:

```javascript

const validator = require('validator');

const _ = require('lodash');

exports.validateSignupInput = (req, res, next) => {

const errors = {};

if (!validator.isEmail(req.body.email)) {

errors.email = 'Please use a valid email address.';

}

if (!validator.isAlphanumeric(req.body.password)) {

errors.password = 'Invalid characters in password.';

} else if (req.body.password.length < 8) {

errors.password = 'Password must be at least 8 characters.';

}

return new Promise((resolve, reject) => {

User.findOne({ where: { email: req.body.email } })

.then(user => {

if (user && user.id) {

errors.email = 'Email is already in use.';

}

if (_.isEmpty(errors)) {

resolve();

} else {

req.flash('errors', errors);

res.locals.formData = req.body;

next();

}

})

.catch(error => reject(error));

});

};

```

## Securing Routes with Middleware

### Step 6: Creating Access Control Middleware

Add a middleware file `middleware/auth.js`:

```javascript

const _ = require('lodash');

exports.isAuth = (req, res, next) => {

if (!req.user) {

req.flash('error', 'Please login first.');

return res.redirect('/');

}

next();

};

exports.isAdmin = (req, res, next) => {

if (!req.user || !req.user.isAdmin) {

req.flash('error', 'Unauthorized access.');

return res.redirect('/');

}

next();

};

```

### Step 7: Securing Leads Routes

Modify your routes to include authentication:

```javascript

const auth = require('../middleware/auth');

router.get('/leads', auth.isAuth, showLeads);

router.get('/leads/:id/edit', auth.isAuth, editLead);

// ... other protected routes

```

## Implementing Role-Based Access Control

### Step 8: Adding isAdmin Field to Users Model

Update your `models/User.js`:

```javascript

const { DataTypes } = require('sequelize');

module.exports = (sequelize) => {

sequelize.define('User', {

email: {

type: DataTypes.STRING,

allowNull: false,

unique: true,

validate: {

isEmail: true

}

},

password: {

type: DataTypes.STRING,

allowNull: false

},

isAdmin: {

type: DataTypes.BOOLEAN,

defaultValue: false

}

});

};

```

## Conclusion

By following this comprehensive guide, you have successfully implemented a secure authentication system with role-based access control in your Express.js application. This setup ensures that only authenticated users can access certain routes, and administrators have additional privileges to manage content.

"WEBVTTKind: captionsLanguage: enhi in this tutorial i'm going to show you how to develop a web application using node.js and the express.js web framework we will then deploy our application to aws using elastic pinstalk environment we will develop a landing page where we collect and manage sales leads you can freely use the resulting source code as a starting point to develop your product and we will cover all of the concepts that you need to know to build a fully fledged web application using node.js we assume intermediate programming knowledge but no background in web application development or not js okay let's get started so a little bit of background on node.js many years back developer ryan doll explored the idea of using javascript for server-side programming with the main motivation that existing http servers could not handle lots of simultaneous connections efficiently meanwhile also google's chrome browser team developed a new javascript engine from scratch called v8 and the unique property of v8 is that it was built to be much much faster in interpreting and running javascript compared to the other browsers and nodejs took google's optimize v8 javascript engine for server-side programming also creating a setup that allowed for much more scalable handling of requests and also a package manager for managing the open source javascript libraries was introduced called npm and node.js was worn now before we install node.js we're going to start by installing a script called nvm so go ahead and type nvm in your browser and click on this link and vm is short for node version manager it's a script to manage multiple active node.js versions on a single computer so let's go ahead and scroll down to copy and paste the install script for nvm and we'll paste it on our terminal now i already had nvm installed so this step may take a little longer in your case and what you need to do is close and reopen your terminal so that the nvm script can initialize while your terminal starts you can check that your installation was successful by typing nvm version we're now ready to install node.js so let's go back to nodejs.org we're interested in the long term support version of node.js and as of this video it is 10.15.0 is the version that we need so we go back to our terminal and type nvm install 10.15.0 now this step may take you a little bit longer you should have now node.js installed and being actively used just for the sake of showing you how it works you can also install other node.js versions let's go for 8.11.3 for example and you can switch between node.js versions by typing nvm use so let's switch back to using node.js 10.15.0 now for our application we're going to use express.js so let's go ahead and visit express.js express.js is a web framework and the power of it is in its simplicity you can develop very complex web applications yet it is a minimalist web framework that is very easy to grasp and this is the install command for express.js but we're going to use another tool called the express generator that will give us a good starting point and a directory structure so let's go ahead and copy and paste this command in our directory to install express generator now here in this command npm as i mentioned is the node package manager we will use this to install packages and here the dash g stands for a global install which means the installation is going to happen the computer-wide and not just one particular project so i'm going to press enter now and now we can go ahead and run express generator to generate our application and a useful directory structure so i'm going to copy paste this command here dash dash view equals pug means we're going to use pug as our html templating engine so i'm just going to press enter and we have now created a directory structure for our application now that we have generated a skeleton directory structure for our application i want to go over each folder we created so let's go ahead and start our text editor and let's take a look so under my app the public folder contains our assets assets are static files that your html files makes references to each html file will refer to certain images such as logos and some javascript files that need to be run on that webpage or style sheets that describe the style on a web page the rouse folder contains the router logic we will get to routers in a little bit and it's one of the key parts of our application and finally views contain the representation of each individual html page in our application notice that these are named pug files each of them get converted to separate html page the bin www file contains the initialization script for our web server and one of the notable files is app.js this is the main entry point for our entire web application and also we have the package.json file which is a recipe that contains the list of open source packages we need to install to run our application now let's go ahead and install these packages and run our application as it is so we go back to our terminal cd my app and we type npm install we're pulling and installing all those packages this file contains not just the packages that we need but also npm allows us to fetch all the dependencies that these packages have and now in order to run our application we need to type this command and once i press enter the web server is running on port 3000 and when i visit localhost 3000 on my browser i get to see this web page served if we go back to our source code app.js is the most important file that we care about app.js defines our web application and node.js express.js applications are monolithic meaning that every piece gets put together into a single application and let's see how that works we first import modules using the require statements and typically these modules are those ones that we find under the package.json file these modules here you will see that they have been imported and assigned to variable instances the one we're interested in is this express variable as you see the required statements includes the express package assigns it to a variable and then later on we call the constructor for express and assign the result to a variable called app an app is an instance of an express application typically this is a vanilla instance and then we make certain method calls to modify and configure our application and also use and include other modules here we first set that the views are included in a directory called views this is what this line does and we have as you can see a fuse directory here and next we set that we you are going to use pug as our view engine so the app instance that is unmodified and new gets modified by these set calls and then we have certain use method calls where we define further configuration and further components that we're going to use and one of the notable ones is the index router object that we have defined in this project if you go up here we use the require statement to include an index.js under the routes directory whatever that has been exported from this index.js file is assigned to an index router variable and this instance is then used for the path that is slash so this line means that our application is going to use index router for the slash route and that's how we also connect pieces of our application into one monolithic instance because index router was defined here under index.js and it has been included from app.js let's take a look at how the route object is defined if we go under routes and index.js again we are requiring the express package we have a variable called express and then we call a router to create an instance of an express router and just as we did here the router instance here is a vanilla instance it hasn't been modified and then we make some certain method calls to define it further in this particular case we're defining a get method and how to handle this slash path with a function and then we export the router instance that we have created to be included by another module and app.js includes that router here and that's how we connect it and the router object to recap is a vanilla instance then we make some modifications on it and then we export it and this pattern is used throughout the application this is how you divide your application into separate instances now let's take a look at what a route handler is and how it works here we have a router variable that is an instance of an express router and this router variable has several components that we care about the first one is that we're making a call to get and this defines that the route handler is associated with the get http method and then the second component we're interested in is the path so typically a router will match a particular path used in a url and then finally there is a handler that gets called if a path is matched to look at it more closely if this is our url the first section defines the protocol being used and the second one is the domain and then finally after the slash here we have a path component so a router object will look at this path and see if it is a match for the path that it has in its own definition finally the router will call the handler that's associated with it the last bit of detail here is that the get method here is defining the http method that this route handler is limited to it only responds to this get method if there are no routes that match for a given path or http method our application generates a 404 error which means not found so as a recap under routes index.js we're creating an express instance and then we're calling express.router to create a router instance and on this router we're defining that for the http get method if we are looking for the path slash and it gets matched we call this function as our handler for this route and under app.js we have an index router representing our exports from routes slash index file and then we have this statement here app.use and for the slash path we're using index router effectively meaning that when we type this root path with no slash or slash it means the same thing essentially and when we press enter we call the route handler that's defined here which renders our index page and that's how essentially our route handler works before we dive into source code and define routes and handlers let's cover what an http request is and how a request sequence works the http short for hypertext transfer protocol defines multiple methods for browsers to communicate with web servers and the http methods allow the browser to take different actions the get method simply fetches a resource from the web server such as a web page when we make an http get request the server typically responds with a resource such as a json object or an html file and in our current scenario we are interested in sending back an html web page and we use the express js specific method called res.render a restart render will generate an html page and our web server will respond back to the browser request with a web page and the other method we're interested in is called http post this is typically used for submitting data to a web server when you fill out a form on a web page and you press the submit button the data is sent to the web server and typically an http post method is used there are multiple http methods and what method is to be used is defined in the form definition on that particular html page but most of the time and almost always a post request is used and once the server receives the post request it does something with the sent data such as updating a database and then the server typically calls the res.redirect method again this is specific to express.js to redirect the browser to another url or path so the server responds with a redirect after processing the data back to the browser and finally the browser will do another http get request as a third step fetching the route that it has been redirected to now there are a few more http methods but this gives you the foundation for developing a rich web application now you know enough to develop routes route handlers and develop your application one of the issues with our route handler is that the logic that matches a url pattern is here but also the handler function the handler logic itself is defined as part of the root handler and what we want to do is separate these two so that we have a modular approach so we go to our terminal and i'm going to create a directory called controllers controllers essentially are a collection of root handlers i'm going to copy this function from here and place it under controllers in a new file save it here and give it a name called index and save it with the name index.js and if i go back to the routes and define index as an instance of what we have exported from our controllers index.js file i can now refer to the handler that i've defined from this route file so if i go back to controllers as a recap we have an index.js and we have a method called index that we're exporting as our handler and under our routes let's save this file again and under our routes we are importing it as a variable instance called index and we're assigning the index handler for this route let's now save our application restart it and see if it will work so i'm restarting the application and typing this url and it's working so controllers allow us to separate handler logic as you see in this example from the root handler logic and we're going to build many more of these controllers now let's take a closer look at what our controller function does so if we go under controllers index.js we named our function as index and the only call it has is to a call called res.render the resident render call renders an html page from a template the first argument is the name of the template file which is index if you see under views directory we have a file called index.pug and the second argument is a javascript object with a key value pair the key is title and the value is express now under app.js we did define our view engine as pug and we did define that the views are located under the views directory so express.js knows where to search as the starting point for view files so when we pass index as the first argument it will go and look at the views directory and find that there is an index.pug file here and then pug will convert this template into a real html if we look at this second parameter again title colon express we also pass this as a parameter to pug so if you look at index.pug it will use the variable and replace it with its value there are two cases where the value is being used here we'll get to this when we look at pug in more detail but essentially our controller function simply renders an html page it responds with a html page back to the requesting browser now is a good time to use version control and checking all the files that we have created so i'm assuming that you've installed git and i'm going to initialize a git repository here by typing git init db now we've initialized the repository and you can check that we have created a dot git file in the current directory that stores all the files by our git repository and now i'm going to check in all the files but before i do that i need to create a file called git ignore under my app let's create that file and type node modules in it because node modules are installed open source files they're not part of our project and git ignore file having node modules will exclude those files all of these files from our version control typically any file that gets auto generated or external to your repository you should exclude by using a git ignore file okay going back to the terminal i'm going to make my first comments by typing git add dot dots here representing the current directory so i'm going to add all the files in my current directory to the git index and commit them by typing git commits dash a meaning commit everything that is in the index to git so as you can see we have a bunch of files being committed and we're also including the get ignore file so let's type initial comment and save and exit and we have essentially committed our first change to our git repository to get the full source code for the tutorials if you go to this website and scroll below you will see posts with programming snippets as well as the link to the source code for those tutorials and if you have questions you can click on this button on the same page become a member it's free and then you'll be able to add comments to tutorials and get answers now one of the problems we have is that every time we make a modification in one of our source files we need to restart our web server because the changes made to source files are not being recognized and in order to remedy this problem there is a tool called node mount that we are going to install so i'm going to stop our web server and i'm going to install nodemon by typing npm install nodemon and then also typing save dash dev what this does is the save dev will save nodemon as a developer dependency meaning that we only need to install it when we are developing our application so if we go under package.json we now see that nodemon is a developer dependency and now we need to modify this line so that in the case of an environment where we're in production we're still using the standard node command but in case of development we're going to run nodemon instead that monitors for changes in source files and restarts our web server so for the start scripts i'm going to go ahead and type if the environment is production then we use node.bin www else we use nodemon bin www and then fi now this should work and we are going to use nodemon to monitor our web server so let's go ahead and try running this okay as you can see nodemon has started and when we make any source code changes it's going to automatically restart our web server now is a good time to make a git commits because we've installed node mode so i'm going to do git add package.json and then git commit dash m install nodemon now i'm going to cover the most common web application development pattern where we are going to build a landing page with various routes to collect sales leads manage them view them and delete them and edit them let's go ahead and rename the variable index as landing because we're going to build the landing page and our controller is going to be called landing and we're going to name our first method that gets our landing page as get landing so if we go we save this file and go to controllers index.js let's let's rename this file as landing.js and first function is going to be get landing and also let's rename the view now when we fetch this file we're going to display a form where if a visitor likes our service or our value proposition they will enter their email address and send us that information in a form so i go under views landing that pug and right below this paragraph i'm going to design a form the the form element takes one parameter called the action when we submit the form which path we're going to use is defined by action so i put a comma and for the second parameter i'm going to use the method called post when you submit a form the method that has been defined in the form is the one that the browser will use for making the request so we're interested in using the post method and i'm going to define an input element of type email and we're going to use a placeholder let's write here enter your email address notice how there is an indentation here pug nests html elements by using indentation so inside form we have nested an input and also typically we want to nest a button inside a form so that the button is associated with that form so i'm going to define a button elements of type submits when this is a submit button that indicates that we're going to submit the form that the button is nested in we're going to use a name for the button called submit and i'm going to now save this form let's make sure all of the files are saved and if i now restart my application i should see the form being served if i press enter here right so we have this enter your email address form with an input and then a submit button we're also going to commit our changes by typing git add because we renamed some files we need to explicitly add let's do git add views git add controllers let's see if we have captured all the files i do git commit dash a to commit all the changes landing.pog has been registered as a new file and so is controller landing.js but we missed views landing that box so i'm going to explicitly add that file landing.pug okay now if i commit we should be covered with all the files that we have renamed and added in git so i'm going to write a commit message landing page getting started and first form typically in git you first summarize your change in a single line and then you would leave an empty space and then include further information in the second paragraph but at this point we don't need to mention much i'm just going to leave it at the first line now that we have defined this form we're going to develop our first post route so i go to routes index.js and include a new router with the post http method and then i'm going to use a new handler called landing.submit lead because we're looking for sales leads it is called submit lead i'm going to save this file go to the controllers landing.js i'm just going to copy and paste this first handler that we had and i'm going to name the second one as submit lead when we submit our form from landing.pug there is this input element we forgot to name it so i'm going to define a name for it called lead email when the form is submitted from that browser we're going to be able to access the value inside this input element with the name lead email by going to our controller let's delete this statement here we're going to print out the input element that we have received lead email and the way we do that is by using the body parser library we are going to do rec dot body lead email to print out the value i believe i need to include the package called body parser in app.js for this to work but it turns out express.js already includes this functionality this allows us to retrieve the values for input elements when there is a handler for a post request if we simply do rec.body.lead email we're going to be able to access the value inside the input element now this handler is successfully reading this data but we can't leave it at that we need to conclude the request so we're going to do a res that's redirect and we're going to use the original path of slash so that we go back to the uh landing page for now so i'm going to save this and we're already running the application let's see what happens if we submit an email address here my email at domain.com so i'm going to press submit as you can see the browser was redirected to the same page but let's see what happened in our console we were able to receive the value and print it let's check in all the changes we made so let's go to our terminal and type git add controllers landing.js git add routes index.js and we also modified our view file so we're going to do git add views landing.pug and comment landing page post route to submit email so we're able to receive data in our application but we're not able to do much with it so we're going to install a database an sql database a particular postgres database for our application go ahead and open up your browser and type homebrew homebrew is a package manager for mac os and one of the packages maintained is the postgresql package so you can copy and paste this installation script on your terminal if you're on a mac os to install homebrew let's go ahead and just do that and it's going to install a command line tool called brew which will allow you to then install various packages including a postgresql now i have it already installed so i'm going to skip this step and assuming you have installed this we can then install postgres by typing brew install postgresql so after you've done that you can start your database by typing brew services start postgres ql this is going to start the postgres process in the background on your machine so that you can connect to it and create databases manipulate tables do things with it so i've already run this command so i already have my database running we're going to use a tool called psql to connect to our database and make some changes so i'm going to type psql postgres to connect and if everything goes well you should see the postgresql prompt and now we're ready to create our database first we create a user that can access that database by typing create role express mvp db user i'm assuming here that i'm going to use the name express mvp for our application so i'm just adding a db user for that and with login password let's make the password simple for now and press enter and now i'm going to create our database by typing create database express mvp db in case you want to delete these roles or databases and redo the same commands you can do that by typing a drop database or drop role so we're now ready with our database i'm going to quit psql by doing the control d we're done with our database setup now we're interested in using a library for accessing our database from javascript and manipulating data and for this we're going to use an object relational mapper library shortly called an orm we picked sqlize as our choice of orm if you go ahead and type sqlize in your browser you're going to find a website for it as sqlize is a stable and popular orm for node.js and it will work well for most of our needs and rm greatly simplifies the type of queries you have to write for manipulating database tables and rows instead of typing long error prone sql queries and rm lets you generate those queries by writing javascript okay so let's go ahead and open up our terminal again and type npm install sqlize this will install sqlize as a package i recommend doing dash dash save so that it's saved to our package.json file we're also interested in the database driver library in node.js for postgresql which is simply called pg so i'm going to go ahead and type npm install pg save as well sqlize will invoke pg in order to access the postgresql database this is a low level library for accessing postgresql databases the other tool that we need is a command line tool for sqlize called sqlize cli so i'm going to install that as well by typing npm install sqlize cli and i'm going to use dash g so that concludes our installation for postgres and sqlize now we're going to create some configuration files so that our application and sqlize can access our database and for that we're going to use the tool a sqlize cli but before we start we need to first create a configuration file for sqlize cli so that the default paths we use are going to be defined let's go ahead and create a file called dot sqlize rc in the root of our project typing a touch dot sqlize rc and let's open up our editor when we open a sqlize rc we see certain paths defined let's remove the db path and let's keep it empty for now we want to create these directories directly under our application root folder so that they're accessible easier with one less step so let's go ahead and save this file and now we're ready to generate some files so i'm going to by sqlize init and we have created several folders the config config.js is the one we're interested in this is defines the database details let's open up our editor again and go to config config.js we have three environments defined here one for development test and also one for production so i'm going to type here module that exports equals and for developments we defined the database username as express mvp dash db user as our password we defined 123.456 and for our database these are the users and database we created using the psql command previously so we're going to type express mvp db and our host is 12701 this stands for the localhost the database we're using is postgres so we're going to use the dialect postgres here there's one more parameter missing here the port parameter typically for a postgres database that is a 5432 i'm currently not going to touch the other environments and going to save this one here so we should be now ready to access our database from sqlize using our application now i'm going to go back to the terminal to commit some of the changes that we made so far we installed sqlize and the pg library so we've modified our package.json file let's go ahead and create a comment for that change we have added sqlize and pg packages and i'm going to save this comment we've also defined a sqlize.rc file so i'm going to add that one as well and commit this change configuration file for sqlize cli and i've also created a configuration file for our database connection so i'm going to commit this file with git add config config.js there's also one more file that i'd like to introduce to you briefly under models when we ran sqlize in it we defined the file called index.js this will initialize sqlize when we run our application it takes the environment that we defined under config.js and then creates a new sqlize instance using the database credentials that we have created so this is the initialization file that was auto generated when we typed sqlize init so i'm going to check this file in as well and the file name is always index.js under models and this is a specific file just for initializing sqlite so i'm going to commit these changes so we added configuration file for sqlize and the script as a recap for where we've left off we can visit our landing page and then submit an email address to our application and display the email address collected as a console log now that we have installed our database and installed sqlize orm and configured it we're ready to define our first model as well as the first migration so let's go ahead into our text editor and create a new folder called migrations and let's create a new file under the models directory named lead.js since we're collecting sales leads our table and model will be named leads migrations allow us to create recipes to take our database state the database definition from point a to point b for example right now we have no tables in our database even though it has been created and with a migration recipe we will be able to create our first table that represents our sales leads and we will run that migration to create our first table and start accessing it and the model definition is used by sqlize to create to generate the methods for accessing the table and to update the table to take database actions on the table such as creating rows deleting rows updating rows and fields and in contrast migrations are used for manipulating the database table definitions themselves such as creating a table adding a new column or changing the type of the column in that table the migration file that we're going to create is highly specific to sqlize sqlize has low level methods for accessing and manipulating a postgresql database but the migration itself is a file a recipe that's specific to sqlize and so is the model that we're going to define so let's go ahead and create a new migration file and let's define our first table i'm going to copy and paste this code that i have already prepared as our first migration let's first save this file migrations are a sequential in the sense that they need to be run in order they don't make sense if they are run without an order so we need to order them by the file name and we do that by including a date starting with the year a month and the hour and even the minutes when the migration is created so as of now we're in january 4th 2019 so i'm going to name my migration as 2019 0 1 0 4 and then the hour is 19 17 and i'm going to include the action that this migration is going to take which is creating a table named lead so create lead table and then finally that's a js here is our first migration saved and the migrations are bi-directional so you can apply a migration represented by the up method and then you can roll back a migration by using a down method so in this case the up method stands for creating a new table called leads with so and so fields and then the down method or action represents dropping the table will effectively cause the table to be deleted from our database now if you look at the fields that are being generated we first obviously have an id field and id represents a unique column in our database and it's represented by universally unique id type and sqlize has that type built in for us and typically we need a created ad and update that field for each row when a new row is created this date will be relevant and each time a row is updated this second field updated at is going to be irrelevant and finally the actual field the data that we were collecting in our application is an email address so we're including a field called email of type sqlize string so we have saved this migration we can go ahead and run it by typing sqlize db migrate the command has succeeded which means we have created a table called leads in our database now we need to define the sqlize model definition for the table we just created so let's open our editor and create a new file under models called lead.js i'm going to copy and paste the definition that i created earlier for this this javascript model file is specific to sqlize sqlize will generate the methods it needs to access the database table by using this model definition we define an id field in the model which is a primary key and then we define an email field as well which is of type string notice how these fields match the migration we just ran for the leads table and we omitted the created that and updated that fields in the model because sqlize assumes they always exist when we run the application sqlize will run models index.js if you look at this for each section it will go over each model definition under the models directory to import and use for accessing the respective database tables under models directory for each database table we define a model such as the one we created for lead.js for the leads table and sqlize will go over each of those to generate the methods so that it can access those tables in order to achieve this we need to go to the initialization file bin slash www and here initialize sqlize for that we need to first create a variable called models and import the models directory and these three lines start our server listening on a particular report we're going to modify this code a little bit and we're going to type return models.sequalize sync and then result going to cut and paste this portion inside the body of this call okay we're now ready to further develop our application and run sqlize queries before we go any further let's check in the files that we have just created so i'm going to add the migration we created and commit this file create migration for leads table for creating leads table i'm going to check in the model as well it's add models lead.js we're also going to check in the changes we made on the initialization file bin slash www initialize sqlize in bmw now that we have a database set up we can implement the post route where we will save an email address to our database so let's go and open up our editor and go to controller slash landing.js we're going to modify the submit lead handler to save the email address collected to our database so let's go to the top and then type const models equals require dot dot slash models models gives us access to the sqlize methods for the models that we have defined and i'm going to type return models that lead that create note that create is a sqlize method and for the email field we're going to use the value we've obtained from reg body lead email then take the results and redirect back to the landing page and let's delete this last line and the first line save and rerun our application if i go back to the landing page and type an email address here username at email.com and submit notice that the browser reloaded the landing page and that's because of the res redirect here and i'm assuming that the create call has succeeded if you go back to our terminal we see this sql statement here generated by sqlize run by sqlize we're inserting a new row into the leads table particularly the id email created that and updated that fields new a unique id for the role and then the email address we just submitted and then the dates so we've successfully saved the email address in our database let's commit the changes we made so i'm going to type git add controllers landing js and then commit the change save leads collected on landing page we save email addresses collected back to the database we're going to implement the most common web development pattern shortly known as crud which stands for create update and delete we've already done the creation of leads with this route and now we're going to define new routes that allow us to do listing editing updating and deleting of leads so and the first one we will cover is for listing delete so let's define a new route with the path slash leads and the handler called as show leads and let's save this file and let's go to controllers landing.js to define our new handler let's copy and paste the first one we created let's name it as show leads now all we need to do is fetch the leads from the database and for that we're going to call models lead dot find all and then we will be returned an object let's name it as leads and let's cut this line with the res render and paste it inside the body here a few things to note this call here is a promise and we're going to cover promises in detail later but for now what you need to know is that this call is going to execute asynchronously and the then here ensures that the results within this body are available after the execution of this call has completed so there's a guarantee that this body is going to be available after this execution even though the call is asynchronous and we'll get to those later and the file all method is defined by sqlize and also the leads object here contains the rows returned from the database and also the methods to access those rows so as you can recall the render method the second parameter is an object passed to our view file we're going to define a new key here called leads and assign it the value of our object leads and save this file and one more thing to note is that this view file usually typically we use a different view file for each purpose but for the time being we're going to use the same landing view file to also show the collection of leads now let's go to viewslanding.pug we're going to type if leads pug will check that if the leads variable is non-zero it's going to include the rest of the html snippets let's type if leads and then let's define a header here called with the text leads plug also has the capability of iteration we're going to do for lead in leads note that leads is an array of objects of type elite we're going to create a paragraph and type lead.email now pug considers that anything of that comes after the p is text we don't want to display this as text and we want to use the pug way of syntax of dereferencing this variable which we used here by typing hash open curly brackets and then close curly brackets so let's save this landing file and go to our terminal our application is still running so let's go to our browser and type localhost 3000 there's one more thing we want to do let's go back to the landing.js controller now instead of redirecting to the slash route we actually want to go to the leads route when we submit a new lead so that's the change we make so that the this new route that we defined is going to be triggered which we'll call this show leads function okay so if we go back to our browser let me submit a new email address lead one email.com and when i submit this i see the list of leads on the same page and notice how the browser went to the slash leads routes because of the change we just made so let's check in the changes we made so i'm going to do git add controllers landing.js git add route index.js and add views landing.pug implement leads routes show a collection of leads upon submission now we want to take a look at the details of each individual lead so let's define a new route called slash lead slash colon lead underscore id and let's define a handler landing that show underscore lead now two interesting things here firstly we defined slash lead slash as a unique path component to match individual leads and notice how this path is unique and different than the other routes we defined we will handle all details of an individual lead under slash lead slash path component which gives us sort of a namespace to work on individual leads the colon here defines lead id as a parameter as a request parameter that means whatever that comes in the url you type in the browser after slash lead slash is going to be captured in a request parameter named lead underscore id and we can then access the value of this parameter in the root antler show lead now let's go to controllers landing.js and copy and paste one of the handlers we already have let's name it as show lead and what we need to do now is query the database for a lead with a given id so i need to do return models.lead.find1 and then the where clause helps us query for a particular field and we're going to use the id field and we're going to pass the request parameter that we received named as lead id to find the particular the lead record in the database corresponding to our lead now this will return a lead value let's go ahead and delete this portion and here we're going to do res render we're going to define a new view file called lead and pass an object with key lead assigning it the database object that we received now let's save this file and go ahead and create a new file under reviews called lead let's copy the initial portion of landing that bug and let's define an h1 lead header and let's simply define a paragraph with the lead information lead.email now let's go to landing.pug we want to give the user an opportunity to click on a link that takes us to the individual details page for that link and we don't have that link here so i'm going to add that to this paragraph but i would like to display both the lead email and also that link on a single line the same line so i'm going to nest the link and the email under the same paragraph as a reminder we nest html elements with indentation in pug so i'm going to first define under the paragraph a span elements that will display our email and also um this character that i'm typing is used for text and also to display spaces in park so i'm going to include one space character and define our link with the anchor tag with an href property of slash lead slash and now here we already have access to the lead object that has been obtained from the database so we can include the id of the lead here by typing lead.id and we are going to use the text details in the link so now this link is going to point at the path slash lead slash plus the database id of the lead so let's save this and run our application everything seems to work fine so let's open up our browser type localhost 3000 let's submit a new lead new leads at domain.com and see that we're able to display both the leads and also the details link for those leads i'm going to click one of them we're now navigated to that path and we're able to display the lead information now let's check in all the changes we made it add views it adds controllers and routes and then if we commit now add a new route to display lead details let's go back to routes slash index.js and we're now going to define the routes for editing individual leads so let's type router that gets slash lead slash colon lead underscore id and we're going to define a new action for this particular lead id which is going to be slash edit and we're going to define a new handler with landing dot show edit lead now this is a gate route which means that we're going to fetch a new web page for the purpose of editing the lead id so we're going to deliver a form that contains information about this lead id by using the show edit lead handler and let's type router.post slash lead slash colon leads id slash edits and define a new handler called edit underscore lead here the first route we defined shows the form for editing the lead id and the second route we defined which is a post submits the form to edit the lead id now there's one key point here we are highly interested in defining the same path component for the get and the post routes and this is because on an error when we handle the post request if we re-render the same page we want the url in the browser to match the original get request we're going to go into more detail about this when we cover error handling now let's get started by creating the link that will take us to the edit route for the lead for that let's open up views lead.pug now we're going to modify this by creating a span under the paragraph and we're also going to create a link an anchor tag with an href of slash lead slash plus lead.id remember that we have the lead database object available to us so we can reference its id and also we're going to add the slash edit path for editing the lead now let's write edits for this link and save this file and notice how the value of this hf property corresponds to the get route we defined here now let's define the handler for this show edit lead route by going to controllers and landing.js and let's copy and paste one of the handlers here and call it show edit underscore lead now this handler also obtains one lead record from the database by using the lead id parameter and then we're going to instead of displaying the lead we're going to display a form where we can edit and submit the updates on a lead so i'm going to call this edit underscore lead and we're going to use a directory called lead for all the view files where we manipulate each lead so i'm going to finally call this lead slash edit.leads now let's save this controller and create a subfolder under views called lead and also create a new pug file called edits underscore lead dot pug now let's go to landing.pug and copy the beginning portion to edit lead and now we're going to create a form under edit lead where we will modify we will have the opportunity to modify the lead so we can copy some code from landing.pug we or where we already had a form i'm going to copy this form and input element and the button elements to edit lead now the action for our form needs to reflect the route that we defined here which is lead slash leads and then the lead id and edit so let's go ahead and add that here we're going to use plus lead.id and then plus slash edit and the method we're using is post method and we're still going to use the same name as lead email in our input it is of type email if we need we have a placeholder if the lead field is empty and then let's call this button save now rather than an empty form we want to show the existing value of the lead so we're going to add a new property in our input element called value and assign it with lead.email which we will receive from the database now let's save this file because this file is one subdirectory under views because we created this lead directory and we are referring to layout.pug at the beginning we need to update also our reference to go one directory level below now if we go back to our index.js file we haven't defined the root handler edit underscore lead for the post route so let's go to our controller's landing.js and define a new route called edit lead and let's delete the body now we have access to the leads id by using rec.params.lead underscore id because this was available to us in the route path we also have access to rec body lead underscore email the actual updated field and that comes from the edits lead form the name of the input element was lead underscore email so we're going to use these fields to first retrieve the object by using its id and then we're going to update its email field by using lead email let's go ahead and type return models dot lead that update email rec body dot lead underscore email and we're going to use a where clause we're going to ask for the id field using rec params lead underscore id and our query is complete then once this field has been updated we're going to receive the results as how many fields has been updated from sqlize we're going to redirect the user to view the lead so we're going to use slash lead slash plus rec params lead underscore id so this way after the post is successful and update is done we're going to be redirected to this route that shows the details of the lead now let's save our controller and run our application and see how it works so i'm going to open up the terminal the application seems to be running ok and i'm going to open up the browser and browse to localhost 3000 let's create a new lead hello at getbuzz.io and submit that so we have a collection of leads displayed let's click on one of them and click edit we're now on the edit route and i'm going to shorten this to let's say a at b.com and save it and i'm redirected to the show lead route that shows the updated leads so this concludes our tutorial on editing and updating leads now is the time to go back to our terminal and check in the changes we made so i'm going to type git add views git add controllers git add routes these are the directories that we modified and then we're going to comment add lead edit and post routes the next route we're going to implement is the delete route let's go back to our editor routes slash index.js and create a new route router.post slash lead slash lead id slash we're going to use the delete path components and then let's define a new handler called delete underscore lead let's save this file and then go to controller landing.js and let's create a new handler for the delete action let's call this delete lead we're going to delete the row in the database representing this lead so we're going to type return models lead destroy where id is rec params.lead underscore id then redirect back to the landing page because we are going to delete the current lead and everything associated with it including the page that shows the lead so let's type rest.redirect slash leads now let's save this file so let's go to views lead lead.pug let's define a new action here we're going to use a button instead of a link because the default method for accessing a link is a get request but we're interested in doing a post request so i'm going to define a form here action will be slash lead slash lead.id slash delete and method will be post we're going to have a button of type equals submit and we're going to call the button delete let's also create some spacing and we're now ready to run our application let's go back to our terminal the application is running let's make sure we've saved all the files and try let's go to slash leads let's go to the details of the first one we do have a delete button now let's click on it the entry was deleted let's try it again okay this one was also deleted let's take a look at our database activity we're deleting from leads where id is this id this concludes our implementation of the delete routes as usual let's check in the changes we made i'm going to do git add controllers git add routes we hit add views we need comments implement delete route for leads in this tutorial we're going to learn how to implement ajax requests and get started with using javascript in the browser we're going to implement the delete lead functionality using client-side javascript so let's start by defining our routes with router.post slash lead slash lead id delete and we're going to name this as delete json and we're going to define a new handler delete lead json let's save this file and go to controllers landing.js we're going to copy the delete lead handler we created previously and we're going to name it as delete lead underscore json we're still going to destroy a lead using the request parameter lead id but then after that instead of redirecting to the slash leads route we're going to send back a json object and we will do that by typing res.send defining a key msg with the value success now let's save this file and go to view slash landing.pug we're going to implement a button that will invoke the ajax request that will delete the particular lead so let's define a button with the text delete and we're going to define the on click property of the button to call the javascript function delete lead onclick is an event that gets fired in the browser when this button is pressed and by assigning it that handler we make sure that when the button is clicked this javascript function will get called now when we insert inline javascript like this inside pug we surround it with this character called the grave accent which looks like this tilted single quotes we're also interested in passing this lead.id field to the delete lead function but also we want pug to evaluate the value of it and pass the value and in order to do that we type dollar and then curly braces id and we surround the result with single quote character now i know this syntax looks a little bit complicated but this is the best way to add inline javascript in pug also passing variables that need to be evaluated for those who are curious grave accent is this left tilted single quote now for the implementation of delete lead we're going to use the jquery javascript library so i'm going to include that at the bottom of the html page with this single line we're also going to add a javascript file that we are going to define as javascripts slash leads.js so let's save this file and go to javascript leads.js now let's define our delete lead method and go over the details this delete lead function is making an ajax call ajax allows us to make http requests to our web server using javascript also sending and receiving data in form of json objects the key point with ajax is that the requests the web requests happen in the background while you're on the same web page so if you go back to our browser let's assume that i clicked on this delete button and it invoked our function that makes the ajax call that means that we're still going to be on the same page and then this url here is not going to change and the request to our web server and the response will happen in the background now let's take a look at the parameters we passed to this function the url field defines the route that we're going to call and notice how this path matches the route that we've defined for this purpose we have a data type as json and then we typically pass the data payload in this data field and json.stringify function is called to pack the data into a form that's transmittable over the network and then it gets unpacked on the other side using another call that matches this which is json.parse the type of our request is a post request and then we define two functions one for the success case and one for the error case and these get called when we receive a response from the server when we delete the lead from our database using the ajax call we want to reflect that the lead is removed to our user on the browser window as well now recall that we did not navigate from the current url and the ajax call happened in the background for that reason we need to modify the currently served html page we're displaying in the browser we do this dynamically in javascript and delete the html that corresponds to the lead that we've deleted the currently served html document visible in the browser is shortly called as dom which stands for document object model now jquery has convenience functions that help us manipulate the dom such as this remove call in this first part here we're looking for an html element with the id of lead id and then we're making a call to remove to remove it from the currently shown html document now in order for this to work we need to assign the lead id to the particular html element we want to delete so for that let's go to views slash landing.pug to this paragraph element for each paragraph we create for an individual lead we're going to assign it the corresponding lead id now html documents are hierarchical and what that means is that this paragraph is a parent of all of these children that have been nested inside it so if we delete this paragraph element from the html document that effectively means that we're also deleting all the children which includes all the details for that individual lead so we're going to delete this whole thing by simply searching for the paragraph elements with the lead id and then remove it from the html document and that's effectively what this call is doing now a few useful details about jquery when you see a dollar sign like this it means that we're making a call to jquery it just means we're making a library call dollar.ajax means we're calling jquery ajax and this dollar and then the parentheses mean whatever that's inside is going to be handled by jquery the second detail i want to mention is this part here when you use this hash character it means that you're simply searching for an id in the current html document the dom when we do hash plus lead id it means we're searching for the elements with that particular lead id jquery will go and search for every element that has an id property defined which is a fast way of searching for elements in an html document now let's take a look at how our application works let's go to the slash leads route in our browser and click on the delete button on some of these leads as you can see the leads are being deleted from this current html page but let's see what happens in the background so i'm going to open up the javascript console to see if you're getting results so if i open up these result objects i see that the message success has been received from our server each time i delete an object let's try it once more and also let's take a look at what happened on our server side as we are seeing we're doing a post request to the delete json route and also we're able to delete leads from our database let's check in the changes we made i'm going to do git add controllers hit add routes git add views we'll also define a new javascript file so i'm going to do git add public javascripts let's commit this implement lead delete route using ajax in this tutorial we're going to update the looks of our application using the bootstrap css framework so let's open up our browser and search for bootstrap and click on this link and go to getbootstrap.com the easiest way to include bootstrap in our project is to include hosted cdn links of the library in our project files cdn shortly stands for content distribution network and there are third-party hosts for javascript libraries and we will copy and include the links for bootstrap library in our project for that let's go to this link and click on the latest version and click on download and if we scroll below we're going to be given the links to the bootstrap cdn let's copy and paste them in our projects there are also dependencies provided so let's copy and paste them as well now in this tutorial we're also going to learn how to separate our pug files into reusable components and we're going to create a header a navbar and a footer component that we can use across all of our files let's create a new folder under views called common and let's create new files head.pug footer.pug and navbar.pug let's go to head.pug and type mixin head title indent head meta char set equals utf-8 and title equals title pug mixins allow us to define common snippets and include them in multiple pug files we can also pass them parameters such as this title field that gets used as the title of the document let's go back to where we copied the bootstrap stylesheet link cut it and paste it on head.pug and change the syntax to pug which is link open parentheses some properties and then close parentheses we also need to add some standard meta tags in our head section so let's do that as well now let's save this file and go to footer.pug and type mixin footer footer for the time being we're just going to include the javascript files so let's go back to where we copied the bootstrap javascript files cut and paste them on this file we're going to change each script tag syntax to use the pug syntax which is script and then open parentheses some properties and close parentheses let's do this one as well now the order that these libraries are declared matter and bootstrap depends on these other libraries so they need to be declared before the bootstrap declaration so let's go ahead and fix that order we're now ready to include our header and footer in landing that box so let's go there and delete these first few lines and type doctype html html blank equals en and we're now going to include common head.pug and we're going to invoke the mixin by typing head and let's give it a title starter mvp we need to add a body tag and let's indent everything to nest in the body and then at the bottom just before leads.js which depends on jquery i'm going to add the footer include common footer.pug and invoke the footer mixing and we don't need this line anymore because we've declared jquery in footer.pug now let's save this file and reload our landing page we can see now that this is a bootstrap enabled page now the page elements look rather plain because we didn't add any styling yet let's conclude our tutorial by doing some maintenance work the other pug file that we used was lead.pug so let's do the same thing on that file as well we're going to copy and paste this header section we're going to add a body we're going to indent the body to nest it under the body elements and we're going to copy the footer section to be nested inside the body and save it we also are not going to make use of this layout.pug file anymore so we can delete that let's check in all the changes we made i'm going to type git add views common git add views and hit comment add a common header and footer section in all pug files in this tutorial we're going to focus on the user interface and update the looks of our landing page using bootstrap templates let's open up our editor and go to view slash landing.pug now under the body i'm going to copy and paste a bootstrap navbar example that i've prepared earlier this is our navigation bar typically for a functional component of a page like this such as a nav bar we can take a look at an example on the bootstrap website and copy now when we define components in pug the first element you define is the html element and then everything that comes after that separated by a dot are css classes css classes modify the appearance of your html elements so in this navigation bar we're first defining a link and then we're nesting an image in it which is going to serve as our logo and then we have two navigation links nested in an unordered list notice how each html elements has a different css class these are classes defined by the bootstrap framework and available to us one last point here notice how we define these html elements in pug but this line does not contain a beginning html element and that's because this is typically considered to be a div you can type it like this or you can omit it and it will be assumed that the first element is a div element we're also making use of an image asset file for that i copied the file under public slash images slash file name all your assets which are shortly static files that never change in your application are stored under public you can refer to an asset file in html by starting with a slash and then the folder name and then the file name so as the root of your asset path slash refers to your public directory let's try and run our application by reloading our home page now we see a navigation bar two links and a logo now as we did previously i'm going to cut this nav bar from here and place it in a common mixing file so let's go under views slash command slash navbar.pug we created earlier and paste this code we're going to define a new mixin called navbar and currently we're not needing any arguments and i need to indent this by one level under mixing and save the file now let's go back to landing.pug and include our mixin under body we first need to add a header tag include common slash navbar.pug and then plus navbar and let's update the rest of our page using bootstrap html elements i'm going to type container and we create a new row and then inside the row we create a new column and the size of that is six for a medium sized screen we're going to copy and paste a header and a paragraph or two for our value proposition and let's delete these two lines here there were a few css classes that were previously prepared i'm going to copy and paste those and we have a form snippet as well that matches the form we created before copy this portion the contents of the input element and let's delete this part now let's save this file and reload our page now we have a landing page that has an updated look let's go back to landing.pug and we're going to update the portion where we list the set of leads for that i'm going to create a new row and then a column with an md-6 type we're going to indent this portion and i'm going to replace this portion with a table let's go ahead and do that now if we reiterate on this source code if there is a variable called leads we're showing the title leads and then we start a table inside the table under this t-head elements we list the names of the columns for the table we're using the name email for the email field and then the actions under the t-body tag we're listing the rows for the leads so here for each lead in leads we're creating a new row and then we're listing the email for the lead and then a link to the details also the delete button for it notice how we move the lead id as the id property to the table row so that the delete lead call can find which row of the table to delete when it's deleting the lead so as a recap if you go under public javascript leads.js this line will find the right html element and then remove it and in the case of a table this is the table row you can check out the bootstrap documentation on how to build tables like this now i want to make a few fixes on the indentation under this h1 tag we are nesting this table and that's not correct so i'm just going to de-nest it by one level also we want to nest this row under the container tag so let's go ahead and do that that's done let's save this now a few more changes let's go to navbar.pug i want to update the link to the leads route and also let's go to footer.pug remember when adding a dependency for the bootstrap library we added this jquery 3.3.1 and then the slim version turns out the slim version does not have ajax calls so we won't be able to make the ajax call under this delete lead function so i'm going to go back to this and delete this slim portion so we're now referring to the full version of jquery that includes the ajax calls as well we need to delete this integrity hash as well since this was referring to the previous file let's save this and we should now be ready to run our application let's go to our browser and reload the home page and let's click on the leads link and if we go down below we see all the leads listed and let's click one of the delete buttons to delete them before we move on let's check in all the changes we made so i'm going to do git add views common git add views landing dot pug and let's try doing git comments and let's type install bootstrap and update the look of pages while we're at it i want to organize our pages under the lead directory and i want to remove the list of leads from the landing page and create a dedicated page for leads so let's go under lead and create a new file and save it as leads.pug we're going to copy the first portion of our landing page let's just copy this part and paste it here also let's copy the footer part and paste that as well and in this middle section we're going to create a new container and then a column let's copy and paste those these are nested under body and header and let's cut and paste the section for leads we're actually not going to use these two lines in the landing page either so let's delete those save it and under leads i'm going to paste the section we don't need this if leads check because we're already displaying a page and let's save this file now let's go to controllers landing.js once we submit a lead we're redirected to the leads route and once we show the leads instead of using the landing page we're going to use the new page we defined and that'll be under lead slash leads let's save this file and let's go ahead and run our application again if i reload this page i got an error because the head file is located under common and i am one directory level below with the leads.pug file so i need to type dot dot slash for all the common files let's save this file and reload our application again and here we are on the leads page we can now see the leads on a separate web page let's also update the title here to leads and i'm also going to move this lead.pug file under the lead directory so let's just do that move use lead.pug views lead need the pug and i'm also going to update the css classes here to match the ones we use under leads and to use bootstrap so let's copy and paste the code we have for leads.pug into lead.pug and let's take the section that lists the single lead and let's delete the rest assuming that we are going to use a table we can update the contents of the table to match a single lead so instead of having for lead in leads we're just going to access the lead we have let's do this the first field is the email field which is the same here we can change this as edit and then delete and here we're going to have edit plus slash edit and instead of the ajax call we were going to use this form let's copy and paste that and as you might know we're using the button using the bootstrap css classes so let's double check what we're doing the first entry is lead.email and the second entry is the link to slash lead slash lead id and then edit which matches the link we created here and then the last one is a http post when we submit with this button and the path is slashly lead id delete so let's delete this portion and the body let's save this file and let's go to controllers landing.js when we render the lead page that is now located under lead lead let's save this and run our application again so i'm going to go to the browser window if i click on the details now i am seeing the lead page it now has the bootstrap classes and a table we need to redo the same exercise with edit lead.pug although i'm going to copy and paste code i prepared earlier because it's repeating the same exercise so let's delete this html and paste this concludes this part of our tutorial we've migrated all of our pages to bootstrap and also creates the separate leads view file let's check in our changes in this tutorial we're going to develop sign up and login functionality and learn how it all works let's open up our editor and open route index.js we're going to get started by defining the routes for login and sign up so let's type router get slash login we're going to use a new controller called user and we're going to use a handler called show login to show the login page and then we're going to have a router.get for signup and again we're going to use the user controller and type show sign up now let's define our user controller here as well so i'm assuming we're going to define a controller called user under controllers and let's save this file and let's go to controllers create a new file called user.js i'm going to copy and paste code that i prepared earlier nothing much happening here we're simply showing the login page the view is located under user slash login and then we're showing the sign up page with a sign up view under user directory we're also passing two objects to the view file one is form data and the other one is errors we're going to get back to these later on for now let's know that we're simply passing empty objects because these views are located under the user directory let's go ahead under views and create a new folder called user and i'm going to create two new files called login.pug and signup.pug now let's define these pages i'm going to paste some code that i prepared earlier for this nothing much interesting happening here since we covered bootstrap a little bit before but the essence of this page is that we have a form that posts to the signup routes and we're placing two input elements here one is an email and the other is a password and we're submitting them with the submit button and then we have a link at the bottom for the option of going to the login route now let's go to login.pug also i'm going to paste code that i prepared for this it's essentially the same code except we're posting to the login route and we're passing an email and password field as well and the purpose of this page is to log in and then we have two optional links at the bottom one is to reset a password we haven't got a route for that yet and then we can go back to the signup route let's save these files and go to our browser to take a look at how they work so this is how our login page looks and if i click on the signup route this is going to serve as our signup page now is a good time to define our user model and migration of our database so let's go to models and create a new file called user.js since we covered one model definition in detail for lead js before i'm going to paste code that i prepared earlier for the user model definition and let's go over it quickly so we're defining a new user model we're defining an id and then we have several fields of type a string we have a username first name last name password and email now we're not going to make use of these first three fields so we're passing a property along null true so that we can create rows that have null values for these fields and we're essentially going to make use of the password field and the email field and we're also passing the property unique for email as a constraint so that each unique user is distinguished by his or her email address and email is a candidate key for this table now we need to create a database migration that matches this model so let's go to migrations and create a new file and i'm going to name this file with today's date so that it goes in the right order in terms of migrations and comes after the lead table migration let's save this file i'm also going to copy and paste codes to go faster since we've covered a migration example before so as we covered previously the migrations have two methods one is an up method to to move the table definitions into a new form and then a down method that rolls back the change that's being made in this migration we're creating a new table called users and the fields we're creating match the fields we defined in the model nothing surprising or interesting here let's save this file and go to our command line to run this migration i'm going to type sqlize db migrate our migration has succeeded so we have created this table in our database and before we move on let's check in the changes we made so i'm going to type git add views user git add controllers hit add routes and git commit implement get route for login and sign up we're also going to check in the migrations and models so for that let's do git add models and git add migrations and git commits create user model and migration now let's open up our editor and go to routes slash index.js and we're going to define the post routes for login and sign up so let's type router.post slash login user.login router.post signup user.signup now before we move on let's define these controller handlers as well so let's go to controllers users.js and create these two empty handlers sign up and login now we're going to implement the sign up and login routes using a node.js library called passport.js in particular passport.js helps us with implementing authentication as you might guess there are many ways to authenticate your users you could use social networks or other means multiple methods of authentication for us and if you're interested to find out more you can go to passportjs.org for more details now let's go back to our terminal to install the packages we need let's type npm install passport we're going to use an add-on to passport for local authentication to our database so for that let's type passport-local we're going to use a library called bcrypt for encrypting our password and we're going to use the package validator to validate the input we make on login and signup routes we're also going to need to create sessions for our users so let's type express session and finally we're going to display error messages if login or signup fails for any reason and for that we're going to use a package called connect dash flash so let's type dash save and press enter this might take a while because we're installing multiple packages and let's check in the changes we made so i'm going to type git add package.json git add package lock.json and comment express session and connect flash now let's go back to our editor we're going to go to app.js to create an instance of passport so let's type let passport equals require passport we're also going to define the session so let session object equals require express session and let's go down below right after this line we're going to declare app dot use session we need to define a secret parameter for this let's just type our new secret for now and in the second line we're going to type app.use passport.initialize and finally app.use passport.session now each of these calls must be in this given order otherwise your application may not work because when app.js is processed it goes line by line to configure the app instance in a sequential order so that's why we need these three lines in this order now we're interested in setting up passport in a separate file than app.js in order not to clutter app.js with details of passport.js setup so for that before we create the app instance we're going to add one more line here we're going to type require dot slash passport setup and we're going to pass the passport object now let's save this file and create a separate file in our root directory called passport underscore setup.js and save now in passport setup.js we're going to start by defining an empty function that we're exporting from this file and we're passing the passport object to it as you might see here we're also calling the same function with this require statement and we're passing the passport instance we created a few lines earlier so let's go back to passport.setup now passport.js requires us to define a few well-defined api calls to function properly the first function is called serialize user and the second one is called this serialize user this stackoverflow page explains it quite well serialize user is used by passport.js to save a handle to the user object in this case it's the database id for the user it stands saved to a session variable and later on the serialized user will use this handle to retrieve the actual database object for the user user object is then assigned to the user key of the request object so that we can use it in our controllers or routes so let's go back to passport setup.js and define these functions for serialized user we're going to simply use the database id and for the serialized user we're going to query our database we'll pass the id to our user and then we're going to type models user find one where id is the id parameter and then we get the user object back if user is null it means there's an error so we're going to throw on error object wrong user id and else we're going to call done null user with the user object so we're almost done as a recap serialize user function determines which handle to the user object is to be saved in the session and then the serialized user will retrieve the user object using that handle now we need to define a strategy for passport.js to use to authenticate our users when they log into the application because we're going to use email and password as the method for authentication we're going to define what is known as a local strategy for passport to authenticate our users via email and password now let's go ahead and type let local strategy equals require passport local this is where this package comes into play and then we're going to type strategy now we need to tell passport.js that we will be using the local strategy for authentication for that we add a statement passport.use new local strategy local strategy will call its authentication function when there is a login form submitted via a post request so local strategy needs to know which fields in the submission contain the username and password for that there are two optional fields to define these username fields in our case it is called email and password field and in our case it is called password now if you go to login.pug you will see that the first input field is named as email which we will use as the username and the second one is named as password so when the local strategy accesses request body email it will consider that as the username and then when it accesses request body password it will assume that to be the password field now we need to define an authentication function where we access the database and show that there is indeed a user with this email address and the password provided we type function email password and done now this function will authenticate the parameters however we also need the request object here and in order for passport to pass us the request object as the first parameter we need to give it another option called passwreck call back true we're going to use this for error handling later on now let's define our function let's open our curly braces and type return models user find one where the email field is the email parameter and then we will receive a result which let's call as user and if this user is null it means we couldn't find the user so we're going to return an error message incorrect credentials and we need to add return done null false and we're going to type else if user.password is null or user that password is undefined rec flash message you must reset your password these wreck flash messages will be shown in the subsequent re-render of the page and we're also going to type return done null false this is another error case finally else if we're going to define a function that validates the password provided is correct so let's call that valid password we're going to define it shortly we're going to pass the user object and then the password provided in the login form and let's type rec flash message incorrect credentials and this will be entered if the password isn't valid so i'm going to add a not and here we're going to type return done null false so we have handled all the error cases and if we have a valid user we're going to return done null user there may be further errors other than incorrect credentials being provided and we will handle them with this catch statement in the end for example if there was a database error when accessing the user model that will be caught by the statement so we're going to type catch error and done error false now let's save this and let's go ahead and define the valid password function for password validation we need bcrypt library so let's type require decrypt actually for accessing the models the database we also need to define the models variable by typing require dot slash models and we're going to compare the past password versus the one in the database so let's type valid password equals function user password and then return bcrypt compare sync is a decrypt function we will pass the password in the login form versus the user.password field now the passwords contained in our database is a hash of the provided password so that we don't keep them as clear text so this function will also convert the password to a hash and compare the hash value to the one that's being stored in the database this way if the database was compromised the adversaries cannot access the clear text passwords but they only get access to the encrypted versions we're done with the implementation of our first passport login and signup strategy using the local strategy and let's go over the api calls again so we're providing passport with a handle to the user object which is to be saved in this session and then passport.js will use this handle to get the actual user object from the database we also define a local strategy where we tell passport.js what fields to use for the email and password fields when authenticating the user post request during authentication there may be various errors once the database is queried given the email and password fields there may be multiple authentication error cases one of them is that the incorrect username is provided the password field is not present or the password is simply not valid in such cases we return an authentication failed message back to the user in the successful case we pass the user object to the done callback and we also catch database or other internal server errors with a catch statement we use a valid password function call to compare the past clear text password with the hash that's stored in the database we're now ready to check in our changes so let's go back to our terminal and type git add app.js git add passport setup js and git commit a implement passport local alt strategy using email and password fields now that we have set up passport.js we can go ahead and use it in our sign up and login route so let's go and open up controller slash user.js in the signup handler we're going to create a new user by using the user model and then save it to our database so let's type const new user equals models dot user.build email rec body email and password we're going to use a function to generate the hash of the password so let's call this function generate hash and we're going to pass rec body password once we build the user object we're going to save it by typing return new user dot save and this is a promise so we're going to do then results and inside the body of this promise we're going to make a call to passport.js to authenticate the user after signup so let's call passport authenticate local since we are using the local strategy and then we're going to define a redirect route after the authentication so let's type success redirect slash failure redirect which is used upon the passport authenticate call failing we will call slash sign up and we're going to define a flash message failure flash true we're also going to pass the request response and next objects now in order to use the models object we need to first define let's models equals require dot dot models and let's define the generate hash function const generate hash equals function password and in the body we're going to use the bcrypt method hash sync so return be crypt sync decrypt can salt sync 8 and null so generate hash function will take the password and create a salted password what that means is we're going to create a hash of this password and save the hash in the database now let's also define the decrypt object let's be crypt equals require bcrypt let's also define passport equals require passport we also need to set up passport so let's type const my passport equals require dot dot passport setup and we're passing the passport instance we also will need flash so let's type let flash equals require connect flash you might be wondering what's flash stands for flash allows us to display an error message on the page that's going to be rendered so it's a one-time message that we can send to our clients now let's save this file and run our application and verify that the signup works i'm going to run the application go back to the browser and type slash sign up let's type user at email.com and then a password and press sign up now that we've been redirected to the slash route it seems to be working let's go and verify this by going to our terminal here we're inserting a new user to the database with the email that i have just typed we have also started a new session with our application now let's go back to our editor and implement the login route in login route we authenticate a user and initiate a session with our application for that we're going to do the identical action as we did in sign up with passport so i'm going to copy and paste that code the only difference being here is that upon failure we're going to be redirected to the login route let's check the result by going back to our browser and let's type slash login let's type user at email.com and then the password and i'm going to click on login and i'm redirected to the slash route which means the login was successful as well and i've initiated a session with my application now let's go back to our editor routes slash index.js and for completeness we're also going to define a logout route so let's type router.post slash logout user.logout and router.get logout user.logout for both requests we're going to use the same method now let's go back to controller's user.js and define a new method called logout we can destroy our session by making a call to rec logout and rec session dot destroy and we will then redirect the user with rest.redirect back to the root route now it will help us to display these routes as links in our navigation bar also we want to know whether we have a user session or not so let's go to views slash navbar.pug to implement this i'm going to paste the snippet that i prepared earlier here if we are passed a user variable that means we have an active session going on and we display that by showing hello user email on the navbar we also have links to logouts login and signup routes now for this user variable to be passed we need to define it as an input to the navbar mixin so let's type user and save this file and navbar is used from the landing page so let's go to view slash landing.pug and pass the user variable to the navbar mixin let's save this file and now let's go to controllers slash landing.js we're going to pass the user variable to the render function so let's type user rec dot user if you recall passport.js will populate this rec.user field with the user object if there is an active session going on let's go to our browser window to test the login and logout routes let's go to login and type user ads email.com password and login as you can see we have logged in and we can see the user information here and let's click on log out and now the user session is destroyed so we don't see the user email address here anymore now let's go back to our terminal and check in all the changes we made if we type git commit dash a it will include all the files that have been modified let's type implemented sign up login and logout routes using passport.js in this tutorial we're going to learn how to validate form input when a form is posted to our server and how to re-render the page with error messages when there are errors as a recap for how we handle form submissions let's open up our editor and go to routes index.js here we have defined a post request handler for sign up path using this user.signup handler so let's open up that handler by going to controller slash user.js if we look at the signup post handler we see that we create a new user object without validating the input we receive from the form reg body email and recbody password fields are used directly to create the user and save to the database we're going to change that and validate these input fields first before saving the data and for that we're going to define a validator function for our form input so let's get started by installing the validator package by typing npm install validator we are also going to use a package called low dash so let's add that as well and type dash dash save and press enter let's commit our package.json just in case we made any changes so i'm going to type git commit package.json and package log.json okay install validator and lodash now let's go back to our editor and in the root directory my app let's create a new folder called validators and save that and we're going to create a new file called signup.js here let's type let validator equals require validator save that and i'm going to create a local function called validate create user fields function this is going to receive an errors object that is empty and we will populate it as we find errors in each form input field and we're going to receive the form input fields with the rec parameter which is the request object so let's type if validator is email rec body email here this mark stands for not so if this input is not an email then we will populate the errors object with the key email with a message please use a valid email so we're going to go over each input field like this with an if statement so the next one for us is if not validator is ascii we're requiring that we want the password to be made out of ascii characters and we're going to pass the password with rec.body.password if this doesn't hold true then we're going to populate the errors object with the password key to be invalid characters in password please try another one we also want to enforce a password length so let's type if not validator is length track body password here we pass a length range object with minimum of 8 characters and maximum of 25 then again we're going to populate the errors for the password key please ensure that your password has a minimum of 8 characters now we're done with this function because the errors object was passed into this function it will be modified in place so we do not need to return the errors object now other than this basic string validation we need to make sure that there isn't an existing user but the same email as the address provided in this email form field for that we need to query the database so let's define a wrapper function export validate user function pairs rec let's type return models user find one where email is wreck body email and then we are going to get value u if u is not equal to null then we're going to populate the email key of the errors object email is already in use please login or reset your password now i need to introduce you a new concept on program execution when we define the body for validate user where we query the database this is an asynchronous piece of code so it will execute sometime in the future and we will get the results also sometime in the future and this first portion we defined the validate create user fields function is a synchronous piece of code which means each of these statements will execute sequentially now in order to validate the form fields we need both this function which is synchronous and this function which is asynchronous and we need to mix the two together for that we need to use a concept called promise and make the entire body asynchronous we're going to cover promises in the future in more detail but for the time being what you should know as a recap is that this piece of code is asynchronous and this piece is synchronous and in order to make use of both in a single function we need to define a promise which wraps the entire code in an asynchronous body so for that let's type return new promise function resolve reject and we're going to create the promise body let's cut this piece paste it here and indent it inside the promise and let's make a call to validate create user fields errors rec and we will return the errors variable in resolve errors and let's not forget to include the models variable so let's go to the top and type let models equals require dot dot slash models now let's save this file now let's go back to controller slash user.js and import validate user so let's type const validate user equals require dot dot validators slash signup now let's go down to the signup handler and declare a new variable let errors equals an empty object and we're going to call return validate user errors and we're going to pass the rec object that contains the input fields to be validated so let's move on and type then errors which is going to be the result we get from validate user and we're going to check whether the errors variable is populated with any values so let's type if not is empty errors which means the errors object has some values we're going to call a new method rerender sign up and we will re-render the form just as we will render the form for the first time using the show sign-up ender except we're going to display the error messages that we have populated during the validate user call so let's add the errors variable here errors and we're also going to pass the usual wreck res and next objects now this case covers the case where we have errors on the form and we will handle this successful case here as well so let's type else and inside the else body let's cut and paste rest of the code and let's indent it so this means if there is an error we're going to re-render the form and if not we're going to save the data to the database there's one more thing we forgot this is empty function is a call that's been provided by the law dash library we just installed so we need to type const is empty equals require low dash now is a good time to define our rerender signup function it's going to be identical to show sign up with a few differences so let's copy and paste show sign up and we're going to make this a local function so let's type const re render sign up now even though re-render sign up looks like a request handler such as show sign up it's actually just a function call so we're free to modify its function signature with the order of parameters being passed normally in express.js the request handlers have a particular order in their parameters in particular the request response and next objects are passed in that order so we render sign up is called from the sign up handler at this point and we can pass the errors object as its first parameter and we're then going to pass that to the errors key so that errors can be displayed on the form when the page is re-rendered we also have another field called form data and form data is a name that we made up in particular for when there are errors on a form when we re-render that page we use form data to pass back all the input fields that have been modified by the user so that let's say when there are errors the user does not have to re-enter the same information to the other form fields again and again on each time the form is re-rendered so we save the user a time by passing back the data that's been entered already in a previous submission so in order to pass that data back to form data key we are going to use rec dot body if you recall if we go down to the sign up handler when the form is submitted to us we have all the form input fields available to us in rec.body object with the keys corresponding to the input names such as email and password so by passing back rec.body after the submission we are effectively passing back all the input fields that have been submitted to us on the form submission so we're passing rec.body back in form of the key form data now if you recall show sign up is using user slash sign up view and we're using the same view in re-render sign up as well so we're going to modify the sign up view to cater for both cases of the showing the form for the first time and also re-rendering the form with errors and existing form information so let's go ahead and open up views slash user slash signup.pug to modify it and to use form data and errors fields now let's take a look at the first input field with the name email we can pass back existing values on an input field using the value property so here for the value property we're going to type form data dot email we could potentially populate the value property of the password field as well but we're not going to do that as password is a sensitive field so let's add error message information now and let's create a new line under the first input and let's type if errors and errors dot email which is the name for the input field we're going to type p dot small dot text danger these are classes from bootstrap and we're going to finally display the error message errors.email if you recall we create these messages in the validator function let's do the same for the password field so i'm going to create a new line under the password input field and let's type if errors and then errors dot password p dot small dot text danger errors.password now let's save our file and we should be ready to try what we've done so far now let's go back to our browser window and go to the slash signup routes and i'm going to type user at email.com we know that we have a user already with this email address so let's see what happens when we include that and for the password i'm going to type 4 character password which should also trigger an error so if i click on sign up i do get the form re-rendered with the right error messages notice how the validator has both detected that the email is already in use we've done this with the database query and the password length was also detected to be not valid let's check in all the changes we made it add validators we've added a new directory validators and we've implemented error handling and form validation for sign up routes in this tutorial we're going to learn how to implement access control in our application also we will learn the concept of a middleware and how to use it in express.js the problem with our application in its current form is that the leads link here is open to public anybody can click on this link view our links or edit them and we're going to fix that so let's open up our editor and go to routes slash index.js in express.js a significant property of route definitions is that we can introduce a sequence or a chain of function calls before we make a call to the final handler for that route let me show what i mean with an example i'm going to introduce a new call right after the path component called know and place a comma and let's define north with const no equals function rec res next and an empty body as you recall the handlers in express.js have this particular function signature where there is first a rec object and then a res object and the next object and we've never made use of this next object here so we're going to make a call to next and leave it at that what this does is that when the slash leads path is matched the first function to be called is going to be know and no op will transfer execution to the next one in line which is show leads and the way we do that is by making a call to next i could potentially add additional know up calls here and it will be all the same because no op does nothing but transfer the control of execution to the next one in line in a route definition we have the capability to add as many calls as we need to any separate handlers before we call the final handler and this gives us a lot of flexibility for adding additional functionality to each route and we're going to see one example shortly before we move on i want to demonstrate you that these no op calls indeed have no effect and we are able to call show leads as normal so let's go to our browser window and click on the leads link and we're still able to see the leads as usual now let's go back to our editor window if you notice these knob calls are in the middle when handling the request for this route that's why they're called middleware middleware may sound like a grand term that does something complex but a middleware can merely be a simple function call such as this knob function and let's remember that in a middleware function we always need to make a call to next in order to proceed the execution to the next one in line and make sure that the final handler gets called now we're going to define a really basic middleware first let's delete the snob call and delete these calls in the middle and let's create a new folder called middleware in our root directory and we're going to create a new file called has auth.js let's type let create error equals require http errors create error function allows us to create an error object with an error message and we've already made use of this in app.js and it comes as standard with the vodila express.js installation so let's go back so let's define a new method exports is logged in equals function rec res next if rec.user then we will call next the presence of rek.user means that passport.js has authenticated the user there's a session and there's a logged in user who is requesting the page so we're allowed to go to the next step of handling that page and else we're going to create the error create error 404 and we're going to give the message page does not exist now there's one thing i need to mention about how this next works in the successful case we're calling next to move on to the next handler but in the error case we're also calling next so how come we're showing an error message when we call next which should normally call the next handler for this route well the answer is in the express documentation if you pass anything to next function express regards the current request as being an error and it will skip any remaining non-error handling routing and middleware functions what that means is we're going to skip all the route handlers that are coming next and we will go straight to our error handler using the object we're passing here and that error handler is in app.js if you scroll down below you will see this error handler already defined for us when we pass an object then that means that this error variable will have that object being passed from next and we're going to display an error message and render the error page so that describes how next will work in both cases of a success and error let's save this file and go to index.js under routes folder and we're going to import this function we have just defined so let's type let is logged in equals require dot dot middleware slash has auth.js and we're going to use it's logged in in the leads route as our middleware so let's type is logged in and then a comma let's save this file and try our application again so i'm logged out so and i'm going to reload this page and i'm going to click on leads let's see what happens indeed our middleware has found that the page does not exist and generated a 404 error while we are at it i want to beautify our error page as well so let's go back to our editor and open up views slash error.pug and i'm going to copy and paste code that i prepared earlier for this we're using a few bootstrap classes let's save and reload this page now this looks better just to note we're able to see exactly what happened in the application and that's because the application is running in debug mode if we were running in the production mode we wouldn't see this error stack now just to demonstrate you the other case let's go back to the landing page and log in i'm going to type user at email.com and sign in now if i click on leads i'm able to still see the leads now every user has access to our leads table so we're going to take our access control concept a little further and only allow a particular user to have access to these pages so let's go back to our editor and create a new migration under migrations let's create a new file with today's date we're going to add a new field called is admin to the users table i'm going to copy and paste code that i prepared for this earlier and let's go over it quickly so what we're doing here is creating an easy admin field which is a boolean and when it's true we will consider the user as an admin of our application and here we have the up method for the migration where we add the column to our table and the down method which will remove this column from our table called users let's save this file and go back to our terminal and type sqlize db migrate so we've successfully migrated our table and added an ease admin boolean field to our users table now let's go back to our editor i'm going to make a modification in the way we create new users let's go to controller slash user.js and the signup handler now if there are no users in our application with an admin flag as true we're going to create the next user as an admin and for that i'm going to modify the sign up handler let's type return models user find one where is admin is true then user and if user exists that means user not equal to null then we're going to craft the user row as normal so let's cut and paste the way we create the first user and else we're going to create the user with the field is admin equals true and for this to work we need to first declare new user outside use the new user variable and finally we're going to save the user back to our database so let's place this after the else statement let's save this file and check that our application is running correctly what we haven't done is update our model under models with the is admin field so let's create an is admin field under here at the bottom i'm going to copy and paste code that i prepared for this earlier so ease admin is a boolean and we allow it to be null because the existing users won't have this field set let's save our model file and go back to our browser and let's sign up as a new user and i'm going to type a password for that and press sign up now we have admin at email.com signed in and let's go back to our terminal to verify that this user was indeed created with is admin as true insert into users first second third and fourth field is is admin and i can confirm that admin at email.com is confirmed as an admin in our application now we're ready to implement the is admin check in our middleware so let's go back to our editor and go to middleware has alt dot js and i'm going to define a new function here exports dot has auth equals function request next and if rec user is not null and and rec user dot is admin is true then we're going to call next as usual and allow access and else we're going to create an error as before next create error 404 page does not exist let's save this and let's go back to routes slash index.js to import this new method as auth and we're going to replace the is logged in middleware with this one so let's type as off and save this and open up our browser and let's reload this page and i have the leads link here if i click on this link i'm still able to see the leads and i'm going to log out now and log in as another user that i just signed up as which is no admin at email.com and login and if i now click on the leads link i'm redirected to the page does not exist error page so this effectively demonstrates our use of the has out middleware in order to control access to certain pages on our application we now want to extend this to other routes where the leads are edited and accessed so we're going to add the has out middleware to other routes as well so let's type has alt for show lead as out for the edit lead and the rest now all of our routes are protected by the has out middleware except the first one which is for visitors and the landing page now let's check in our changes let's type git add middleware git add migrations git commit a and implement has auth middleware and is admin flag lead routes are protected by as auth and only the admin user has access to them i hope you enjoyed these tutorials my name is bahadur i'm a systems software engineer my background is in low level software and operating systems if you enjoy these tutorials and want to be notified of similar content in the future you can go to this website and join our community here if you scroll down below you will see a button to join it's free thank you for watching these tutorials and i hope to see you in another tutorial in the future youhi in this tutorial i'm going to show you how to develop a web application using node.js and the express.js web framework we will then deploy our application to aws using elastic pinstalk environment we will develop a landing page where we collect and manage sales leads you can freely use the resulting source code as a starting point to develop your product and we will cover all of the concepts that you need to know to build a fully fledged web application using node.js we assume intermediate programming knowledge but no background in web application development or not js okay let's get started so a little bit of background on node.js many years back developer ryan doll explored the idea of using javascript for server-side programming with the main motivation that existing http servers could not handle lots of simultaneous connections efficiently meanwhile also google's chrome browser team developed a new javascript engine from scratch called v8 and the unique property of v8 is that it was built to be much much faster in interpreting and running javascript compared to the other browsers and nodejs took google's optimize v8 javascript engine for server-side programming also creating a setup that allowed for much more scalable handling of requests and also a package manager for managing the open source javascript libraries was introduced called npm and node.js was worn now before we install node.js we're going to start by installing a script called nvm so go ahead and type nvm in your browser and click on this link and vm is short for node version manager it's a script to manage multiple active node.js versions on a single computer so let's go ahead and scroll down to copy and paste the install script for nvm and we'll paste it on our terminal now i already had nvm installed so this step may take a little longer in your case and what you need to do is close and reopen your terminal so that the nvm script can initialize while your terminal starts you can check that your installation was successful by typing nvm version we're now ready to install node.js so let's go back to nodejs.org we're interested in the long term support version of node.js and as of this video it is 10.15.0 is the version that we need so we go back to our terminal and type nvm install 10.15.0 now this step may take you a little bit longer you should have now node.js installed and being actively used just for the sake of showing you how it works you can also install other node.js versions let's go for 8.11.3 for example and you can switch between node.js versions by typing nvm use so let's switch back to using node.js 10.15.0 now for our application we're going to use express.js so let's go ahead and visit express.js express.js is a web framework and the power of it is in its simplicity you can develop very complex web applications yet it is a minimalist web framework that is very easy to grasp and this is the install command for express.js but we're going to use another tool called the express generator that will give us a good starting point and a directory structure so let's go ahead and copy and paste this command in our directory to install express generator now here in this command npm as i mentioned is the node package manager we will use this to install packages and here the dash g stands for a global install which means the installation is going to happen the computer-wide and not just one particular project so i'm going to press enter now and now we can go ahead and run express generator to generate our application and a useful directory structure so i'm going to copy paste this command here dash dash view equals pug means we're going to use pug as our html templating engine so i'm just going to press enter and we have now created a directory structure for our application now that we have generated a skeleton directory structure for our application i want to go over each folder we created so let's go ahead and start our text editor and let's take a look so under my app the public folder contains our assets assets are static files that your html files makes references to each html file will refer to certain images such as logos and some javascript files that need to be run on that webpage or style sheets that describe the style on a web page the rouse folder contains the router logic we will get to routers in a little bit and it's one of the key parts of our application and finally views contain the representation of each individual html page in our application notice that these are named pug files each of them get converted to separate html page the bin www file contains the initialization script for our web server and one of the notable files is app.js this is the main entry point for our entire web application and also we have the package.json file which is a recipe that contains the list of open source packages we need to install to run our application now let's go ahead and install these packages and run our application as it is so we go back to our terminal cd my app and we type npm install we're pulling and installing all those packages this file contains not just the packages that we need but also npm allows us to fetch all the dependencies that these packages have and now in order to run our application we need to type this command and once i press enter the web server is running on port 3000 and when i visit localhost 3000 on my browser i get to see this web page served if we go back to our source code app.js is the most important file that we care about app.js defines our web application and node.js express.js applications are monolithic meaning that every piece gets put together into a single application and let's see how that works we first import modules using the require statements and typically these modules are those ones that we find under the package.json file these modules here you will see that they have been imported and assigned to variable instances the one we're interested in is this express variable as you see the required statements includes the express package assigns it to a variable and then later on we call the constructor for express and assign the result to a variable called app an app is an instance of an express application typically this is a vanilla instance and then we make certain method calls to modify and configure our application and also use and include other modules here we first set that the views are included in a directory called views this is what this line does and we have as you can see a fuse directory here and next we set that we you are going to use pug as our view engine so the app instance that is unmodified and new gets modified by these set calls and then we have certain use method calls where we define further configuration and further components that we're going to use and one of the notable ones is the index router object that we have defined in this project if you go up here we use the require statement to include an index.js under the routes directory whatever that has been exported from this index.js file is assigned to an index router variable and this instance is then used for the path that is slash so this line means that our application is going to use index router for the slash route and that's how we also connect pieces of our application into one monolithic instance because index router was defined here under index.js and it has been included from app.js let's take a look at how the route object is defined if we go under routes and index.js again we are requiring the express package we have a variable called express and then we call a router to create an instance of an express router and just as we did here the router instance here is a vanilla instance it hasn't been modified and then we make some certain method calls to define it further in this particular case we're defining a get method and how to handle this slash path with a function and then we export the router instance that we have created to be included by another module and app.js includes that router here and that's how we connect it and the router object to recap is a vanilla instance then we make some modifications on it and then we export it and this pattern is used throughout the application this is how you divide your application into separate instances now let's take a look at what a route handler is and how it works here we have a router variable that is an instance of an express router and this router variable has several components that we care about the first one is that we're making a call to get and this defines that the route handler is associated with the get http method and then the second component we're interested in is the path so typically a router will match a particular path used in a url and then finally there is a handler that gets called if a path is matched to look at it more closely if this is our url the first section defines the protocol being used and the second one is the domain and then finally after the slash here we have a path component so a router object will look at this path and see if it is a match for the path that it has in its own definition finally the router will call the handler that's associated with it the last bit of detail here is that the get method here is defining the http method that this route handler is limited to it only responds to this get method if there are no routes that match for a given path or http method our application generates a 404 error which means not found so as a recap under routes index.js we're creating an express instance and then we're calling express.router to create a router instance and on this router we're defining that for the http get method if we are looking for the path slash and it gets matched we call this function as our handler for this route and under app.js we have an index router representing our exports from routes slash index file and then we have this statement here app.use and for the slash path we're using index router effectively meaning that when we type this root path with no slash or slash it means the same thing essentially and when we press enter we call the route handler that's defined here which renders our index page and that's how essentially our route handler works before we dive into source code and define routes and handlers let's cover what an http request is and how a request sequence works the http short for hypertext transfer protocol defines multiple methods for browsers to communicate with web servers and the http methods allow the browser to take different actions the get method simply fetches a resource from the web server such as a web page when we make an http get request the server typically responds with a resource such as a json object or an html file and in our current scenario we are interested in sending back an html web page and we use the express js specific method called res.render a restart render will generate an html page and our web server will respond back to the browser request with a web page and the other method we're interested in is called http post this is typically used for submitting data to a web server when you fill out a form on a web page and you press the submit button the data is sent to the web server and typically an http post method is used there are multiple http methods and what method is to be used is defined in the form definition on that particular html page but most of the time and almost always a post request is used and once the server receives the post request it does something with the sent data such as updating a database and then the server typically calls the res.redirect method again this is specific to express.js to redirect the browser to another url or path so the server responds with a redirect after processing the data back to the browser and finally the browser will do another http get request as a third step fetching the route that it has been redirected to now there are a few more http methods but this gives you the foundation for developing a rich web application now you know enough to develop routes route handlers and develop your application one of the issues with our route handler is that the logic that matches a url pattern is here but also the handler function the handler logic itself is defined as part of the root handler and what we want to do is separate these two so that we have a modular approach so we go to our terminal and i'm going to create a directory called controllers controllers essentially are a collection of root handlers i'm going to copy this function from here and place it under controllers in a new file save it here and give it a name called index and save it with the name index.js and if i go back to the routes and define index as an instance of what we have exported from our controllers index.js file i can now refer to the handler that i've defined from this route file so if i go back to controllers as a recap we have an index.js and we have a method called index that we're exporting as our handler and under our routes let's save this file again and under our routes we are importing it as a variable instance called index and we're assigning the index handler for this route let's now save our application restart it and see if it will work so i'm restarting the application and typing this url and it's working so controllers allow us to separate handler logic as you see in this example from the root handler logic and we're going to build many more of these controllers now let's take a closer look at what our controller function does so if we go under controllers index.js we named our function as index and the only call it has is to a call called res.render the resident render call renders an html page from a template the first argument is the name of the template file which is index if you see under views directory we have a file called index.pug and the second argument is a javascript object with a key value pair the key is title and the value is express now under app.js we did define our view engine as pug and we did define that the views are located under the views directory so express.js knows where to search as the starting point for view files so when we pass index as the first argument it will go and look at the views directory and find that there is an index.pug file here and then pug will convert this template into a real html if we look at this second parameter again title colon express we also pass this as a parameter to pug so if you look at index.pug it will use the variable and replace it with its value there are two cases where the value is being used here we'll get to this when we look at pug in more detail but essentially our controller function simply renders an html page it responds with a html page back to the requesting browser now is a good time to use version control and checking all the files that we have created so i'm assuming that you've installed git and i'm going to initialize a git repository here by typing git init db now we've initialized the repository and you can check that we have created a dot git file in the current directory that stores all the files by our git repository and now i'm going to check in all the files but before i do that i need to create a file called git ignore under my app let's create that file and type node modules in it because node modules are installed open source files they're not part of our project and git ignore file having node modules will exclude those files all of these files from our version control typically any file that gets auto generated or external to your repository you should exclude by using a git ignore file okay going back to the terminal i'm going to make my first comments by typing git add dot dots here representing the current directory so i'm going to add all the files in my current directory to the git index and commit them by typing git commits dash a meaning commit everything that is in the index to git so as you can see we have a bunch of files being committed and we're also including the get ignore file so let's type initial comment and save and exit and we have essentially committed our first change to our git repository to get the full source code for the tutorials if you go to this website and scroll below you will see posts with programming snippets as well as the link to the source code for those tutorials and if you have questions you can click on this button on the same page become a member it's free and then you'll be able to add comments to tutorials and get answers now one of the problems we have is that every time we make a modification in one of our source files we need to restart our web server because the changes made to source files are not being recognized and in order to remedy this problem there is a tool called node mount that we are going to install so i'm going to stop our web server and i'm going to install nodemon by typing npm install nodemon and then also typing save dash dev what this does is the save dev will save nodemon as a developer dependency meaning that we only need to install it when we are developing our application so if we go under package.json we now see that nodemon is a developer dependency and now we need to modify this line so that in the case of an environment where we're in production we're still using the standard node command but in case of development we're going to run nodemon instead that monitors for changes in source files and restarts our web server so for the start scripts i'm going to go ahead and type if the environment is production then we use node.bin www else we use nodemon bin www and then fi now this should work and we are going to use nodemon to monitor our web server so let's go ahead and try running this okay as you can see nodemon has started and when we make any source code changes it's going to automatically restart our web server now is a good time to make a git commits because we've installed node mode so i'm going to do git add package.json and then git commit dash m install nodemon now i'm going to cover the most common web application development pattern where we are going to build a landing page with various routes to collect sales leads manage them view them and delete them and edit them let's go ahead and rename the variable index as landing because we're going to build the landing page and our controller is going to be called landing and we're going to name our first method that gets our landing page as get landing so if we go we save this file and go to controllers index.js let's let's rename this file as landing.js and first function is going to be get landing and also let's rename the view now when we fetch this file we're going to display a form where if a visitor likes our service or our value proposition they will enter their email address and send us that information in a form so i go under views landing that pug and right below this paragraph i'm going to design a form the the form element takes one parameter called the action when we submit the form which path we're going to use is defined by action so i put a comma and for the second parameter i'm going to use the method called post when you submit a form the method that has been defined in the form is the one that the browser will use for making the request so we're interested in using the post method and i'm going to define an input element of type email and we're going to use a placeholder let's write here enter your email address notice how there is an indentation here pug nests html elements by using indentation so inside form we have nested an input and also typically we want to nest a button inside a form so that the button is associated with that form so i'm going to define a button elements of type submits when this is a submit button that indicates that we're going to submit the form that the button is nested in we're going to use a name for the button called submit and i'm going to now save this form let's make sure all of the files are saved and if i now restart my application i should see the form being served if i press enter here right so we have this enter your email address form with an input and then a submit button we're also going to commit our changes by typing git add because we renamed some files we need to explicitly add let's do git add views git add controllers let's see if we have captured all the files i do git commit dash a to commit all the changes landing.pog has been registered as a new file and so is controller landing.js but we missed views landing that box so i'm going to explicitly add that file landing.pug okay now if i commit we should be covered with all the files that we have renamed and added in git so i'm going to write a commit message landing page getting started and first form typically in git you first summarize your change in a single line and then you would leave an empty space and then include further information in the second paragraph but at this point we don't need to mention much i'm just going to leave it at the first line now that we have defined this form we're going to develop our first post route so i go to routes index.js and include a new router with the post http method and then i'm going to use a new handler called landing.submit lead because we're looking for sales leads it is called submit lead i'm going to save this file go to the controllers landing.js i'm just going to copy and paste this first handler that we had and i'm going to name the second one as submit lead when we submit our form from landing.pug there is this input element we forgot to name it so i'm going to define a name for it called lead email when the form is submitted from that browser we're going to be able to access the value inside this input element with the name lead email by going to our controller let's delete this statement here we're going to print out the input element that we have received lead email and the way we do that is by using the body parser library we are going to do rec dot body lead email to print out the value i believe i need to include the package called body parser in app.js for this to work but it turns out express.js already includes this functionality this allows us to retrieve the values for input elements when there is a handler for a post request if we simply do rec.body.lead email we're going to be able to access the value inside the input element now this handler is successfully reading this data but we can't leave it at that we need to conclude the request so we're going to do a res that's redirect and we're going to use the original path of slash so that we go back to the uh landing page for now so i'm going to save this and we're already running the application let's see what happens if we submit an email address here my email at domain.com so i'm going to press submit as you can see the browser was redirected to the same page but let's see what happened in our console we were able to receive the value and print it let's check in all the changes we made so let's go to our terminal and type git add controllers landing.js git add routes index.js and we also modified our view file so we're going to do git add views landing.pug and comment landing page post route to submit email so we're able to receive data in our application but we're not able to do much with it so we're going to install a database an sql database a particular postgres database for our application go ahead and open up your browser and type homebrew homebrew is a package manager for mac os and one of the packages maintained is the postgresql package so you can copy and paste this installation script on your terminal if you're on a mac os to install homebrew let's go ahead and just do that and it's going to install a command line tool called brew which will allow you to then install various packages including a postgresql now i have it already installed so i'm going to skip this step and assuming you have installed this we can then install postgres by typing brew install postgresql so after you've done that you can start your database by typing brew services start postgres ql this is going to start the postgres process in the background on your machine so that you can connect to it and create databases manipulate tables do things with it so i've already run this command so i already have my database running we're going to use a tool called psql to connect to our database and make some changes so i'm going to type psql postgres to connect and if everything goes well you should see the postgresql prompt and now we're ready to create our database first we create a user that can access that database by typing create role express mvp db user i'm assuming here that i'm going to use the name express mvp for our application so i'm just adding a db user for that and with login password let's make the password simple for now and press enter and now i'm going to create our database by typing create database express mvp db in case you want to delete these roles or databases and redo the same commands you can do that by typing a drop database or drop role so we're now ready with our database i'm going to quit psql by doing the control d we're done with our database setup now we're interested in using a library for accessing our database from javascript and manipulating data and for this we're going to use an object relational mapper library shortly called an orm we picked sqlize as our choice of orm if you go ahead and type sqlize in your browser you're going to find a website for it as sqlize is a stable and popular orm for node.js and it will work well for most of our needs and rm greatly simplifies the type of queries you have to write for manipulating database tables and rows instead of typing long error prone sql queries and rm lets you generate those queries by writing javascript okay so let's go ahead and open up our terminal again and type npm install sqlize this will install sqlize as a package i recommend doing dash dash save so that it's saved to our package.json file we're also interested in the database driver library in node.js for postgresql which is simply called pg so i'm going to go ahead and type npm install pg save as well sqlize will invoke pg in order to access the postgresql database this is a low level library for accessing postgresql databases the other tool that we need is a command line tool for sqlize called sqlize cli so i'm going to install that as well by typing npm install sqlize cli and i'm going to use dash g so that concludes our installation for postgres and sqlize now we're going to create some configuration files so that our application and sqlize can access our database and for that we're going to use the tool a sqlize cli but before we start we need to first create a configuration file for sqlize cli so that the default paths we use are going to be defined let's go ahead and create a file called dot sqlize rc in the root of our project typing a touch dot sqlize rc and let's open up our editor when we open a sqlize rc we see certain paths defined let's remove the db path and let's keep it empty for now we want to create these directories directly under our application root folder so that they're accessible easier with one less step so let's go ahead and save this file and now we're ready to generate some files so i'm going to by sqlize init and we have created several folders the config config.js is the one we're interested in this is defines the database details let's open up our editor again and go to config config.js we have three environments defined here one for development test and also one for production so i'm going to type here module that exports equals and for developments we defined the database username as express mvp dash db user as our password we defined 123.456 and for our database these are the users and database we created using the psql command previously so we're going to type express mvp db and our host is 12701 this stands for the localhost the database we're using is postgres so we're going to use the dialect postgres here there's one more parameter missing here the port parameter typically for a postgres database that is a 5432 i'm currently not going to touch the other environments and going to save this one here so we should be now ready to access our database from sqlize using our application now i'm going to go back to the terminal to commit some of the changes that we made so far we installed sqlize and the pg library so we've modified our package.json file let's go ahead and create a comment for that change we have added sqlize and pg packages and i'm going to save this comment we've also defined a sqlize.rc file so i'm going to add that one as well and commit this change configuration file for sqlize cli and i've also created a configuration file for our database connection so i'm going to commit this file with git add config config.js there's also one more file that i'd like to introduce to you briefly under models when we ran sqlize in it we defined the file called index.js this will initialize sqlize when we run our application it takes the environment that we defined under config.js and then creates a new sqlize instance using the database credentials that we have created so this is the initialization file that was auto generated when we typed sqlize init so i'm going to check this file in as well and the file name is always index.js under models and this is a specific file just for initializing sqlite so i'm going to commit these changes so we added configuration file for sqlize and the script as a recap for where we've left off we can visit our landing page and then submit an email address to our application and display the email address collected as a console log now that we have installed our database and installed sqlize orm and configured it we're ready to define our first model as well as the first migration so let's go ahead into our text editor and create a new folder called migrations and let's create a new file under the models directory named lead.js since we're collecting sales leads our table and model will be named leads migrations allow us to create recipes to take our database state the database definition from point a to point b for example right now we have no tables in our database even though it has been created and with a migration recipe we will be able to create our first table that represents our sales leads and we will run that migration to create our first table and start accessing it and the model definition is used by sqlize to create to generate the methods for accessing the table and to update the table to take database actions on the table such as creating rows deleting rows updating rows and fields and in contrast migrations are used for manipulating the database table definitions themselves such as creating a table adding a new column or changing the type of the column in that table the migration file that we're going to create is highly specific to sqlize sqlize has low level methods for accessing and manipulating a postgresql database but the migration itself is a file a recipe that's specific to sqlize and so is the model that we're going to define so let's go ahead and create a new migration file and let's define our first table i'm going to copy and paste this code that i have already prepared as our first migration let's first save this file migrations are a sequential in the sense that they need to be run in order they don't make sense if they are run without an order so we need to order them by the file name and we do that by including a date starting with the year a month and the hour and even the minutes when the migration is created so as of now we're in january 4th 2019 so i'm going to name my migration as 2019 0 1 0 4 and then the hour is 19 17 and i'm going to include the action that this migration is going to take which is creating a table named lead so create lead table and then finally that's a js here is our first migration saved and the migrations are bi-directional so you can apply a migration represented by the up method and then you can roll back a migration by using a down method so in this case the up method stands for creating a new table called leads with so and so fields and then the down method or action represents dropping the table will effectively cause the table to be deleted from our database now if you look at the fields that are being generated we first obviously have an id field and id represents a unique column in our database and it's represented by universally unique id type and sqlize has that type built in for us and typically we need a created ad and update that field for each row when a new row is created this date will be relevant and each time a row is updated this second field updated at is going to be irrelevant and finally the actual field the data that we were collecting in our application is an email address so we're including a field called email of type sqlize string so we have saved this migration we can go ahead and run it by typing sqlize db migrate the command has succeeded which means we have created a table called leads in our database now we need to define the sqlize model definition for the table we just created so let's open our editor and create a new file under models called lead.js i'm going to copy and paste the definition that i created earlier for this this javascript model file is specific to sqlize sqlize will generate the methods it needs to access the database table by using this model definition we define an id field in the model which is a primary key and then we define an email field as well which is of type string notice how these fields match the migration we just ran for the leads table and we omitted the created that and updated that fields in the model because sqlize assumes they always exist when we run the application sqlize will run models index.js if you look at this for each section it will go over each model definition under the models directory to import and use for accessing the respective database tables under models directory for each database table we define a model such as the one we created for lead.js for the leads table and sqlize will go over each of those to generate the methods so that it can access those tables in order to achieve this we need to go to the initialization file bin slash www and here initialize sqlize for that we need to first create a variable called models and import the models directory and these three lines start our server listening on a particular report we're going to modify this code a little bit and we're going to type return models.sequalize sync and then result going to cut and paste this portion inside the body of this call okay we're now ready to further develop our application and run sqlize queries before we go any further let's check in the files that we have just created so i'm going to add the migration we created and commit this file create migration for leads table for creating leads table i'm going to check in the model as well it's add models lead.js we're also going to check in the changes we made on the initialization file bin slash www initialize sqlize in bmw now that we have a database set up we can implement the post route where we will save an email address to our database so let's go and open up our editor and go to controller slash landing.js we're going to modify the submit lead handler to save the email address collected to our database so let's go to the top and then type const models equals require dot dot slash models models gives us access to the sqlize methods for the models that we have defined and i'm going to type return models that lead that create note that create is a sqlize method and for the email field we're going to use the value we've obtained from reg body lead email then take the results and redirect back to the landing page and let's delete this last line and the first line save and rerun our application if i go back to the landing page and type an email address here username at email.com and submit notice that the browser reloaded the landing page and that's because of the res redirect here and i'm assuming that the create call has succeeded if you go back to our terminal we see this sql statement here generated by sqlize run by sqlize we're inserting a new row into the leads table particularly the id email created that and updated that fields new a unique id for the role and then the email address we just submitted and then the dates so we've successfully saved the email address in our database let's commit the changes we made so i'm going to type git add controllers landing js and then commit the change save leads collected on landing page we save email addresses collected back to the database we're going to implement the most common web development pattern shortly known as crud which stands for create update and delete we've already done the creation of leads with this route and now we're going to define new routes that allow us to do listing editing updating and deleting of leads so and the first one we will cover is for listing delete so let's define a new route with the path slash leads and the handler called as show leads and let's save this file and let's go to controllers landing.js to define our new handler let's copy and paste the first one we created let's name it as show leads now all we need to do is fetch the leads from the database and for that we're going to call models lead dot find all and then we will be returned an object let's name it as leads and let's cut this line with the res render and paste it inside the body here a few things to note this call here is a promise and we're going to cover promises in detail later but for now what you need to know is that this call is going to execute asynchronously and the then here ensures that the results within this body are available after the execution of this call has completed so there's a guarantee that this body is going to be available after this execution even though the call is asynchronous and we'll get to those later and the file all method is defined by sqlize and also the leads object here contains the rows returned from the database and also the methods to access those rows so as you can recall the render method the second parameter is an object passed to our view file we're going to define a new key here called leads and assign it the value of our object leads and save this file and one more thing to note is that this view file usually typically we use a different view file for each purpose but for the time being we're going to use the same landing view file to also show the collection of leads now let's go to viewslanding.pug we're going to type if leads pug will check that if the leads variable is non-zero it's going to include the rest of the html snippets let's type if leads and then let's define a header here called with the text leads plug also has the capability of iteration we're going to do for lead in leads note that leads is an array of objects of type elite we're going to create a paragraph and type lead.email now pug considers that anything of that comes after the p is text we don't want to display this as text and we want to use the pug way of syntax of dereferencing this variable which we used here by typing hash open curly brackets and then close curly brackets so let's save this landing file and go to our terminal our application is still running so let's go to our browser and type localhost 3000 there's one more thing we want to do let's go back to the landing.js controller now instead of redirecting to the slash route we actually want to go to the leads route when we submit a new lead so that's the change we make so that the this new route that we defined is going to be triggered which we'll call this show leads function okay so if we go back to our browser let me submit a new email address lead one email.com and when i submit this i see the list of leads on the same page and notice how the browser went to the slash leads routes because of the change we just made so let's check in the changes we made so i'm going to do git add controllers landing.js git add route index.js and add views landing.pug implement leads routes show a collection of leads upon submission now we want to take a look at the details of each individual lead so let's define a new route called slash lead slash colon lead underscore id and let's define a handler landing that show underscore lead now two interesting things here firstly we defined slash lead slash as a unique path component to match individual leads and notice how this path is unique and different than the other routes we defined we will handle all details of an individual lead under slash lead slash path component which gives us sort of a namespace to work on individual leads the colon here defines lead id as a parameter as a request parameter that means whatever that comes in the url you type in the browser after slash lead slash is going to be captured in a request parameter named lead underscore id and we can then access the value of this parameter in the root antler show lead now let's go to controllers landing.js and copy and paste one of the handlers we already have let's name it as show lead and what we need to do now is query the database for a lead with a given id so i need to do return models.lead.find1 and then the where clause helps us query for a particular field and we're going to use the id field and we're going to pass the request parameter that we received named as lead id to find the particular the lead record in the database corresponding to our lead now this will return a lead value let's go ahead and delete this portion and here we're going to do res render we're going to define a new view file called lead and pass an object with key lead assigning it the database object that we received now let's save this file and go ahead and create a new file under reviews called lead let's copy the initial portion of landing that bug and let's define an h1 lead header and let's simply define a paragraph with the lead information lead.email now let's go to landing.pug we want to give the user an opportunity to click on a link that takes us to the individual details page for that link and we don't have that link here so i'm going to add that to this paragraph but i would like to display both the lead email and also that link on a single line the same line so i'm going to nest the link and the email under the same paragraph as a reminder we nest html elements with indentation in pug so i'm going to first define under the paragraph a span elements that will display our email and also um this character that i'm typing is used for text and also to display spaces in park so i'm going to include one space character and define our link with the anchor tag with an href property of slash lead slash and now here we already have access to the lead object that has been obtained from the database so we can include the id of the lead here by typing lead.id and we are going to use the text details in the link so now this link is going to point at the path slash lead slash plus the database id of the lead so let's save this and run our application everything seems to work fine so let's open up our browser type localhost 3000 let's submit a new lead new leads at domain.com and see that we're able to display both the leads and also the details link for those leads i'm going to click one of them we're now navigated to that path and we're able to display the lead information now let's check in all the changes we made it add views it adds controllers and routes and then if we commit now add a new route to display lead details let's go back to routes slash index.js and we're now going to define the routes for editing individual leads so let's type router that gets slash lead slash colon lead underscore id and we're going to define a new action for this particular lead id which is going to be slash edit and we're going to define a new handler with landing dot show edit lead now this is a gate route which means that we're going to fetch a new web page for the purpose of editing the lead id so we're going to deliver a form that contains information about this lead id by using the show edit lead handler and let's type router.post slash lead slash colon leads id slash edits and define a new handler called edit underscore lead here the first route we defined shows the form for editing the lead id and the second route we defined which is a post submits the form to edit the lead id now there's one key point here we are highly interested in defining the same path component for the get and the post routes and this is because on an error when we handle the post request if we re-render the same page we want the url in the browser to match the original get request we're going to go into more detail about this when we cover error handling now let's get started by creating the link that will take us to the edit route for the lead for that let's open up views lead.pug now we're going to modify this by creating a span under the paragraph and we're also going to create a link an anchor tag with an href of slash lead slash plus lead.id remember that we have the lead database object available to us so we can reference its id and also we're going to add the slash edit path for editing the lead now let's write edits for this link and save this file and notice how the value of this hf property corresponds to the get route we defined here now let's define the handler for this show edit lead route by going to controllers and landing.js and let's copy and paste one of the handlers here and call it show edit underscore lead now this handler also obtains one lead record from the database by using the lead id parameter and then we're going to instead of displaying the lead we're going to display a form where we can edit and submit the updates on a lead so i'm going to call this edit underscore lead and we're going to use a directory called lead for all the view files where we manipulate each lead so i'm going to finally call this lead slash edit.leads now let's save this controller and create a subfolder under views called lead and also create a new pug file called edits underscore lead dot pug now let's go to landing.pug and copy the beginning portion to edit lead and now we're going to create a form under edit lead where we will modify we will have the opportunity to modify the lead so we can copy some code from landing.pug we or where we already had a form i'm going to copy this form and input element and the button elements to edit lead now the action for our form needs to reflect the route that we defined here which is lead slash leads and then the lead id and edit so let's go ahead and add that here we're going to use plus lead.id and then plus slash edit and the method we're using is post method and we're still going to use the same name as lead email in our input it is of type email if we need we have a placeholder if the lead field is empty and then let's call this button save now rather than an empty form we want to show the existing value of the lead so we're going to add a new property in our input element called value and assign it with lead.email which we will receive from the database now let's save this file because this file is one subdirectory under views because we created this lead directory and we are referring to layout.pug at the beginning we need to update also our reference to go one directory level below now if we go back to our index.js file we haven't defined the root handler edit underscore lead for the post route so let's go to our controller's landing.js and define a new route called edit lead and let's delete the body now we have access to the leads id by using rec.params.lead underscore id because this was available to us in the route path we also have access to rec body lead underscore email the actual updated field and that comes from the edits lead form the name of the input element was lead underscore email so we're going to use these fields to first retrieve the object by using its id and then we're going to update its email field by using lead email let's go ahead and type return models dot lead that update email rec body dot lead underscore email and we're going to use a where clause we're going to ask for the id field using rec params lead underscore id and our query is complete then once this field has been updated we're going to receive the results as how many fields has been updated from sqlize we're going to redirect the user to view the lead so we're going to use slash lead slash plus rec params lead underscore id so this way after the post is successful and update is done we're going to be redirected to this route that shows the details of the lead now let's save our controller and run our application and see how it works so i'm going to open up the terminal the application seems to be running ok and i'm going to open up the browser and browse to localhost 3000 let's create a new lead hello at getbuzz.io and submit that so we have a collection of leads displayed let's click on one of them and click edit we're now on the edit route and i'm going to shorten this to let's say a at b.com and save it and i'm redirected to the show lead route that shows the updated leads so this concludes our tutorial on editing and updating leads now is the time to go back to our terminal and check in the changes we made so i'm going to type git add views git add controllers git add routes these are the directories that we modified and then we're going to comment add lead edit and post routes the next route we're going to implement is the delete route let's go back to our editor routes slash index.js and create a new route router.post slash lead slash lead id slash we're going to use the delete path components and then let's define a new handler called delete underscore lead let's save this file and then go to controller landing.js and let's create a new handler for the delete action let's call this delete lead we're going to delete the row in the database representing this lead so we're going to type return models lead destroy where id is rec params.lead underscore id then redirect back to the landing page because we are going to delete the current lead and everything associated with it including the page that shows the lead so let's type rest.redirect slash leads now let's save this file so let's go to views lead lead.pug let's define a new action here we're going to use a button instead of a link because the default method for accessing a link is a get request but we're interested in doing a post request so i'm going to define a form here action will be slash lead slash lead.id slash delete and method will be post we're going to have a button of type equals submit and we're going to call the button delete let's also create some spacing and we're now ready to run our application let's go back to our terminal the application is running let's make sure we've saved all the files and try let's go to slash leads let's go to the details of the first one we do have a delete button now let's click on it the entry was deleted let's try it again okay this one was also deleted let's take a look at our database activity we're deleting from leads where id is this id this concludes our implementation of the delete routes as usual let's check in the changes we made i'm going to do git add controllers git add routes we hit add views we need comments implement delete route for leads in this tutorial we're going to learn how to implement ajax requests and get started with using javascript in the browser we're going to implement the delete lead functionality using client-side javascript so let's start by defining our routes with router.post slash lead slash lead id delete and we're going to name this as delete json and we're going to define a new handler delete lead json let's save this file and go to controllers landing.js we're going to copy the delete lead handler we created previously and we're going to name it as delete lead underscore json we're still going to destroy a lead using the request parameter lead id but then after that instead of redirecting to the slash leads route we're going to send back a json object and we will do that by typing res.send defining a key msg with the value success now let's save this file and go to view slash landing.pug we're going to implement a button that will invoke the ajax request that will delete the particular lead so let's define a button with the text delete and we're going to define the on click property of the button to call the javascript function delete lead onclick is an event that gets fired in the browser when this button is pressed and by assigning it that handler we make sure that when the button is clicked this javascript function will get called now when we insert inline javascript like this inside pug we surround it with this character called the grave accent which looks like this tilted single quotes we're also interested in passing this lead.id field to the delete lead function but also we want pug to evaluate the value of it and pass the value and in order to do that we type dollar and then curly braces id and we surround the result with single quote character now i know this syntax looks a little bit complicated but this is the best way to add inline javascript in pug also passing variables that need to be evaluated for those who are curious grave accent is this left tilted single quote now for the implementation of delete lead we're going to use the jquery javascript library so i'm going to include that at the bottom of the html page with this single line we're also going to add a javascript file that we are going to define as javascripts slash leads.js so let's save this file and go to javascript leads.js now let's define our delete lead method and go over the details this delete lead function is making an ajax call ajax allows us to make http requests to our web server using javascript also sending and receiving data in form of json objects the key point with ajax is that the requests the web requests happen in the background while you're on the same web page so if you go back to our browser let's assume that i clicked on this delete button and it invoked our function that makes the ajax call that means that we're still going to be on the same page and then this url here is not going to change and the request to our web server and the response will happen in the background now let's take a look at the parameters we passed to this function the url field defines the route that we're going to call and notice how this path matches the route that we've defined for this purpose we have a data type as json and then we typically pass the data payload in this data field and json.stringify function is called to pack the data into a form that's transmittable over the network and then it gets unpacked on the other side using another call that matches this which is json.parse the type of our request is a post request and then we define two functions one for the success case and one for the error case and these get called when we receive a response from the server when we delete the lead from our database using the ajax call we want to reflect that the lead is removed to our user on the browser window as well now recall that we did not navigate from the current url and the ajax call happened in the background for that reason we need to modify the currently served html page we're displaying in the browser we do this dynamically in javascript and delete the html that corresponds to the lead that we've deleted the currently served html document visible in the browser is shortly called as dom which stands for document object model now jquery has convenience functions that help us manipulate the dom such as this remove call in this first part here we're looking for an html element with the id of lead id and then we're making a call to remove to remove it from the currently shown html document now in order for this to work we need to assign the lead id to the particular html element we want to delete so for that let's go to views slash landing.pug to this paragraph element for each paragraph we create for an individual lead we're going to assign it the corresponding lead id now html documents are hierarchical and what that means is that this paragraph is a parent of all of these children that have been nested inside it so if we delete this paragraph element from the html document that effectively means that we're also deleting all the children which includes all the details for that individual lead so we're going to delete this whole thing by simply searching for the paragraph elements with the lead id and then remove it from the html document and that's effectively what this call is doing now a few useful details about jquery when you see a dollar sign like this it means that we're making a call to jquery it just means we're making a library call dollar.ajax means we're calling jquery ajax and this dollar and then the parentheses mean whatever that's inside is going to be handled by jquery the second detail i want to mention is this part here when you use this hash character it means that you're simply searching for an id in the current html document the dom when we do hash plus lead id it means we're searching for the elements with that particular lead id jquery will go and search for every element that has an id property defined which is a fast way of searching for elements in an html document now let's take a look at how our application works let's go to the slash leads route in our browser and click on the delete button on some of these leads as you can see the leads are being deleted from this current html page but let's see what happens in the background so i'm going to open up the javascript console to see if you're getting results so if i open up these result objects i see that the message success has been received from our server each time i delete an object let's try it once more and also let's take a look at what happened on our server side as we are seeing we're doing a post request to the delete json route and also we're able to delete leads from our database let's check in the changes we made i'm going to do git add controllers hit add routes git add views we'll also define a new javascript file so i'm going to do git add public javascripts let's commit this implement lead delete route using ajax in this tutorial we're going to update the looks of our application using the bootstrap css framework so let's open up our browser and search for bootstrap and click on this link and go to getbootstrap.com the easiest way to include bootstrap in our project is to include hosted cdn links of the library in our project files cdn shortly stands for content distribution network and there are third-party hosts for javascript libraries and we will copy and include the links for bootstrap library in our project for that let's go to this link and click on the latest version and click on download and if we scroll below we're going to be given the links to the bootstrap cdn let's copy and paste them in our projects there are also dependencies provided so let's copy and paste them as well now in this tutorial we're also going to learn how to separate our pug files into reusable components and we're going to create a header a navbar and a footer component that we can use across all of our files let's create a new folder under views called common and let's create new files head.pug footer.pug and navbar.pug let's go to head.pug and type mixin head title indent head meta char set equals utf-8 and title equals title pug mixins allow us to define common snippets and include them in multiple pug files we can also pass them parameters such as this title field that gets used as the title of the document let's go back to where we copied the bootstrap stylesheet link cut it and paste it on head.pug and change the syntax to pug which is link open parentheses some properties and then close parentheses we also need to add some standard meta tags in our head section so let's do that as well now let's save this file and go to footer.pug and type mixin footer footer for the time being we're just going to include the javascript files so let's go back to where we copied the bootstrap javascript files cut and paste them on this file we're going to change each script tag syntax to use the pug syntax which is script and then open parentheses some properties and close parentheses let's do this one as well now the order that these libraries are declared matter and bootstrap depends on these other libraries so they need to be declared before the bootstrap declaration so let's go ahead and fix that order we're now ready to include our header and footer in landing that box so let's go there and delete these first few lines and type doctype html html blank equals en and we're now going to include common head.pug and we're going to invoke the mixin by typing head and let's give it a title starter mvp we need to add a body tag and let's indent everything to nest in the body and then at the bottom just before leads.js which depends on jquery i'm going to add the footer include common footer.pug and invoke the footer mixing and we don't need this line anymore because we've declared jquery in footer.pug now let's save this file and reload our landing page we can see now that this is a bootstrap enabled page now the page elements look rather plain because we didn't add any styling yet let's conclude our tutorial by doing some maintenance work the other pug file that we used was lead.pug so let's do the same thing on that file as well we're going to copy and paste this header section we're going to add a body we're going to indent the body to nest it under the body elements and we're going to copy the footer section to be nested inside the body and save it we also are not going to make use of this layout.pug file anymore so we can delete that let's check in all the changes we made i'm going to type git add views common git add views and hit comment add a common header and footer section in all pug files in this tutorial we're going to focus on the user interface and update the looks of our landing page using bootstrap templates let's open up our editor and go to view slash landing.pug now under the body i'm going to copy and paste a bootstrap navbar example that i've prepared earlier this is our navigation bar typically for a functional component of a page like this such as a nav bar we can take a look at an example on the bootstrap website and copy now when we define components in pug the first element you define is the html element and then everything that comes after that separated by a dot are css classes css classes modify the appearance of your html elements so in this navigation bar we're first defining a link and then we're nesting an image in it which is going to serve as our logo and then we have two navigation links nested in an unordered list notice how each html elements has a different css class these are classes defined by the bootstrap framework and available to us one last point here notice how we define these html elements in pug but this line does not contain a beginning html element and that's because this is typically considered to be a div you can type it like this or you can omit it and it will be assumed that the first element is a div element we're also making use of an image asset file for that i copied the file under public slash images slash file name all your assets which are shortly static files that never change in your application are stored under public you can refer to an asset file in html by starting with a slash and then the folder name and then the file name so as the root of your asset path slash refers to your public directory let's try and run our application by reloading our home page now we see a navigation bar two links and a logo now as we did previously i'm going to cut this nav bar from here and place it in a common mixing file so let's go under views slash command slash navbar.pug we created earlier and paste this code we're going to define a new mixin called navbar and currently we're not needing any arguments and i need to indent this by one level under mixing and save the file now let's go back to landing.pug and include our mixin under body we first need to add a header tag include common slash navbar.pug and then plus navbar and let's update the rest of our page using bootstrap html elements i'm going to type container and we create a new row and then inside the row we create a new column and the size of that is six for a medium sized screen we're going to copy and paste a header and a paragraph or two for our value proposition and let's delete these two lines here there were a few css classes that were previously prepared i'm going to copy and paste those and we have a form snippet as well that matches the form we created before copy this portion the contents of the input element and let's delete this part now let's save this file and reload our page now we have a landing page that has an updated look let's go back to landing.pug and we're going to update the portion where we list the set of leads for that i'm going to create a new row and then a column with an md-6 type we're going to indent this portion and i'm going to replace this portion with a table let's go ahead and do that now if we reiterate on this source code if there is a variable called leads we're showing the title leads and then we start a table inside the table under this t-head elements we list the names of the columns for the table we're using the name email for the email field and then the actions under the t-body tag we're listing the rows for the leads so here for each lead in leads we're creating a new row and then we're listing the email for the lead and then a link to the details also the delete button for it notice how we move the lead id as the id property to the table row so that the delete lead call can find which row of the table to delete when it's deleting the lead so as a recap if you go under public javascript leads.js this line will find the right html element and then remove it and in the case of a table this is the table row you can check out the bootstrap documentation on how to build tables like this now i want to make a few fixes on the indentation under this h1 tag we are nesting this table and that's not correct so i'm just going to de-nest it by one level also we want to nest this row under the container tag so let's go ahead and do that that's done let's save this now a few more changes let's go to navbar.pug i want to update the link to the leads route and also let's go to footer.pug remember when adding a dependency for the bootstrap library we added this jquery 3.3.1 and then the slim version turns out the slim version does not have ajax calls so we won't be able to make the ajax call under this delete lead function so i'm going to go back to this and delete this slim portion so we're now referring to the full version of jquery that includes the ajax calls as well we need to delete this integrity hash as well since this was referring to the previous file let's save this and we should now be ready to run our application let's go to our browser and reload the home page and let's click on the leads link and if we go down below we see all the leads listed and let's click one of the delete buttons to delete them before we move on let's check in all the changes we made so i'm going to do git add views common git add views landing dot pug and let's try doing git comments and let's type install bootstrap and update the look of pages while we're at it i want to organize our pages under the lead directory and i want to remove the list of leads from the landing page and create a dedicated page for leads so let's go under lead and create a new file and save it as leads.pug we're going to copy the first portion of our landing page let's just copy this part and paste it here also let's copy the footer part and paste that as well and in this middle section we're going to create a new container and then a column let's copy and paste those these are nested under body and header and let's cut and paste the section for leads we're actually not going to use these two lines in the landing page either so let's delete those save it and under leads i'm going to paste the section we don't need this if leads check because we're already displaying a page and let's save this file now let's go to controllers landing.js once we submit a lead we're redirected to the leads route and once we show the leads instead of using the landing page we're going to use the new page we defined and that'll be under lead slash leads let's save this file and let's go ahead and run our application again if i reload this page i got an error because the head file is located under common and i am one directory level below with the leads.pug file so i need to type dot dot slash for all the common files let's save this file and reload our application again and here we are on the leads page we can now see the leads on a separate web page let's also update the title here to leads and i'm also going to move this lead.pug file under the lead directory so let's just do that move use lead.pug views lead need the pug and i'm also going to update the css classes here to match the ones we use under leads and to use bootstrap so let's copy and paste the code we have for leads.pug into lead.pug and let's take the section that lists the single lead and let's delete the rest assuming that we are going to use a table we can update the contents of the table to match a single lead so instead of having for lead in leads we're just going to access the lead we have let's do this the first field is the email field which is the same here we can change this as edit and then delete and here we're going to have edit plus slash edit and instead of the ajax call we were going to use this form let's copy and paste that and as you might know we're using the button using the bootstrap css classes so let's double check what we're doing the first entry is lead.email and the second entry is the link to slash lead slash lead id and then edit which matches the link we created here and then the last one is a http post when we submit with this button and the path is slashly lead id delete so let's delete this portion and the body let's save this file and let's go to controllers landing.js when we render the lead page that is now located under lead lead let's save this and run our application again so i'm going to go to the browser window if i click on the details now i am seeing the lead page it now has the bootstrap classes and a table we need to redo the same exercise with edit lead.pug although i'm going to copy and paste code i prepared earlier because it's repeating the same exercise so let's delete this html and paste this concludes this part of our tutorial we've migrated all of our pages to bootstrap and also creates the separate leads view file let's check in our changes in this tutorial we're going to develop sign up and login functionality and learn how it all works let's open up our editor and open route index.js we're going to get started by defining the routes for login and sign up so let's type router get slash login we're going to use a new controller called user and we're going to use a handler called show login to show the login page and then we're going to have a router.get for signup and again we're going to use the user controller and type show sign up now let's define our user controller here as well so i'm assuming we're going to define a controller called user under controllers and let's save this file and let's go to controllers create a new file called user.js i'm going to copy and paste code that i prepared earlier nothing much happening here we're simply showing the login page the view is located under user slash login and then we're showing the sign up page with a sign up view under user directory we're also passing two objects to the view file one is form data and the other one is errors we're going to get back to these later on for now let's know that we're simply passing empty objects because these views are located under the user directory let's go ahead under views and create a new folder called user and i'm going to create two new files called login.pug and signup.pug now let's define these pages i'm going to paste some code that i prepared earlier for this nothing much interesting happening here since we covered bootstrap a little bit before but the essence of this page is that we have a form that posts to the signup routes and we're placing two input elements here one is an email and the other is a password and we're submitting them with the submit button and then we have a link at the bottom for the option of going to the login route now let's go to login.pug also i'm going to paste code that i prepared for this it's essentially the same code except we're posting to the login route and we're passing an email and password field as well and the purpose of this page is to log in and then we have two optional links at the bottom one is to reset a password we haven't got a route for that yet and then we can go back to the signup route let's save these files and go to our browser to take a look at how they work so this is how our login page looks and if i click on the signup route this is going to serve as our signup page now is a good time to define our user model and migration of our database so let's go to models and create a new file called user.js since we covered one model definition in detail for lead js before i'm going to paste code that i prepared earlier for the user model definition and let's go over it quickly so we're defining a new user model we're defining an id and then we have several fields of type a string we have a username first name last name password and email now we're not going to make use of these first three fields so we're passing a property along null true so that we can create rows that have null values for these fields and we're essentially going to make use of the password field and the email field and we're also passing the property unique for email as a constraint so that each unique user is distinguished by his or her email address and email is a candidate key for this table now we need to create a database migration that matches this model so let's go to migrations and create a new file and i'm going to name this file with today's date so that it goes in the right order in terms of migrations and comes after the lead table migration let's save this file i'm also going to copy and paste codes to go faster since we've covered a migration example before so as we covered previously the migrations have two methods one is an up method to to move the table definitions into a new form and then a down method that rolls back the change that's being made in this migration we're creating a new table called users and the fields we're creating match the fields we defined in the model nothing surprising or interesting here let's save this file and go to our command line to run this migration i'm going to type sqlize db migrate our migration has succeeded so we have created this table in our database and before we move on let's check in the changes we made so i'm going to type git add views user git add controllers hit add routes and git commit implement get route for login and sign up we're also going to check in the migrations and models so for that let's do git add models and git add migrations and git commits create user model and migration now let's open up our editor and go to routes slash index.js and we're going to define the post routes for login and sign up so let's type router.post slash login user.login router.post signup user.signup now before we move on let's define these controller handlers as well so let's go to controllers users.js and create these two empty handlers sign up and login now we're going to implement the sign up and login routes using a node.js library called passport.js in particular passport.js helps us with implementing authentication as you might guess there are many ways to authenticate your users you could use social networks or other means multiple methods of authentication for us and if you're interested to find out more you can go to passportjs.org for more details now let's go back to our terminal to install the packages we need let's type npm install passport we're going to use an add-on to passport for local authentication to our database so for that let's type passport-local we're going to use a library called bcrypt for encrypting our password and we're going to use the package validator to validate the input we make on login and signup routes we're also going to need to create sessions for our users so let's type express session and finally we're going to display error messages if login or signup fails for any reason and for that we're going to use a package called connect dash flash so let's type dash save and press enter this might take a while because we're installing multiple packages and let's check in the changes we made so i'm going to type git add package.json git add package lock.json and comment express session and connect flash now let's go back to our editor we're going to go to app.js to create an instance of passport so let's type let passport equals require passport we're also going to define the session so let session object equals require express session and let's go down below right after this line we're going to declare app dot use session we need to define a secret parameter for this let's just type our new secret for now and in the second line we're going to type app.use passport.initialize and finally app.use passport.session now each of these calls must be in this given order otherwise your application may not work because when app.js is processed it goes line by line to configure the app instance in a sequential order so that's why we need these three lines in this order now we're interested in setting up passport in a separate file than app.js in order not to clutter app.js with details of passport.js setup so for that before we create the app instance we're going to add one more line here we're going to type require dot slash passport setup and we're going to pass the passport object now let's save this file and create a separate file in our root directory called passport underscore setup.js and save now in passport setup.js we're going to start by defining an empty function that we're exporting from this file and we're passing the passport object to it as you might see here we're also calling the same function with this require statement and we're passing the passport instance we created a few lines earlier so let's go back to passport.setup now passport.js requires us to define a few well-defined api calls to function properly the first function is called serialize user and the second one is called this serialize user this stackoverflow page explains it quite well serialize user is used by passport.js to save a handle to the user object in this case it's the database id for the user it stands saved to a session variable and later on the serialized user will use this handle to retrieve the actual database object for the user user object is then assigned to the user key of the request object so that we can use it in our controllers or routes so let's go back to passport setup.js and define these functions for serialized user we're going to simply use the database id and for the serialized user we're going to query our database we'll pass the id to our user and then we're going to type models user find one where id is the id parameter and then we get the user object back if user is null it means there's an error so we're going to throw on error object wrong user id and else we're going to call done null user with the user object so we're almost done as a recap serialize user function determines which handle to the user object is to be saved in the session and then the serialized user will retrieve the user object using that handle now we need to define a strategy for passport.js to use to authenticate our users when they log into the application because we're going to use email and password as the method for authentication we're going to define what is known as a local strategy for passport to authenticate our users via email and password now let's go ahead and type let local strategy equals require passport local this is where this package comes into play and then we're going to type strategy now we need to tell passport.js that we will be using the local strategy for authentication for that we add a statement passport.use new local strategy local strategy will call its authentication function when there is a login form submitted via a post request so local strategy needs to know which fields in the submission contain the username and password for that there are two optional fields to define these username fields in our case it is called email and password field and in our case it is called password now if you go to login.pug you will see that the first input field is named as email which we will use as the username and the second one is named as password so when the local strategy accesses request body email it will consider that as the username and then when it accesses request body password it will assume that to be the password field now we need to define an authentication function where we access the database and show that there is indeed a user with this email address and the password provided we type function email password and done now this function will authenticate the parameters however we also need the request object here and in order for passport to pass us the request object as the first parameter we need to give it another option called passwreck call back true we're going to use this for error handling later on now let's define our function let's open our curly braces and type return models user find one where the email field is the email parameter and then we will receive a result which let's call as user and if this user is null it means we couldn't find the user so we're going to return an error message incorrect credentials and we need to add return done null false and we're going to type else if user.password is null or user that password is undefined rec flash message you must reset your password these wreck flash messages will be shown in the subsequent re-render of the page and we're also going to type return done null false this is another error case finally else if we're going to define a function that validates the password provided is correct so let's call that valid password we're going to define it shortly we're going to pass the user object and then the password provided in the login form and let's type rec flash message incorrect credentials and this will be entered if the password isn't valid so i'm going to add a not and here we're going to type return done null false so we have handled all the error cases and if we have a valid user we're going to return done null user there may be further errors other than incorrect credentials being provided and we will handle them with this catch statement in the end for example if there was a database error when accessing the user model that will be caught by the statement so we're going to type catch error and done error false now let's save this and let's go ahead and define the valid password function for password validation we need bcrypt library so let's type require decrypt actually for accessing the models the database we also need to define the models variable by typing require dot slash models and we're going to compare the past password versus the one in the database so let's type valid password equals function user password and then return bcrypt compare sync is a decrypt function we will pass the password in the login form versus the user.password field now the passwords contained in our database is a hash of the provided password so that we don't keep them as clear text so this function will also convert the password to a hash and compare the hash value to the one that's being stored in the database this way if the database was compromised the adversaries cannot access the clear text passwords but they only get access to the encrypted versions we're done with the implementation of our first passport login and signup strategy using the local strategy and let's go over the api calls again so we're providing passport with a handle to the user object which is to be saved in this session and then passport.js will use this handle to get the actual user object from the database we also define a local strategy where we tell passport.js what fields to use for the email and password fields when authenticating the user post request during authentication there may be various errors once the database is queried given the email and password fields there may be multiple authentication error cases one of them is that the incorrect username is provided the password field is not present or the password is simply not valid in such cases we return an authentication failed message back to the user in the successful case we pass the user object to the done callback and we also catch database or other internal server errors with a catch statement we use a valid password function call to compare the past clear text password with the hash that's stored in the database we're now ready to check in our changes so let's go back to our terminal and type git add app.js git add passport setup js and git commit a implement passport local alt strategy using email and password fields now that we have set up passport.js we can go ahead and use it in our sign up and login route so let's go and open up controller slash user.js in the signup handler we're going to create a new user by using the user model and then save it to our database so let's type const new user equals models dot user.build email rec body email and password we're going to use a function to generate the hash of the password so let's call this function generate hash and we're going to pass rec body password once we build the user object we're going to save it by typing return new user dot save and this is a promise so we're going to do then results and inside the body of this promise we're going to make a call to passport.js to authenticate the user after signup so let's call passport authenticate local since we are using the local strategy and then we're going to define a redirect route after the authentication so let's type success redirect slash failure redirect which is used upon the passport authenticate call failing we will call slash sign up and we're going to define a flash message failure flash true we're also going to pass the request response and next objects now in order to use the models object we need to first define let's models equals require dot dot models and let's define the generate hash function const generate hash equals function password and in the body we're going to use the bcrypt method hash sync so return be crypt sync decrypt can salt sync 8 and null so generate hash function will take the password and create a salted password what that means is we're going to create a hash of this password and save the hash in the database now let's also define the decrypt object let's be crypt equals require bcrypt let's also define passport equals require passport we also need to set up passport so let's type const my passport equals require dot dot passport setup and we're passing the passport instance we also will need flash so let's type let flash equals require connect flash you might be wondering what's flash stands for flash allows us to display an error message on the page that's going to be rendered so it's a one-time message that we can send to our clients now let's save this file and run our application and verify that the signup works i'm going to run the application go back to the browser and type slash sign up let's type user at email.com and then a password and press sign up now that we've been redirected to the slash route it seems to be working let's go and verify this by going to our terminal here we're inserting a new user to the database with the email that i have just typed we have also started a new session with our application now let's go back to our editor and implement the login route in login route we authenticate a user and initiate a session with our application for that we're going to do the identical action as we did in sign up with passport so i'm going to copy and paste that code the only difference being here is that upon failure we're going to be redirected to the login route let's check the result by going back to our browser and let's type slash login let's type user at email.com and then the password and i'm going to click on login and i'm redirected to the slash route which means the login was successful as well and i've initiated a session with my application now let's go back to our editor routes slash index.js and for completeness we're also going to define a logout route so let's type router.post slash logout user.logout and router.get logout user.logout for both requests we're going to use the same method now let's go back to controller's user.js and define a new method called logout we can destroy our session by making a call to rec logout and rec session dot destroy and we will then redirect the user with rest.redirect back to the root route now it will help us to display these routes as links in our navigation bar also we want to know whether we have a user session or not so let's go to views slash navbar.pug to implement this i'm going to paste the snippet that i prepared earlier here if we are passed a user variable that means we have an active session going on and we display that by showing hello user email on the navbar we also have links to logouts login and signup routes now for this user variable to be passed we need to define it as an input to the navbar mixin so let's type user and save this file and navbar is used from the landing page so let's go to view slash landing.pug and pass the user variable to the navbar mixin let's save this file and now let's go to controllers slash landing.js we're going to pass the user variable to the render function so let's type user rec dot user if you recall passport.js will populate this rec.user field with the user object if there is an active session going on let's go to our browser window to test the login and logout routes let's go to login and type user ads email.com password and login as you can see we have logged in and we can see the user information here and let's click on log out and now the user session is destroyed so we don't see the user email address here anymore now let's go back to our terminal and check in all the changes we made if we type git commit dash a it will include all the files that have been modified let's type implemented sign up login and logout routes using passport.js in this tutorial we're going to learn how to validate form input when a form is posted to our server and how to re-render the page with error messages when there are errors as a recap for how we handle form submissions let's open up our editor and go to routes index.js here we have defined a post request handler for sign up path using this user.signup handler so let's open up that handler by going to controller slash user.js if we look at the signup post handler we see that we create a new user object without validating the input we receive from the form reg body email and recbody password fields are used directly to create the user and save to the database we're going to change that and validate these input fields first before saving the data and for that we're going to define a validator function for our form input so let's get started by installing the validator package by typing npm install validator we are also going to use a package called low dash so let's add that as well and type dash dash save and press enter let's commit our package.json just in case we made any changes so i'm going to type git commit package.json and package log.json okay install validator and lodash now let's go back to our editor and in the root directory my app let's create a new folder called validators and save that and we're going to create a new file called signup.js here let's type let validator equals require validator save that and i'm going to create a local function called validate create user fields function this is going to receive an errors object that is empty and we will populate it as we find errors in each form input field and we're going to receive the form input fields with the rec parameter which is the request object so let's type if validator is email rec body email here this mark stands for not so if this input is not an email then we will populate the errors object with the key email with a message please use a valid email so we're going to go over each input field like this with an if statement so the next one for us is if not validator is ascii we're requiring that we want the password to be made out of ascii characters and we're going to pass the password with rec.body.password if this doesn't hold true then we're going to populate the errors object with the password key to be invalid characters in password please try another one we also want to enforce a password length so let's type if not validator is length track body password here we pass a length range object with minimum of 8 characters and maximum of 25 then again we're going to populate the errors for the password key please ensure that your password has a minimum of 8 characters now we're done with this function because the errors object was passed into this function it will be modified in place so we do not need to return the errors object now other than this basic string validation we need to make sure that there isn't an existing user but the same email as the address provided in this email form field for that we need to query the database so let's define a wrapper function export validate user function pairs rec let's type return models user find one where email is wreck body email and then we are going to get value u if u is not equal to null then we're going to populate the email key of the errors object email is already in use please login or reset your password now i need to introduce you a new concept on program execution when we define the body for validate user where we query the database this is an asynchronous piece of code so it will execute sometime in the future and we will get the results also sometime in the future and this first portion we defined the validate create user fields function is a synchronous piece of code which means each of these statements will execute sequentially now in order to validate the form fields we need both this function which is synchronous and this function which is asynchronous and we need to mix the two together for that we need to use a concept called promise and make the entire body asynchronous we're going to cover promises in the future in more detail but for the time being what you should know as a recap is that this piece of code is asynchronous and this piece is synchronous and in order to make use of both in a single function we need to define a promise which wraps the entire code in an asynchronous body so for that let's type return new promise function resolve reject and we're going to create the promise body let's cut this piece paste it here and indent it inside the promise and let's make a call to validate create user fields errors rec and we will return the errors variable in resolve errors and let's not forget to include the models variable so let's go to the top and type let models equals require dot dot slash models now let's save this file now let's go back to controller slash user.js and import validate user so let's type const validate user equals require dot dot validators slash signup now let's go down to the signup handler and declare a new variable let errors equals an empty object and we're going to call return validate user errors and we're going to pass the rec object that contains the input fields to be validated so let's move on and type then errors which is going to be the result we get from validate user and we're going to check whether the errors variable is populated with any values so let's type if not is empty errors which means the errors object has some values we're going to call a new method rerender sign up and we will re-render the form just as we will render the form for the first time using the show sign-up ender except we're going to display the error messages that we have populated during the validate user call so let's add the errors variable here errors and we're also going to pass the usual wreck res and next objects now this case covers the case where we have errors on the form and we will handle this successful case here as well so let's type else and inside the else body let's cut and paste rest of the code and let's indent it so this means if there is an error we're going to re-render the form and if not we're going to save the data to the database there's one more thing we forgot this is empty function is a call that's been provided by the law dash library we just installed so we need to type const is empty equals require low dash now is a good time to define our rerender signup function it's going to be identical to show sign up with a few differences so let's copy and paste show sign up and we're going to make this a local function so let's type const re render sign up now even though re-render sign up looks like a request handler such as show sign up it's actually just a function call so we're free to modify its function signature with the order of parameters being passed normally in express.js the request handlers have a particular order in their parameters in particular the request response and next objects are passed in that order so we render sign up is called from the sign up handler at this point and we can pass the errors object as its first parameter and we're then going to pass that to the errors key so that errors can be displayed on the form when the page is re-rendered we also have another field called form data and form data is a name that we made up in particular for when there are errors on a form when we re-render that page we use form data to pass back all the input fields that have been modified by the user so that let's say when there are errors the user does not have to re-enter the same information to the other form fields again and again on each time the form is re-rendered so we save the user a time by passing back the data that's been entered already in a previous submission so in order to pass that data back to form data key we are going to use rec dot body if you recall if we go down to the sign up handler when the form is submitted to us we have all the form input fields available to us in rec.body object with the keys corresponding to the input names such as email and password so by passing back rec.body after the submission we are effectively passing back all the input fields that have been submitted to us on the form submission so we're passing rec.body back in form of the key form data now if you recall show sign up is using user slash sign up view and we're using the same view in re-render sign up as well so we're going to modify the sign up view to cater for both cases of the showing the form for the first time and also re-rendering the form with errors and existing form information so let's go ahead and open up views slash user slash signup.pug to modify it and to use form data and errors fields now let's take a look at the first input field with the name email we can pass back existing values on an input field using the value property so here for the value property we're going to type form data dot email we could potentially populate the value property of the password field as well but we're not going to do that as password is a sensitive field so let's add error message information now and let's create a new line under the first input and let's type if errors and errors dot email which is the name for the input field we're going to type p dot small dot text danger these are classes from bootstrap and we're going to finally display the error message errors.email if you recall we create these messages in the validator function let's do the same for the password field so i'm going to create a new line under the password input field and let's type if errors and then errors dot password p dot small dot text danger errors.password now let's save our file and we should be ready to try what we've done so far now let's go back to our browser window and go to the slash signup routes and i'm going to type user at email.com we know that we have a user already with this email address so let's see what happens when we include that and for the password i'm going to type 4 character password which should also trigger an error so if i click on sign up i do get the form re-rendered with the right error messages notice how the validator has both detected that the email is already in use we've done this with the database query and the password length was also detected to be not valid let's check in all the changes we made it add validators we've added a new directory validators and we've implemented error handling and form validation for sign up routes in this tutorial we're going to learn how to implement access control in our application also we will learn the concept of a middleware and how to use it in express.js the problem with our application in its current form is that the leads link here is open to public anybody can click on this link view our links or edit them and we're going to fix that so let's open up our editor and go to routes slash index.js in express.js a significant property of route definitions is that we can introduce a sequence or a chain of function calls before we make a call to the final handler for that route let me show what i mean with an example i'm going to introduce a new call right after the path component called know and place a comma and let's define north with const no equals function rec res next and an empty body as you recall the handlers in express.js have this particular function signature where there is first a rec object and then a res object and the next object and we've never made use of this next object here so we're going to make a call to next and leave it at that what this does is that when the slash leads path is matched the first function to be called is going to be know and no op will transfer execution to the next one in line which is show leads and the way we do that is by making a call to next i could potentially add additional know up calls here and it will be all the same because no op does nothing but transfer the control of execution to the next one in line in a route definition we have the capability to add as many calls as we need to any separate handlers before we call the final handler and this gives us a lot of flexibility for adding additional functionality to each route and we're going to see one example shortly before we move on i want to demonstrate you that these no op calls indeed have no effect and we are able to call show leads as normal so let's go to our browser window and click on the leads link and we're still able to see the leads as usual now let's go back to our editor window if you notice these knob calls are in the middle when handling the request for this route that's why they're called middleware middleware may sound like a grand term that does something complex but a middleware can merely be a simple function call such as this knob function and let's remember that in a middleware function we always need to make a call to next in order to proceed the execution to the next one in line and make sure that the final handler gets called now we're going to define a really basic middleware first let's delete the snob call and delete these calls in the middle and let's create a new folder called middleware in our root directory and we're going to create a new file called has auth.js let's type let create error equals require http errors create error function allows us to create an error object with an error message and we've already made use of this in app.js and it comes as standard with the vodila express.js installation so let's go back so let's define a new method exports is logged in equals function rec res next if rec.user then we will call next the presence of rek.user means that passport.js has authenticated the user there's a session and there's a logged in user who is requesting the page so we're allowed to go to the next step of handling that page and else we're going to create the error create error 404 and we're going to give the message page does not exist now there's one thing i need to mention about how this next works in the successful case we're calling next to move on to the next handler but in the error case we're also calling next so how come we're showing an error message when we call next which should normally call the next handler for this route well the answer is in the express documentation if you pass anything to next function express regards the current request as being an error and it will skip any remaining non-error handling routing and middleware functions what that means is we're going to skip all the route handlers that are coming next and we will go straight to our error handler using the object we're passing here and that error handler is in app.js if you scroll down below you will see this error handler already defined for us when we pass an object then that means that this error variable will have that object being passed from next and we're going to display an error message and render the error page so that describes how next will work in both cases of a success and error let's save this file and go to index.js under routes folder and we're going to import this function we have just defined so let's type let is logged in equals require dot dot middleware slash has auth.js and we're going to use it's logged in in the leads route as our middleware so let's type is logged in and then a comma let's save this file and try our application again so i'm logged out so and i'm going to reload this page and i'm going to click on leads let's see what happens indeed our middleware has found that the page does not exist and generated a 404 error while we are at it i want to beautify our error page as well so let's go back to our editor and open up views slash error.pug and i'm going to copy and paste code that i prepared earlier for this we're using a few bootstrap classes let's save and reload this page now this looks better just to note we're able to see exactly what happened in the application and that's because the application is running in debug mode if we were running in the production mode we wouldn't see this error stack now just to demonstrate you the other case let's go back to the landing page and log in i'm going to type user at email.com and sign in now if i click on leads i'm able to still see the leads now every user has access to our leads table so we're going to take our access control concept a little further and only allow a particular user to have access to these pages so let's go back to our editor and create a new migration under migrations let's create a new file with today's date we're going to add a new field called is admin to the users table i'm going to copy and paste code that i prepared for this earlier and let's go over it quickly so what we're doing here is creating an easy admin field which is a boolean and when it's true we will consider the user as an admin of our application and here we have the up method for the migration where we add the column to our table and the down method which will remove this column from our table called users let's save this file and go back to our terminal and type sqlize db migrate so we've successfully migrated our table and added an ease admin boolean field to our users table now let's go back to our editor i'm going to make a modification in the way we create new users let's go to controller slash user.js and the signup handler now if there are no users in our application with an admin flag as true we're going to create the next user as an admin and for that i'm going to modify the sign up handler let's type return models user find one where is admin is true then user and if user exists that means user not equal to null then we're going to craft the user row as normal so let's cut and paste the way we create the first user and else we're going to create the user with the field is admin equals true and for this to work we need to first declare new user outside use the new user variable and finally we're going to save the user back to our database so let's place this after the else statement let's save this file and check that our application is running correctly what we haven't done is update our model under models with the is admin field so let's create an is admin field under here at the bottom i'm going to copy and paste code that i prepared for this earlier so ease admin is a boolean and we allow it to be null because the existing users won't have this field set let's save our model file and go back to our browser and let's sign up as a new user and i'm going to type a password for that and press sign up now we have admin at email.com signed in and let's go back to our terminal to verify that this user was indeed created with is admin as true insert into users first second third and fourth field is is admin and i can confirm that admin at email.com is confirmed as an admin in our application now we're ready to implement the is admin check in our middleware so let's go back to our editor and go to middleware has alt dot js and i'm going to define a new function here exports dot has auth equals function request next and if rec user is not null and and rec user dot is admin is true then we're going to call next as usual and allow access and else we're going to create an error as before next create error 404 page does not exist let's save this and let's go back to routes slash index.js to import this new method as auth and we're going to replace the is logged in middleware with this one so let's type as off and save this and open up our browser and let's reload this page and i have the leads link here if i click on this link i'm still able to see the leads and i'm going to log out now and log in as another user that i just signed up as which is no admin at email.com and login and if i now click on the leads link i'm redirected to the page does not exist error page so this effectively demonstrates our use of the has out middleware in order to control access to certain pages on our application we now want to extend this to other routes where the leads are edited and accessed so we're going to add the has out middleware to other routes as well so let's type has alt for show lead as out for the edit lead and the rest now all of our routes are protected by the has out middleware except the first one which is for visitors and the landing page now let's check in our changes let's type git add middleware git add migrations git commit a and implement has auth middleware and is admin flag lead routes are protected by as auth and only the admin user has access to them i hope you enjoyed these tutorials my name is bahadur i'm a systems software engineer my background is in low level software and operating systems if you enjoy these tutorials and want to be notified of similar content in the future you can go to this website and join our community here if you scroll down below you will see a button to join it's free thank you for watching these tutorials and i hope to see you in another tutorial in the future you\n"