In this project, we will take the afternoon project of the first day of Node and modify it to use sessions, custom middleware, and also use query parameters. We'll build a filter middleware that will censor words before being pushed to the messages array. We'll also modify the update and delete endpoints to use query parameters instead of URL parameters. Lastly, we'll use sessions to keep track of messages sent by a user during a session and build out an endpoint that will display the history of messages.
- Fork and clone this repository.
cdinto the project.- Run
npm install.
In this step, we'll use npm to install express-session and dotenv, require them in our server/index.js, and configure our app to use sessions.
- Run
npm install --save express-session. - Open
server/index.jsand requireexpress-sessionin a variable calledsession. - Configure the app to use sessions using
app.use.- The first parameter should be
sessioninvoked with an object as its first argument. - In the object define the value for
secret,resave,saveUninitialized, andcookie.maxAge.cookie.maxAgeshould be set to the value of10000.- Don't forget to configure
dotenvto use with your session secret and include your.envfile in your.gitignore.
- Don't forget to configure
- The first parameter should be
server/index.js
const express = require('express');
const bodyParser = require('body-parser');
const session = require('express-session');
const mc = require( `./controllers/messages_controller` );
require('dotenv').config()
const app = express();
app.use( bodyParser.json() );
app.use( express.static( `${__dirname}/../build` ) );
app.use( session({
secret: process.env.SESSION_SECRET,
resave: false,
saveUninitialized: true,
cookie: { maxAge: 10000 }
}));
app.post( "/api/messages", mc.create );
app.get( "/api/messages", mc.read );
app.put( "/api/messages", mc.update );
app.delete( "/api/messages", mc.delete );
const port = 1337
app.listen( port, () => { console.log(`Server listening on port ${port}.`); } );In this step, we'll create custom middleware that will check to see if the session has a user object. If it doesn't, we'll add a user object that has a messages array on it.
- Create a folder called
middlewaresinserver/. - Create a file called
sessioninserver/middlewares/session.js. - Open
server/middlewares/session.js. - Use
module.exportsto export a function with areq,res, andnextparameter. - Inside the function check if
req.sessionhas a user property, if it doesn't add a user property that equals an object with amessagesarray on it. - After the if statement, call
next. - Open
server/index.js. - Require
server/middlewares/session.jsin a variable calledcreateInitialSession. - Tell
appto use thecreateInitalSessionmiddleware after sessions are setup.
server/middlewares/session.js
module.exports = function( req, res, next ) {
const { session } = req;
if ( !session.user ) {
session.user = {
messages: []
};
}
next();
} server/index.js
const express = require('express');
const bodyParser = require('body-parser');
const session = require('express-session');
const mc = require( `./controllers/messages_controller` );
require('dotenv').config()
const createInitialSession = require( `./middlewares/session.js` );
const app = express();
app.use( bodyParser.json() );
app.use( express.static( `${__dirname}/../build` ) );
app.use( session({
secret: process.env.SESSION_SECRET,
resave: false,
saveUninitialized: true,
cookie: { maxAge: 10000 }
}));
app.use( createInitialSession );
app.post( "/api/messages", mc.create );
app.get( "/api/messages", mc.read );
app.put( "/api/messages", mc.update );
app.delete( "/api/messages", mc.delete );
const port = 1337
app.listen( port, () => { console.log(`Server listening on port ${port}.`); } );In this step, we will create a filter middleware file that will handle filtering messages with profanity.
- Create a file called
filter.jsinserver/middlewares/. - Open
server/middlewares/filter.js. - At the very top of the file create an array called
notAllowedthat contains words that should be censored. - Use
module.exportsto export a function that has areq,res, andnextparameter. - Copy in the following filter code:
-
filter logicwhile ( notAllowed.find( word => req.body.text.includes(word) ) ) { const badWord = notAllowed.find( word => req.body.text.includes(word) ); req.body.text = req.body.text.replace( badWord, '*'.repeat( badWord.length ) ); }
-
- Call
nextafter thewhileloop.
server/middlewares/filter.js
const notAllowed = [ 'poo', 'butt' ];
module.exports = function( req, res, next ) {
while ( notAllowed.find( word => req.body.text.includes(word) ) ) {
const badWord = notAllowed.find( word => req.body.text.includes(word) );
req.body.text = req.body.text.replace( badWord, '*'.repeat( badWord.length ) );
}
next();
};In this step, we'll require server/middlewares/filter.js in server/index.js and check if the method of the request is POST or PUT. If it is POST or PUT, we'll call our filter middleware to filter the text from the request body.
- Open
server/index.js. - Require
server/middlewares/filter.jsin a variable calledfilter. - Add middleware to app that captures
req,res, andnext. - Check if the method of the request is
POSTorPUT. If it isPOSTorPUT, callfilterwithreq,res, andnextas arguments. Otherwise just invokenext.- The method of a request is defined on
req.method.
- The method of a request is defined on
server/index.js
const express = require('express');
const bodyParser = require('body-parser');
const session = require('express-session');
const mc = require( `./controllers/messages_controller` );
require('dotenv').config()
const createInitialSession = require( `./middlewares/session.js` );
const filter = require( `./middlewares/filter.js`);
const app = express();
app.use( bodyParser.json() );
app.use( express.static( `${__dirname}/../build` ) );
app.use( session({
secret: process.env.SESSION_SECRET,
resave: false,
saveUninitialized: true,
cookie: { maxAge: 10000 }
}));
app.use( createInitialSession );
app.use( ( req, res, next ) => {
const { method } = req;
if ( method === "POST" || method === "PUT" ) {
filter( req, res, next );
} else {
next();
}
});
app.post( "/api/messages", mc.create );
app.get( "/api/messages", mc.read );
app.put( "/api/messages", mc.update );
app.delete( "/api/messages", mc.delete );
const port = 1337
app.listen( port, () => { console.log(`Server listening on port ${port}.`); } );In this step, we'll update the messages controller to add new messages to a user's session and modify the update and delete methods to use query parameters instead. We'll also add a history endpoint that will allow us to see messages on the session.
- Open
server/controllers/messages_controller.js. - Modify the
createmethod to add the new message object to themessagesarray on session as well. - Modify the
updatemethod to useidoff therequestquery. - Modify the
deletemethod to useidoff therequestquery. - Create a
historymethod that will return allmessageson a user's session. - Open
server/index.js. - Create a
GETendpoint at/api/messages/historythat calls thehistorymethod from themessagescontroller.
server/controllers/messages_controller.js
let messages = [];
let id = 0;
module.exports = {
create: ( req, res ) => {
const { text, time } = req.body;
const { user } = req.session;
messages.push({ id, text, time });
user.messages.push({ id, text, time });
id++;
res.status(200).send( messages );
},
read: ( req, res ) => {
res.status(200).send( messages );
},
update: ( req, res ) => {
const { text } = req.body;
const updateID = req.query.id;
const messageIndex = messages.findIndex( message => message.id == updateID );
let message = messages[ messageIndex ];
messages[ messageIndex ] = {
id: message.id,
text: text || message.text,
time: message.time
};
res.status(200).send( messages );
},
delete: ( req, res ) => {
const deleteID = req.query.id;
messageIndex = messages.findIndex( message => message.id == deleteID );
messages.splice(messageIndex, 1);
res.status(200).send( messages );
},
history: ( req, res ) => {
const { user } = req.session;
res.status(200).send( user.messages );
}
}; server/index.js
const express = require('express');
const bodyParser = require('body-parser');
const session = require('express-session');
const mc = require( `./controllers/messages_controller` );
require('dotenv').config()
const createInitialSession = require( `./middlewares/session.js` );
const filter = require( `./middlewares/filter.js`);
const app = express();
app.use( bodyParser.json() );
app.use( express.static( `${__dirname}/../build` ) );
app.use( session({
secret: process.env.SESSION_SECRET,
resave: false,
saveUninitialized: true,
cookie: { maxAge: 10000 }
}));
app.use( ( req, res, next ) => createInitialSession( req, res, next ) );
app.use( ( req, res, next ) => {
const { method } = req;
if ( method === "POST" || method === "PUT" ) {
filter( req, res, next );
} else {
next();
}
});
app.post( "/api/messages", mc.create );
app.get( "/api/messages", mc.read );
app.put( "/api/messages", mc.update );
app.delete( "/api/messages", mc.delete );
app.get( "/api/messages/history", mc.history );
const port = 1337
app.listen( port, () => { console.log(`Server listening on port ${port}.`); } );In this step, we'll use the front-end to see if the history endpoint is working.
- Use
nodemonornode index.jswhen inserver/to start the server. - Go to
localhost:3000in your browser. - Send some messages and then check the history.
- Wait 10 seconds and re-check the history.
- The history should now be blank since the session has been set to expire in 10 seconds.
- To refresh the history, toggle it off and on.
If you see a problem or a typo, please fork, make the necessary changes, and create a pull request so we can review your changes and merge them into the master repo and branch.
© DevMountain LLC, 2017. Unauthorized use and/or duplication of this material without express and written permission from DevMountain, LLC is strictly prohibited. Excerpts and links may be used, provided that full and clear credit is given to DevMountain with appropriate and specific direction to the original content.


