node/express session to pass an object to the view - node.js

I have this post login that stores an object in req.locals.user.
var router = express.Router();
var User = require('../models/user');
var Company = require('../models/company');
/* GET home page. */
router.get('/', function(req, res) {
res.render('users/login');
});
router.post('/users/login', function(req, res){
var email = req.body.email;
var password = req.body.password;
User.find({email: email, password: password}, function(err, user){
if(user.length == 0)
{
//user wasn't found
res.render('users/login', {validation: "Invalid Email Or Password"})
}
else
{
//user was found set session and local objects
req.session.user = user;
res.locals.user = user;
res.redirect('/dashboard');
}
});
});
my problem is that when I redirect the user to the dashboard. I get an error message saying that my object is undefined.
<h1 class="page-header">Dashboard v2 <small><%=user.firstName%>.</small></h1>
app.js
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var mongoose = require('mongoose');
var moment = require('moment');
var session = require('express-session');
var dashboard = require('./routes/dashboard');
var users = require('./routes/users');
var categories = require('./routes/categories');
var products = require('./routes/products');
var sales = require('./routes/sales');
var companies = require('./routes/companies');
var app = express();
// set locals
app.locals.moment = moment;
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use(session({resave: true, saveUninitialized: true, secret:"mySecretString"}));
app.use(function(req,res,next){
res.locals.user = req.session.user;
delete req.session.user;
next();
}
app.use('/', dashboard);
app.use('/', users);
app.use('/', categories);
app.use('/', products);
app.use('/', sales);
app.use('/', companies);
app.use(function(req, res, next){
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "X-Requested-With");
res.header("Access-Control-Allow-Headers", "api_key");
if(req.method == 'OPTIONS') {
res.send(200);
}
else {
next();
}
});
// catch 404 and forward to error handler
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
// error handlers
// development error handler
// will print stacktrace
if (app.get('env') === 'development') {
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: err
});
});
mongoose.connect('mongodb://localhost/test');
}
// production error handler
// no stacktraces leaked to user
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: {}
});
});
module.exports = app;
How do I pass my object globally between my views ?

Problem because res.locals.user will be remove when you redirect (next request). Only req.session exists.
For set variable to next request. You need a middleware to set session to locals again
app.use(function(req,res,next){
res.locals.user = req.session.user;
delete req.session.user;
next();
});

Related

SyntaxError: Unexpected token )

I am using Cassandra + Node.js to create an app, but I am receiving an error for this code:
C:\Users\userx\node-cassandra\app.js:44
app.post('/',new);
^
SyntaxError: Unexpected token )
at Module._compile (module.js:545:28)
This is my code
app.js
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var helenus = require('helenus');
var index = require('./routes/index');
var users = require('./routes/users');
var app = express();
var pool = new helenus.ConnectionPool({
hosts : ['localhost:9160'],
keyspace : 'webinar',
cqlVersion : '3.0.0',
//user : 'test',
//password : 'test1233',
//timeout : 3000
//cqlVersion : '3.0.0' // specify this if you're using Cassandra 1.1 and want to use CQL 3
});
pool.connect(function(err){
if(err){
throw(err);
}
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
app.set('cassandra',pool);
// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.get('/', routes.index);
app.post('/', new);
app.delete('/', delete);;
// catch 404 and forward to error handler
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
module.exports = app;
});
index.js
exports.index = function(req, res, next){
req.app.get('cassandra').cql('SELECT * FROM users LIMIT 10',function(err, users){
if(err){
return next(err);
}
res.render('index', { title: 'Users', users: users });
});
};
exports.new = function(req, res, next){
var insert = 'UPDATE users SET first_name=?, last_name=? WHERE email=?',
params = [req.body.first_name, req.body.last_name, req.body.email];
req.app.get('cassandra').cql(insert, params, function(err, users){
if(err){
return next(err);
}
res.redirect('/');
});
};
exports.delete = function(req, res, next){
var remove = 'DELETE FROM users WHERE email=?',
params = [req.body.email];
req.app.get('cassandra').cql(remove, params, function(err, users){
if(err){
return next(err);
}
res.redirect('/');
});
};
Error
SyntaxError: Unexpected token )
i just tried to change the app.post('/',routes.new);
but it showed inheritance mustnot be done
Please tell me where is my mistake
new is a reserved word in ECMAScript. I don't think you will be able to use it as a member name as it is being interpreted as creating a new object.

nodejs rest api with postgresql and passportjs

I'am new to NodejS and trying to implement PassportJS into my existing rest api that uses postgresql as datastore.
My code is based on this tutorial: http://mherman.org/blog/2016/03/13/designing-a-restful-api-with-node-and-postgres/#.WMBV9BLhBR1
My app.js looks like this:
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var log4js = require('log4js');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var routes = require('./routes/index');
var users = require('./routes/users');
var passport = require('passport')
, LocalStrategy = require('passport-local').Strategy;
var app = express();
//For logging
var httpLogFormat = ':remote-addr - - [:date] ":method :url ' + 'HTTP/:http-version" :status :res[content-length] ' + '":referrer" ":user-agent" :response-time';
log4js.loadAppender('file');
log4js.addAppender(log4js.appenders.file('logs/access.log'), 'access');
var logger = log4js.getLogger('access');
app.use(log4js.connectLogger(logger, { level: 'auto', format: httpLogFormat }));
//Passport security
app.use(passport.initialize());
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
//For CORS
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "https://example.com");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
res.header("Access-Control-Allow-Methods", "GET, POST, PUT, OPTIONS, DELETE");
next();
});
app.use('/', routes);
app.use('/users', users);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
// error handlers
// development error handler
// will print stacktrace
if (app.get('env') === 'development') {
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: err
});
var callerIP = req.headers['x-forwarded-for'] || req.connection.remoteAddress;
logger.debug("development message");
});
}
// production error handler
// no stacktraces leaked to user
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: {}
});
var callerIP = req.headers['x-forwarded-for'] || req.connection.remoteAddress;
logger.debug("production message");
});
module.exports = app;
And in my queries.js I try to do the following:
function getAllUsers(req, res, next) {
db.any('select * from users')
.then(function (data) {
res.status(200)
.json({
users: data
});
})
.catch(function (err) {
return next(err);
});
}
passport.use(new LocalStrategy(options, (username, password, done) => {
db.one('select * from users where id = $1', username)
.then(function (data) {
if(!data){
return done(null, user);
}else{
//Generete a jwt token and return it.
}
})
.catch((err) => { return done(err); });
});
My questions is:
Have I implemented passport correctly in my app.js?
Also the code in my queries.js failes at compile time, one of the issues iam facing is how to use the passport functionality around existing queries, for example the existing getAllUsers function and the function that fails were I try to lookup a username when trying to sign in.
My routes is placed in a index.js file:
router.get('/api/users', db.getAllUsers);
router.get('/api/user/:id', db.getSingleUser);
router.post('/api/users', db.createUser);
router.delete('/api/user/:id', db.deleteUser);
How do I encapsulate them in a passport method so some of them could only be called if the user calling them is valid?

How to share Session across multiple route JS files in ExpressJS

First of all, I am using:
express-session#1.14.2
express#4.14.0
I am basically trying to get a login system working and when user logs in, I set session.isloggedin = true.
So this is my app.js
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var session = require('express-session');
var index = require('./routes/index');
var portfolioRoute = require('./routes/portfolio');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'pug');
// CORS (Cross-Origin Resource Sharing) headers to support Cross-site HTTP requests
app.all('*', function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "X-Requested-With");
next();
});
// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use(session({
secret: 'keyboard cat',
resave: false,
saveUninitialized: true,
cookie: { secure: true,
maxAge: new Date(Date.now() + 2 * 60 * 1000) }
}));
app.use('/', index);
app.use('/portfolio', portfolioRoute);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
module.exports = app;
The index.html contains the login form.
Next, my index.js
var express = require('express');
var router = express.Router();
var util = require('util');
var api = require('../server/api.js');
var port = require('../server/portfolio.js');
var sess;
/* GET home page. */
router.get('/', function (req, res) {
sess = req.session;
console.log("SESSION IS: " + sess.isLoggedIn);
if(sess.isLoggedIn) {
res.render('portfolio', { isLoggedIn: true })
} else {
res.render('index', { isLoggedIn: false })
}
})
//END ------------
if(global.GLB_PORTFOLIO === null) {
port.getPortfolio(null, function(err, result) {
global.GLB_PORTFOLIO = result;
});
}
// API Routes
//router.use('/api', router);
router.route('/api/login')
.post(api.postLogin)
router.route('/api/portfolio')
.post(api.postPortfolio)
.get(api.getPortfolio)
//END ------------
module.exports = router;
Next, my api.js:
var util = require('util');
const backend = require('./portfolio.js');
exports.postPortfolio = function(req,res) {
backend.insertPortFolio(req.body, function(err, result) {
res.json({ result: result, error:err });
});
}
exports.getPortfolio = function(req,res) {
backend.getPortfolio(req, function(err, result) {
global.GLB_PORTFOLIO = result;
res.json({ portfolio: result, error: err });
});
}
exports.postLogin = function(req,res) {
backend.findUserByEmail(req.body.email, function(err, result) {
console.log("API: SESSION IS: " + req.session.isLoggedIn);
if(err || result === null) {
req.session.isLoggedIn = false;
} else {
req.session.isLoggedIn = true;
}
req.session.save();
res.json({ user: result, error: err });
});
}
The session variable is always undefined even after the save(). What am I doing wrong?

node express express.static prevents access from root path '/'

I am using express and I have a catch all route
router.use('*',function(){...});
and a root route
router.use('/', function(){...});
I have this route placed after the
app.use(express.static(path.join(__dirname, 'public')));
this causes my routes to not fire when placed below the previous line. however if I put my routes above it my catch all is also called on static asset requests. is there a way I can catch all requests except for the assets in my public folder including the route '/'? I don't want to resort to using regex and having to update it every time a directory is added to the public directory.
sorry for not being more details here are the relavant files
//app.js
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var routes = require('./routes/index');
var users = require('./routes/users');
var app = express();
/* This is going to initialize the menubar for nwjs it is currently commented out as this is a non issue at this point
setTimeout(function () {
//initialize passport
var passport = require('./helpers/passport.js');
//setup routes
//setup window menu
console = window.console;
console.log(passport);
passport.init(app);
var gui = window.require('nw.gui');
var win = gui.Window.get();
var menu = new gui.Menu({
type: 'menubar'
});
menu.createMacBuiltin('jist', {
hideEdit: true,
hideWindow: true
});
gui.Window.get().menu = menu;
},1000);*/
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
extended: false
}));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', routes);
app.use('/users', users);
// catch 404 and forward to error handler
app.use(function (req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
// error handlers
// development error handler
// will print stacktrace
if (app.get('env') === 'development') {
app.use(function (err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: err
});
});
}
// production error handler
// no stacktraces leaked to user
app.use(function (err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: {}
});
});
module.exports = app;
//window.location.href="http://localhost:3000";
this is my index router
//routes/index.js
var express = require('express');
var router = express.Router();
/* GET home page. */
router.use('*', function(req, res, nex){
var path = req.originalPath;
if(~['/users/login', '/users/signup'].indexOf(path) || req.user) return next();
if(!req.user) return res.redirect('/users/login');
});
router.get('/', function(req, res, next) {
res.render('index', { title: 'Express' });
});
module.exports = router;

node/express - exporting controller functionality

I am building a Node API on express which takes GET requests and uses the parameters supplied by the client to return the results of GET requests made to other API's.
In order to keep the controller thin when adding more API's I would like to export the logic within the controller into a separate .js file, and module.export those functions back in, to be used in the controller. The problem here is that the functions that are being exported do not appear to be visible within the controller.
Pasted below is before and after code to illustrate progress made so far.
app.js (before) - see router.get('/')
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var request = require('request');
var routes = require('./routes/index');
var users = require('./routes/users');
var app = express();
var router = express.Router();
if ( app.get('env') === 'development') {
var dotenv = require('dotenv');
dotenv.load();
};
var prodAdv = require('./lib/prod-adv.js')
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', routes);
app.use('/users', users);
app.use('/api', router);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
// error handlers
// development error handler
// will print stacktrace
if (app.get('env') === 'development') {
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: err
});
});
}
// production error handler
// no stacktraces leaked to user
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: {}
});
});
router.get('/', function(req, res) {
request('https://openapi.etsy.com/v2/listings/active?includes=Images&keywords=' + req.param('SearchIndex') + '&limit=100&api_key=' + process.env.ETSY_KEY, function(error, response, body) {
res.header({'Access-Control-Allow-Origin': '*'});
var data = JSON.parse(body);
res.json(data);
});
});
router.use('*', function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, accept, authorization");
next();
});
var server = app.listen(9876, function() {
var host = server.address().address;
var port = server.address().port;
console.log('Example app listening at http://%s:%s',host,port);
});
module.exports = app;
This approach works, returning JSON objects. However the following approach to try and export the code does not work.
apiCaller.js
var express = require('express');
var app = express();
if ( app.get('env') === 'development' ) { var dotenv = require('dotenv'); dotenv.load(); };
var request = require('request');
var call, response;
var call = function(searchIndex) {
return request('https://openapi.etsy.com/v2/listings/active?includes=Images&keywords=' + searchIndex + '&limit=100&api_key=' + process.env.ETSY_KEY, function(error, response, body) {
response = JSON.parse(body);
});
};
module.exports.response = response;
module.exports.call = call;
app.js (after)
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var squid = require('./lib/apiCaller.js');
var routes = require('./routes/index');
var users = require('./routes/users');
var app = express();
var router = express.Router();
if ( app.get('env') === 'development') {
var dotenv = require('dotenv');
dotenv.load();
};
var prodAdv = require('./lib/prod-adv.js')
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', routes);
app.use('/users', users);
app.use('/api', router);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
// error handlers
// development error handler
// will print stacktrace
if (app.get('env') === 'development') {
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: err
});
});
}
// production error handler
// no stacktraces leaked to user
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: {}
});
});
router.get('/', function(req, res) {
squid.call(req.param('SearchIndex'));
res.header({'Access-Control-Allow-Origin': '*'});
res.json(squid.response);
});
router.use('*', function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, accept, authorization");
next();
});
var server = app.listen(9876, function() {
var host = server.address().address;
var port = server.address().port;
console.log('Example app listening at http://%s:%s',host,port);
});
module.exports = app;
What occurs now in the browser is a 200 OK with an empty response body. console.logging the responses return undefined objects.
You need to rewrite your call function to have a callback since request(...) is asyncronous
var call = function(searchIndex, callback) {
request('https://openapi.etsy.com/v2/listings/active?includes=Images&keywords=' + searchIndex + '&limit=100&api_key=' + process.env.ETSY_KEY, function(error, response, body) {
if (!error && response.statusCode == 200) {
return callback(null, JSON.parse(body));
}
callback('error');
});
};
Only export call function, there's no need to export or even use response and no need for this line
var call, response;
Now you also need to use it a bit different way
router.get('/', function(req, res) {
res.header({'Access-Control-Allow-Origin': '*'});
squid.call(req.param('SearchIndex'), function(err, data){
if(!err) return res.json(data);
res.json({error: err});
});
});

Resources