1

I'm currently learning node, postgres, and passport but I am not sure on how to secure my application and best practices. I'm not sure on how to sanitize data from client and server or if it's needed but I've parameterized my queries. Any help would be greatly appreciated! Apologies for my newbieness.

var express = require('express');
var helmet = require('helmet')

var bodyParser = require('body-parser');
var cookieParser = require('cookie-parser');
var expressSession = require('express-session');

var passport = require('passport');
var passportLocal = require('passport-local');
var pg = require ('pg');
var bcrypt = require('bcryptjs');

var app = express();
app.use(helmet());
var server = require('http').createServer(app);
var io = require('socket.io')(server);

var config = {
  user: 'REDACTED',
  database: 'REDACTED',
  password: 'REDACTED',
  host: 'REDACTED',
  port: 5432,
  max: 10,
  idleTimeoutMillis: 30000,
};

var pool = new pg.Pool(config);
pool.on('error', function (err, client) {
  console.error('idle client error', err.message, err.stack)
})

app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(expressSession( {
  secret: process.env.SESSION_SECRET || 'secret',
  resave: false,
  saveUninitialized: false
}));

app.use(passport.initialize());
app.use(passport.session());

passport.use(new passportLocal.Strategy(function(username, password, done) {
  pool.connect(function(poolErr, poolClient, poolDone) {
    if(poolErr) {
      return console.error('pool client fetch error', poolErr);
    }

    poolClient.query('SELECT id, password FROM users WHERE username = $1', [username], function(queryErr, queryRes) {
      if(queryErr) {
        return console.error('query error', queryErr);
      }

      if(queryRes.rows[0] != undefined)
      {
          bcrypt.compare(password, queryRes.rows[0].password, function(compareErr, compareRes) {
            if(compareErr) {
              return console.error('bcrypt error', compareErr);
            }

            if(compareRes) {
                done(null, { id: queryRes.rows[0].id });
            } else {
                done(null, null);
            }

            poolDone();
          });
      } else {
        //user not found
        poolDone();
        done(null, null);
      }
    });
  });
  
}));


passport.serializeUser(function(user, done) {
  done(null, user.id);
});

passport.deserializeUser(function(id, done) {
  pool.connect(function(err, poolClient, poolDone) {
    if(err) {
      return console.error('pool client fetch error', err);
    }

    poolClient.query('SELECT * FROM users WHERE id = $1', [id], function(queryErr, queryRes) {
      if(queryErr) {
        return console.error('query error', queryErr);
      }

      if(queryRes.rows[0] != undefined)
      {
        done(null, { id: id, username: queryRes.rows[0].username, firstname: queryRes.rows[0].firstname, lastname: queryRes.rows[0].lastname });
      } else {
        //user not found
	done(null, null);
      }

      poolDone();
    });
  });
  
});

app.set('view engine', 'ejs');

app.get('/', function(req, res) {
  res.render('index', {
    isAuthenticated: req.isAuthenticated(),
    user: req.user
  })
});


app.get('/login', function(req, res) {
  res.render('login');
});

app.post('/login', passport.authenticate('local'), function(req, res) {
  res.redirect('/');
});

app.get('/logout', function(req, res) {
  req.logout();
  res.redirect('/');
});

server.listen(8080);
console.log('Server is running...');

2 Answers 2

2

I don't see much problem but here is my 2 cent to improve it.

Use compression to reduce network size

app.use(require('compression'));

Use serve-static for static file like images or pdf

app.use(require('serve-static')('./public'))

Use middleware to control end point that need Authentication like view/edit profile, change password and etc

function authenticated(req, res, next) {
  if (req.isAuthenticated()) next();
  else {
    res.status(401).send('User not authenticated.');
    // or redirect to login
  }
}

app.get('/profile', authenticated, function(req, res) {
  res.render('profile', {
    req.user
  })
})

Include session destroy when logout

app.get('/logout', function(req, res) {
  req.session.destroy();
  req.logout();
  res.redirect('/');
});
Sign up to request clarification or add additional context in comments.

Comments

1

for sanitizing queries you can use ORM like sequelise

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.