From 19cd9e05edf1f791e6c6c1bed7ad27ea8768aeaa Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Sun, 28 Apr 2013 13:28:20 -0400 Subject: [PATCH 1/6] fixing login and logout sessions --- public/templates/login.tpl | 3 +- src/user.js | 58 ++++++++++++++++++-------------------- src/webserver.js | 43 ++++++++++++++++++++-------- 3 files changed, 59 insertions(+), 45 deletions(-) diff --git a/public/templates/login.tpl b/public/templates/login.tpl index b73f8749b7..d4756927a7 100644 --- a/public/templates/login.tpl +++ b/public/templates/login.tpl @@ -30,8 +30,7 @@ jQuery('#error').show(50); jQuery('#error p').html(data.message); } else { - jQuery('#error').hide(50); - ajaxify.go('/'); + document.location.href = '/'; } }); }()); diff --git a/src/user.js b/src/user.js index 7075519cb9..46434ca34a 100644 --- a/src/user.js +++ b/src/user.js @@ -33,25 +33,17 @@ var config = require('../config.js'), global.uid = uid; - global.socket.emit('event:alert', { - title: 'Welcome ' + user.username, - message: 'You have successfully logged in.', - type: 'notify', - timeout: 2000 - }); - return global.socket.emit('user.login', {'status': 1, 'message': 'Logged in!'}); } }); }); }; - User.logout = function(callback) { - RDB.get('uid:' + global.uid + ':session', function(sessionID) { - if (sessionID) { + User.logout = function(sessionID, callback) { + User.get_uid_by_session(sessionID, function(uid) { + if (uid) { RDB.del('sess:' + sessionID + ':uid'); - RDB.del('uid:' + global.uid + ':session'); - global.uid = null; + RDB.del('uid:' + uid + ':session'); callback(true); } else callback(false); }); @@ -236,32 +228,36 @@ var config = require('../config.js'), }, keys = []; - for(var a in active) { - keys.push('sess:' + active[a].split(':')[1] + ':uid'); - } + if (active.length > 0) { + for(var a in active) { + keys.push('sess:' + active[a].split(':')[1] + ':uid'); + } - RDB.mget(keys, function(uids) { - for(var u in uids) { - if (uids[u] !== null) { - if (returnObj.uids.indexOf(uids[u]) === -1) { - returnObj.users++; - returnObj.uids.push(uids[u]); + RDB.mget(keys, function(uids) { + for(var u in uids) { + if (uids[u] !== null) { + if (returnObj.uids.indexOf(uids[u]) === -1) { + returnObj.users++; + returnObj.uids.push(uids[u]); + } + } else { + returnObj.anon++; } - } else { - returnObj.anon++; } - } - if (callback === undefined) { - global.socket.emit('api:user.active.get', returnObj) - } else { - callback(returnObj); - } - }); + if (callback === undefined) { + global.socket.emit('api:user.active.get', returnObj) + } else { + callback(returnObj); + } + }); + } else { + global.socket.emit('api:user.active.get', returnObj) + } }); }, register: function(sessionID) { - RDB.set('active:' + sessionID, 60*10); // Active state persists for 10 minutes + RDB.set('active:' + sessionID, '', 60*10); // Active state persists for 10 minutes } } }(exports)); \ No newline at end of file diff --git a/src/webserver.js b/src/webserver.js index b1d7b5d085..4e32d25aa3 100644 --- a/src/webserver.js +++ b/src/webserver.js @@ -36,18 +36,33 @@ var express = require('express'), key: 'express.sid' })); app.use(function(req, res, next) { - if (global.uid === undefined) { - console.log('info: [Auth] First load, retrieving uid...'); - global.modules.user.get_uid_by_session(req.sessionID, function(uid) { - global.uid = uid; - if (global.uid !== null) console.log('info: [Auth] uid ' + global.uid + ' found. Welcome back.'); - else console.log('info: [Auth] No login session found.'); - }); + var hasExtension = /\.[\w]{2,4}$/; + if (!hasExtension.test(req.url.indexOf('?') !== -1 ? req.url.substr(0, req.url.indexOf('?')) : req.url)) { + console.log('REQUESTING: ' + req.url); + if (req.session.uid === undefined) { + console.log('info: [Auth] First load, retrieving uid...'); + global.modules.user.get_uid_by_session(req.sessionID, function(uid) { + if (uid !== null) { + req.session.uid = uid; + + global.socket.emit('event:alert', { + title: 'Welcome ' + user.username, + message: 'You have successfully logged in.', + type: 'notify', + timeout: 2000 + }); + } else req.session.uid = 0; + + if (req.session.uid) console.log('info: [Auth] uid ' + req.session.uid + ' found. Welcome back.'); + else console.log('info: [Auth] No login session found.'); + }); + } else { + // console.log('SESSION: ' + req.sessionID); + // console.log('info: [Auth] Ping from uid ' + req.session.uid); + } // (Re-)register the session as active global.modules.user.active.register(req.sessionID); - } else { - console.log('info: [Auth] Ping from uid ' + global.uid); } next(); @@ -85,6 +100,7 @@ var express = require('express'), break; default : res.send('{}'); + break; } }); @@ -94,8 +110,11 @@ var express = require('express'), app.get('/logout', function(req, res) { console.log('info: [Auth] Session ' + res.sessionID + ' logout (uid: ' + global.uid + ')'); - global.modules.user.logout(function(logout) { - if (logout === true) req.session.destroy(); + global.modules.user.logout(req.sessionID, function(logout) { + if (logout === true) { + delete(req.session.uid); + req.session.destroy(); + } }); res.send(templates['header'] + templates['logout'] + templates['footer']); @@ -125,7 +144,7 @@ var express = require('express'), module.exports.init = function() { // todo move some of this stuff into config.json app.configure(function() { - app.use(express.static(global.configuration.ROOT_DIRECTORY + '/public')); + app.use(express.static(global.configuration.ROOT_DIRECTORY + '/public')); }); } }(WebServer)); From f4b14df19590001433669052d33db508a75e3bc1 Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Sun, 28 Apr 2013 13:58:19 -0400 Subject: [PATCH 2/6] some more fixes to the session handling to ignore the /api folder, and refactoring how the public directory is set up in webserver.js. THIS COMMIT ALTERS NODEBB'S DEPENDENCIES! Please run npm install after pulling. --- app.js | 2 +- package.json | 3 ++- public/templates/login.tpl | 1 - src/webserver.js | 25 +++++++++---------------- 4 files changed, 12 insertions(+), 19 deletions(-) diff --git a/app.js b/app.js index 8ab74cf957..8732c4aee4 100644 --- a/app.js +++ b/app.js @@ -22,7 +22,7 @@ global.modules = modules; config['ROOT_DIRECTORY'] = __dirname; modules.templates.init(); - modules.webserver.init(); + // modules.webserver.init(); modules.websockets.init(); diff --git a/package.json b/package.json index f51de29b2c..62729ea37c 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,8 @@ "connect": "2.7.6", "emailjs": "0.3.4", "cookie": "0.0.6", - "connect-redis": "1.4.5" + "connect-redis": "1.4.5", + "path": "0.4.9" }, "devDependencies": {}, "optionalDependencies": {}, diff --git a/public/templates/login.tpl b/public/templates/login.tpl index d4756927a7..e9a96e7862 100644 --- a/public/templates/login.tpl +++ b/public/templates/login.tpl @@ -25,7 +25,6 @@ ajaxify.register_events(['user.login']); socket.on('user.login', function(data) { - console.log(data); if (data.status === 0) { jQuery('#error').show(50); jQuery('#error p').html(data.message); diff --git a/src/webserver.js b/src/webserver.js index 4e32d25aa3..db5e72b2f7 100644 --- a/src/webserver.js +++ b/src/webserver.js @@ -1,7 +1,8 @@ var express = require('express'), WebServer = express(), server = require('http').createServer(WebServer), - RedisStore = require('connect-redis')(express); + RedisStore = require('connect-redis')(express), + path = require('path'), config = require('../config.js'); (function(app) { @@ -26,8 +27,10 @@ var express = require('express'), // Middlewares app.use(express.favicon()); // 2 args: string path and object options (i.e. expire time etc) + app.use(express.static(path.join(__dirname, '../', 'public'))); app.use(express.bodyParser()); // Puts POST vars in request.body app.use(express.cookieParser()); // If you want to parse cookies (res.cookies) + app.use(express.compress()); app.use(express.session({ store: new RedisStore({ ttl: 60*60*24*14 @@ -36,9 +39,8 @@ var express = require('express'), key: 'express.sid' })); app.use(function(req, res, next) { - var hasExtension = /\.[\w]{2,4}$/; - if (!hasExtension.test(req.url.indexOf('?') !== -1 ? req.url.substr(0, req.url.indexOf('?')) : req.url)) { - console.log('REQUESTING: ' + req.url); + // Don't bother with session handling for API requests + if (!/^\/api\//.test(req.url)) { if (req.session.uid === undefined) { console.log('info: [Auth] First load, retrieving uid...'); global.modules.user.get_uid_by_session(req.sessionID, function(uid) { @@ -60,11 +62,11 @@ var express = require('express'), // console.log('SESSION: ' + req.sessionID); // console.log('info: [Auth] Ping from uid ' + req.session.uid); } - - // (Re-)register the session as active - global.modules.user.active.register(req.sessionID); } + // (Re-)register the session as active + global.modules.user.active.register(req.sessionID); + next(); }); // Dunno wtf this does @@ -78,8 +80,6 @@ var express = require('express'), }); }); - - app.get('/topics/:topic_id', function(req, res) { global.modules.topics.generate_topic_body(function(topic_body) { res.send(templates['header'] + topic_body + templates['footer']); @@ -140,13 +140,6 @@ var express = require('express'), app.get('/403', function(req, res) { res.send(templates['header'] + templates['403'] + templates['footer']); }); - - module.exports.init = function() { - // todo move some of this stuff into config.json - app.configure(function() { - app.use(express.static(global.configuration.ROOT_DIRECTORY + '/public')); - }); - } }(WebServer)); server.listen(config.port); From 33f155b2d15cdd34dcdb9d202f179ceaebf0fe50 Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Sun, 28 Apr 2013 15:39:40 -0400 Subject: [PATCH 3/6] updating web sockets so that uid is populated for socket calls --- src/websockets.js | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/websockets.js b/src/websockets.js index 122765b6bb..321ed6e4ba 100644 --- a/src/websockets.js +++ b/src/websockets.js @@ -4,7 +4,8 @@ var SocketIO = require('socket.io').listen(global.server), (function(io) { var modules = null, - sessionID; + sessionID, + uid; global.io = io; module.exports.init = function() { @@ -27,7 +28,12 @@ var SocketIO = require('socket.io').listen(global.server), // Otherwise, continue unimpeded. sessionID = handshakeData.sessionID; - accept(null, true); + global.modules.user.get_uid_by_session(sessionID, function(session_uid) { + if (session_uid) uid = session_uid; + else uid = 0; + + accept(null, true); + }); }); io.sockets.on('connection', function(socket) { From 570dfd9786479993d6d6a83b94977772f60a4041 Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Sun, 28 Apr 2013 15:41:26 -0400 Subject: [PATCH 4/6] updated topics module to use uid as a passed in param, instead of through global.uid --- src/topics.js | 12 ++++++------ src/websockets.js | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/topics.js b/src/topics.js index 4265e3b12c..caef722f6b 100644 --- a/src/topics.js +++ b/src/topics.js @@ -99,8 +99,8 @@ var RDB = require('./redis.js'), } - Topics.post = function(title, content, category) { - if (global.uid === null) { + Topics.post = function(uid, title, content, category) { + if (uid === 0) { global.socket.emit('event:alert', { title: 'Thank you for posting', message: 'Since you are unregistered, your post is awaiting approval. Click here to register now.', @@ -115,8 +115,8 @@ var RDB = require('./redis.js'), RDB.incr('global:next_topic_id', function(tid) { // Global Topics - if (global.uid == null) global.uid = 0; - if (global.uid !== null) { + if (uid == null) uid = 0; + if (uid !== null) { RDB.lpush('topics:tid', tid); } else { // need to add some unique key sent by client so we can update this with the real uid later @@ -133,7 +133,7 @@ var RDB = require('./redis.js'), // Topic Info RDB.set('tid:' + tid + ':title', title); - RDB.set('tid:' + tid + ':uid', global.uid); + RDB.set('tid:' + tid + ':uid', uid); RDB.set('tid:' + tid + ':slug', slug); RDB.set('tid:' + tid + ':timestamp', new Date().getTime()); RDB.incr('tid:' + tid + ':postcount'); @@ -147,7 +147,7 @@ var RDB = require('./redis.js'), // User Details - move this out later - RDB.lpush('uid:' + global.uid + ':topics', tid); + RDB.lpush('uid:' + uid + ':topics', tid); global.socket.emit('event:alert', { diff --git a/src/websockets.js b/src/websockets.js index 321ed6e4ba..99d2559a96 100644 --- a/src/websockets.js +++ b/src/websockets.js @@ -86,7 +86,7 @@ var SocketIO = require('socket.io').listen(global.server), }); socket.on('api:topics.post', function(data) { - modules.topics.post(data.title, data.content); + modules.topics.post(uid, data.title, data.content); }); socket.on('api:user.active.get', function() { From 7827534819055af7c50a899793a7a58c7b4a35eb Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Sun, 28 Apr 2013 15:56:44 -0400 Subject: [PATCH 5/6] tweaking active.register so that it emits an active user change --- src/user.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/user.js b/src/user.js index 46434ca34a..bc250e1c5f 100644 --- a/src/user.js +++ b/src/user.js @@ -258,6 +258,7 @@ var config = require('../config.js'), }, register: function(sessionID) { RDB.set('active:' + sessionID, '', 60*10); // Active state persists for 10 minutes + this.get(); } } }(exports)); \ No newline at end of file From 64ca3d7444e460bce4548fed4f26349178de1335 Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Sun, 28 Apr 2013 16:04:00 -0400 Subject: [PATCH 6/6] properly broadcasting a user.active change --- src/user.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/user.js b/src/user.js index bc250e1c5f..7b03bc4767 100644 --- a/src/user.js +++ b/src/user.js @@ -246,13 +246,13 @@ var config = require('../config.js'), } if (callback === undefined) { - global.socket.emit('api:user.active.get', returnObj) + io.sockets.emit('api:user.active.get', returnObj) } else { callback(returnObj); } }); } else { - global.socket.emit('api:user.active.get', returnObj) + io.sockets.emit('api:user.active.get', returnObj) } }); },