UNPKG

userauthjs

Version:

Node module for management of user/group privileges and sessions

122 lines (115 loc) 3.94 kB
var async = require('async') var bcrypt = require('bcrypt') var jwt = require('jwt-simple') var secret = process.env.USERAUTH_KEY var User = require('./models/user') var Usergroup = require('./models/usergroup') var Privilege = require('./models/privilege') var Session = require('./models/session') /** * Allow only a few active sessions per user * Decide if an session should have an timeout. * Usually an smartphone native app should not have an timeout */ exports.start = function(username, password, next, permanent) { permanent = typeof permanent !== 'undefined' ? permanent : false User.findOne({username: username}) .select('password') .select('username') .select('active') .select('usergroups') .exec(function(err, user) { if (err) { return next(err) } if (!user) { return next(null, false) } bcrypt.compare(password, user.password, function(err, valid) { if (err) { return next(err) } if (!valid) { return next(null, false) } var started = new Date() var token = jwt.encode({ username: user.username, userid: user._id, usergroups: user.usergroups, started: started }, process.env.USERAUTH_KEY) session = new Session({ user: user._id, token: token, permanent: permanent, started: started }) session.save(function(err, session) { if (err) { return next(err) } if (!session) { return next(null, false) } if (process.env.USERAUTH_LOG) { console.log('Userauth session started for: ' + username) } next(null, token) }) }) }) } exports.verify = function(token, privilege, next) { userinfo = decodeToken(token) if (!userinfo) { return next(null, false) } Session.findOne({ token: token }, function(err, session) { if (err) { return next(err) } if (!session) { return next(null, false) } var now = new Date() var validTime = session.started.getTime() + process.env.SESSION_TIMEOUT * 1000 if (!session.permanent && now.getTime() > validTime) { return next(null, false) } Privilege.findOne({ title: privilege }, function(err, privilege) { if (err) { return next(err) } if (!privilege) { return next(null, false) } User.findOne({ _id: userinfo.userid }, function(err, user) { if (err) { return next(err) } if (!user) { return next(null, false) } var validUsergroup = false for (var i = 0; i < user.usergroups.length; i++) { if (privilege.usergroups.indexOf(user.usergroups[i]) > -1) { validUsergroup = true } } if (privilege.users.indexOf(user._id) > -1 || validUsergroup) { next(null, userinfo) } else { next(null, false) } }) }) }) } exports.stop = function(token, next) { Session.findOneAndRemove({ token: token }, function(err, session) { if (err) { return next(err) } if (!session) { return next(null, false) } var userinfo = decodeToken(token) if (process.env.USERAUTH_LOG) { console.log('Userauth session stopped for: ' + userinfo.username) } next(null, userinfo) }) } exports.stopAll = function(userid, next) { var userinfo Session.find({ user: userid }) .populate('user') .exec(function(err, sessions) { if (err) { return next(err) } if (!sessions) { return next(null, false) } if (sessions.length < 1) { return next(null, false) } var iSession = 1 async.each(sessions, function(session, done) { session.remove(function(err, session) { if (err) { return done(err) } userinfo = decodeToken(session.token) if (process.env.USERAUTH_LOG) { console.log('Userauth session (' + iSession + '/' + sessions.length + ') stopped for: ' + userinfo.username) } iSession++ done() }) }, function(err) { if (err) { return next(err) } if (process.env.USERAUTH_LOG) { console.log('All userauth sessions stopped for: ' + userinfo.username) } next(null, userinfo) }) }) } var decodeToken = function (token) { return jwt.decode(token, process.env.USERAUTH_KEY) } exports.decodeToken = decodeToken