Skip to content

Commit

Permalink
Add Logout Everywhere
Browse files Browse the repository at this point in the history
  • Loading branch information
vimark1 authored and YasharF committed Feb 2, 2025
1 parent 2edc559 commit 2efc3e8
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 1 deletion.
1 change: 1 addition & 0 deletions app.js
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,7 @@ app.get('/account', passportConfig.isAuthenticated, userController.getAccount);
app.post('/account/profile', passportConfig.isAuthenticated, userController.postUpdateProfile);
app.post('/account/password', passportConfig.isAuthenticated, userController.postUpdatePassword);
app.post('/account/delete', passportConfig.isAuthenticated, userController.postDeleteAccount);
app.post('/account/logout-everywhere', passportConfig.isAuthenticated, userController.postLogoutEverywhere);
app.get('/account/unlink/:provider', passportConfig.isAuthenticated, userController.getOauthUnlink);

/**
Expand Down
21 changes: 21 additions & 0 deletions controllers/user.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ const _ = require('lodash');
const validator = require('validator');
const mailChecker = require('mailchecker');
const User = require('../models/User');
const Session = require('../models/Session');

const randomBytesAsync = promisify(crypto.randomBytes);

Expand Down Expand Up @@ -542,3 +543,23 @@ exports.postForgot = (req, res, next) => {
.then(() => res.redirect('/forgot'))
.catch(next);
};

/**
* POST /account/logout-everywhere
* Logout current user from all devices
*/
exports.postLogoutEverywhere = async (req, res, next) => {
const userId = req.user.id;
try {
await Session.removeSessionByUserId(userId);
req.logout((err) => {
if (err) {
return next(err);
}
req.flash('info', { msg: 'You have been logged out of all sessions.' });
res.redirect('/');
});
} catch (err) {
return next(err);
}
};
24 changes: 24 additions & 0 deletions models/Session.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
const mongoose = require('mongoose');

const sessionSchema = new mongoose.Schema({
session: String,
expires: Date,
});

sessionSchema.statics = {
/**
* Removes all valid sessions for a given user
* @param {string} userId
* @returns {Promise}
*/
removeSessionByUserId(userId) {
return this.deleteMany({
expires: { $gt: new Date() },
session: { $regex: userId }
});
}
};

const Session = mongoose.model('Session', sessionSchema);

module.exports = Session;
15 changes: 14 additions & 1 deletion views/account/profile.pug
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,19 @@ block content
i.fas.fa-lock.fa-sm.iconpadding
| Change Password

.pb-2.mt-2.mb-4.border-bottom
h3 Logout Everywhere

form(action='/account/logout-everywhere', method='POST')
input(type='hidden', name='_csrf', value=_csrf)
.form-group
p.offset-sm-3.col-md-7.pl-2 This will log you out of all devices and locations.

.offset-sm-3.col-md-7.pl-2
button.btn.btn-danger(type='submit')
i.fas.fa-sm.iconpadding.fa-sign-out-alt
| Logout everywhere

.pb-2.mt-2.mb-4.border-bottom
h3 Delete Account

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

0 comments on commit 2efc3e8

Please sign in to comment.