Skip to content

Commit 6aa82de

Browse files
authored
Added Logout Everywhere
Added logout functionality to allow users to log out from all devices and locations. --------- authored-by: vimark <[email protected]>
1 parent 2edc559 commit 6aa82de

File tree

4 files changed

+60
-1
lines changed

4 files changed

+60
-1
lines changed

app.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,7 @@ app.get('/account', passportConfig.isAuthenticated, userController.getAccount);
169169
app.post('/account/profile', passportConfig.isAuthenticated, userController.postUpdateProfile);
170170
app.post('/account/password', passportConfig.isAuthenticated, userController.postUpdatePassword);
171171
app.post('/account/delete', passportConfig.isAuthenticated, userController.postDeleteAccount);
172+
app.post('/account/logout-everywhere', passportConfig.isAuthenticated, userController.postLogoutEverywhere);
172173
app.get('/account/unlink/:provider', passportConfig.isAuthenticated, userController.getOauthUnlink);
173174

174175
/**

controllers/user.js

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ const _ = require('lodash');
66
const validator = require('validator');
77
const mailChecker = require('mailchecker');
88
const User = require('../models/User');
9+
const Session = require('../models/Session');
910

1011
const randomBytesAsync = promisify(crypto.randomBytes);
1112

@@ -542,3 +543,23 @@ exports.postForgot = (req, res, next) => {
542543
.then(() => res.redirect('/forgot'))
543544
.catch(next);
544545
};
546+
547+
/**
548+
* POST /account/logout-everywhere
549+
* Logout current user from all devices
550+
*/
551+
exports.postLogoutEverywhere = async (req, res, next) => {
552+
const userId = req.user.id;
553+
try {
554+
await Session.removeSessionByUserId(userId);
555+
req.logout((err) => {
556+
if (err) {
557+
return next(err);
558+
}
559+
req.flash('info', { msg: 'You have been logged out of all sessions.' });
560+
res.redirect('/');
561+
});
562+
} catch (err) {
563+
return next(err);
564+
}
565+
};

models/Session.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
const mongoose = require('mongoose');
2+
3+
const sessionSchema = new mongoose.Schema({
4+
session: String,
5+
expires: Date,
6+
});
7+
8+
sessionSchema.statics = {
9+
/**
10+
* Removes all valid sessions for a given user
11+
* @param {string} userId
12+
* @returns {Promise}
13+
*/
14+
removeSessionByUserId(userId) {
15+
return this.deleteMany({
16+
expires: { $gt: new Date() },
17+
session: { $regex: userId }
18+
});
19+
}
20+
};
21+
22+
const Session = mongoose.model('Session', sessionSchema);
23+
24+
module.exports = Session;

views/account/profile.pug

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,19 @@ block content
7373
i.fas.fa-lock.fa-sm.iconpadding
7474
| Change Password
7575

76+
.pb-2.mt-2.mb-4.border-bottom
77+
h3 Logout Everywhere
78+
79+
form(action='/account/logout-everywhere', method='POST')
80+
input(type='hidden', name='_csrf', value=_csrf)
81+
.form-group
82+
p.offset-sm-3.col-md-7.pl-2 This will log you out of all devices and locations.
83+
84+
.offset-sm-3.col-md-7.pl-2
85+
button.btn.btn-danger(type='submit')
86+
i.fas.fa-sm.iconpadding.fa-sign-out-alt
87+
| Logout everywhere
88+
7689
.pb-2.mt-2.mb-4.border-bottom
7790
h3 Delete Account
7891

@@ -137,4 +150,4 @@ block content
137150
if user.tumblr
138151
p.mb-1: a.text-danger(href='/account/unlink/tumblr') Unlink your Tumblr account
139152
else
140-
p.mb-1: a(href='/auth/tumblr') Link your Tumblr account
153+
p.mb-1: a(href='/auth/tumblr') Link your Tumblr account

0 commit comments

Comments
 (0)