├── package.json ├── lib ├── index.js └── strategy.js ├── README.md └── LICENSE /package.json: -------------------------------------------------------------------------------- 1 | {"name":"passport-one-session-per-user","version":"1.0.3","description":"This passport strategy force every user to be connected only from one session","main":"lib/index.js","scripts":{"test":"echo \"Error: no test specified\" && exit 1"},"author":"","license":"ISC"} -------------------------------------------------------------------------------- /lib/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Module dependencies. 3 | */ 4 | var Strategy = require('./strategy'); 5 | 6 | 7 | /** 8 | * Expose `Strategy` directly from package. 9 | */ 10 | exports = module.exports = Strategy; 11 | 12 | /** 13 | * Export constructors. 14 | */ 15 | exports.Strategy = Strategy; 16 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # passport-one-session-per-user 2 | 3 | This strategy check if the user that trying to connect is already connected in other sessions. 4 | If so, it will disconnect the previous sessions. 5 | 6 | How to install 7 | --- 8 | 9 | npm i -s passport-one-session-per-user 10 | 11 | How to use 12 | --- 13 | 14 | var passportOneSessionPerUser=require('passport-one-session-per-user') 15 | passport.use(new passportOneSessionPerUser()) 16 | app.use(passport.authenticate('passport-one-session-per-user')) 17 | 18 | That's all. 19 | 20 | **Note:** The information about sessionIDs, and users, is saved in memory. So it's not recommended when running in cluster, or multi process node.exe. 21 | 22 | --- 23 | 24 | Pull requests are welcome :) So if you have any fix, please fork, and create pull request. -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | (The MIT License) 2 | 3 | Copyright (c) 2011-2013 Jared Hanson 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /lib/strategy.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Creates an instance of `Strategy`. 3 | * 4 | * @constructor 5 | * @api public 6 | */ 7 | function Strategy() { 8 | this.name = 'passport-one-session-per-user' 9 | } 10 | 11 | /** 12 | * Authenticate request. 13 | * 14 | * This function must be overridden by subclasses. In abstract form, it always 15 | * throws an exception. 16 | * 17 | * @param {Object} req The request to authenticate. 18 | * @param {Object} [options] Strategy-specific options. 19 | * @api public 20 | */ 21 | var loggedInUsers = [] 22 | 23 | var passport = require('passport') 24 | 25 | Strategy.prototype.authenticate = function(req) { 26 | var self = this; 27 | 28 | // If there is not logged in user, do nothing. 29 | if (!req.user) { 30 | return self.pass() 31 | } 32 | 33 | // If there is logged in user, let's see if he exists in [loggedInUsers] array 34 | passport.serializeUser(req.user, function(err, thisUserId) { 35 | var found = false 36 | for (var i = 0; i < loggedInUsers.length; i++) { 37 | if (thisUserId == loggedInUsers[i].user) { 38 | if (loggedInUsers[i].sessionID != req.sessionID) { 39 | //Same user logged in from other session 40 | // Flag him to `logout` next time he request and pge 41 | 42 | loggedInUsers[i].logout = true; 43 | } else if (loggedInUsers[i].logout) { 44 | // This user flagged to logout. Log him out, and remove this instance from array; 45 | found = true 46 | loggedInUsers.splice(i, 1) 47 | req.logout() 48 | return self.pass() 49 | } else { 50 | // this user and this sessionID already in Array. 51 | // We don't need to do add him again. 52 | found = true 53 | } 54 | } 55 | } 56 | 57 | // If the current session && curred User not in Array. Add it to array 58 | if (!found) { 59 | loggedInUsers.push({ 60 | user: thisUserId, 61 | sessionID: req.sessionID 62 | }) 63 | } 64 | self.pass() 65 | }); 66 | }; 67 | 68 | 69 | /** 70 | * Expose `Strategy`. 71 | */ 72 | module.exports = Strategy; 73 | --------------------------------------------------------------------------------