diff --git a/public/src/app.js b/public/src/app.js index 21d0f4bf3d..7d64a87537 100644 --- a/public/src/app.js +++ b/public/src/app.js @@ -108,6 +108,31 @@ var socket, }; jQuery('document').ready(function() { + // On menu click, change "active" state + var menuEl = document.querySelector('.nav'), + liEls = menuEl.querySelectorAll('li'), + logoutEl = document.getElementById('logout'), + parentEl; + + menuEl.addEventListener('click', function(e) { + parentEl = e.target.parentNode; + if (parentEl.nodeName === 'LI') { + for(var x=0,numLis=liEls.length;x - - \ No newline at end of file diff --git a/public/templates/header.tpl b/public/templates/header.tpl index 8d6f9fa6b4..ecac91904d 100644 --- a/public/templates/header.tpl +++ b/public/templates/header.tpl @@ -11,140 +11,144 @@ -
-
-
- -
-
-
-
+ +
+
+
+
+ +
+
+
+
-
-
- - - - -
-
- Submit - Discard +
+
+ + + +
-
+ +
- + -
-
-
+
+
+
-
\ No newline at end of file +
\ No newline at end of file diff --git a/public/templates/logout.tpl b/public/templates/logout.tpl new file mode 100644 index 0000000000..987b4b68ef --- /dev/null +++ b/public/templates/logout.tpl @@ -0,0 +1,7 @@ +
+ Logout +

You have successfully logged out of NodeBB

+

+ NodeBB Home +

+
diff --git a/src/templates.js b/src/templates.js index 9c909aceec..4cd4ae86bf 100644 --- a/src/templates.js +++ b/src/templates.js @@ -27,6 +27,7 @@ var fs = require('fs'); loadTemplates([ 'header', 'footer', 'register', 'home', 'login', 'reset', 'reset_code', 'account_settings', + 'logout', 'emails/reset', 'emails/reset_plaintext' ]); } diff --git a/src/user.js b/src/user.js index 95ee11cf59..e08727f3d4 100644 --- a/src/user.js +++ b/src/user.js @@ -21,20 +21,33 @@ var config = require('../config.js'), return global.socket.emit('user.login', {'status': 0, 'message': 'Incorrect username / password combination.'}); } else { // Start, replace, or extend a session - RDB.get('session:' + user.sessionID, function(session) { + RDB.get('sess:' + user.sessionID, function(session) { if (session !== user.sessionID) { - RDB.set('session:' + user.sessionID, uid, 60*60*24*14); // Login valid for two weeks + RDB.set('sess:' + user.sessionID + ':uid', uid, 60*60*24*14); // Login valid for two weeks + RDB.set('uid:' + uid + ':session', user.sessionID, 60*60*24*14); } else { - RDB.expire('session:' + user.sessionID, 60*60*24*14); // Defer expiration to two weeks from now + RDB.expire('sess:' + user.sessionID + ':uid', 60*60*24*14); // Defer expiration to two weeks from now + RDB.expire('uid:' + uid + ':session', 60*60*24*14); } }); + global.uid = uid; 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) { + RDB.del('sess:' + sessionID + ':uid'); + RDB.del('uid:' + global.uid + ':session'); + global.uid = null; + callback(true); + } else callback(false); + }); + } User.create = function(username, password, email) { if (username == null || password == null) { @@ -104,7 +117,7 @@ var config = require('../config.js'), }; User.get_uid_by_session = function(session, callback) { - RDB.get('session:' + session, callback); + RDB.get('sess:' + session + ':uid', callback); }; User.reset = { diff --git a/src/webserver.js b/src/webserver.js index f166d1b7af..678ad74b19 100644 --- a/src/webserver.js +++ b/src/webserver.js @@ -15,30 +15,13 @@ var express = require('express'), } } - function hasAuth(req, res, next) { - // Include this middleware if the endpoint is publically accessible, but has elements that logged in users can see - global.modules.user.get_uid_by_session(req.sessionID, function(uid) { - if (uid) { - global.uid = uid; - console.log('info: [Auth] User is logged in as uid: ' + uid); - } else { - console.log('info: [Auth] User is not logged in'); - } - - next(); - }); - } - function requireAuth(req, res, next) { // Include this middleware if the endpoint requires a logged in user to view - hasAuth(req, res, function() { - if (!global.uid) { - res.redirect('/403'); - } else { - console.log('info: [Auth] User is logged in as uid: ' + uid); - next(); - } - }); + if (!global.uid) { + res.redirect('/403'); + } else { + next(); + } } // Middlewares @@ -46,16 +29,32 @@ var express = require('express'), 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.session({ - store: new RedisStore(), + store: new RedisStore({ + ttl: 60*60*24*14 + }), secret: 'nodebb', 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.'); + }); + } else { + console.log('info: [Auth] Ping from uid ' + global.uid); + } + + next(); + }); // Dunno wtf this does // app.use(express.logger({ format: '\x1b[1m:method\x1b[0m \x1b[33m:url\x1b[0m :response-time ms' })); // Useful if you want to use app.put and app.delete (instead of app.post all the time) // app.use(express.methodOverride()); - app.get('/', hasAuth, function(req, res) { + app.get('/', function(req, res) { global.modules.topics.generate_forum_body(function(forum_body) { res.send(templates['header'] + forum_body + templates['footer']); }) @@ -63,10 +62,19 @@ var express = require('express'), //res.send(templates['header'] + templates['home'] + templates['footer']); }); - app.get('/login', hasAuth, function(req, res) { + app.get('/login', function(req, res) { res.send(templates['header'] + templates['login'] + templates['footer']); }); + 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(); + }); + + res.send(templates['header'] + templates['logout'] + templates['footer']); + }); + app.get('/reset/:code', function(req, res) { res.send(templates['header'] + templates['reset_code'].parse({ reset_code: req.params.code }) + templates['footer']); });