Merge pull request #5651 from NodeBB/ban-improvements

Ban improvements
v1.18.x
psychobunny 8 years ago committed by GitHub
commit da5a0d8881

@ -44,5 +44,10 @@
"unsub.cta": "Click here to alter those settings", "unsub.cta": "Click here to alter those settings",
"banned.subject": "You have been banned from %1",
"banned.text1": "The user %1 has been banned from %2.",
"banned.text2": "This ban will last until %1.",
"banned.text3": "This is the reason why you have been banned:",
"closing": "Thanks!" "closing": "Thanks!"
} }

@ -37,6 +37,7 @@
"user-banned": "User banned", "user-banned": "User banned",
"user-banned-reason": "Sorry, this account has been banned (Reason: %1)", "user-banned-reason": "Sorry, this account has been banned (Reason: %1)",
"user-banned-reason-until": "Sorry, this account has been banned until %1 (Reason: %2)",
"user-too-new": "Sorry, you are required to wait %1 second(s) before making your first post", "user-too-new": "Sorry, you are required to wait %1 second(s) before making your first post",
"blacklisted-ip": "Sorry, your IP address has been banned from this community. If you feel this is in error, please contact an administrator.", "blacklisted-ip": "Sorry, your IP address has been banned from this community. If you feel this is in error, please contact an administrator.",
"ban-expiry-missing": "Please provide an end date for this ban", "ban-expiry-missing": "Please provide an end date for this ban",

@ -10,7 +10,6 @@ app.cacheBuster = null;
(function () { (function () {
var showWelcomeMessage = !!utils.params().loggedin; var showWelcomeMessage = !!utils.params().loggedin;
var showBannedMessage = !!utils.params().banned && app.user && app.user.uid === 0;
templates.setGlobal('config', config); templates.setGlobal('config', config);
@ -266,11 +265,6 @@ app.cacheBuster = null;
title: '[[global:welcome_back]] ' + app.user.username + '!', title: '[[global:welcome_back]] ' + app.user.username + '!',
message: '[[global:you_have_successfully_logged_in]]', message: '[[global:you_have_successfully_logged_in]]',
}, },
banned: {
format: 'modal',
title: '[[error:user-banned]]',
message: '[[error:user-banned-reason, ' + utils.params().banned + ']]',
},
}; };
function showAlert(type) { function showAlert(type) {
@ -303,13 +297,6 @@ app.cacheBuster = null;
showAlert('login'); showAlert('login');
}); });
} }
if (showBannedMessage) {
showBannedMessage = false;
$(document).ready(function () {
showAlert('banned');
});
}
}; };
app.openChat = function (roomId, uid) { app.openChat = function (roomId, uid) {

@ -117,6 +117,8 @@ if (typeof window !== 'undefined') {
$.timeago.settings.cutoff = 1000 * 60 * 60 * 24 * (parseInt(config.timeagoCutoff, 10) || 30); $.timeago.settings.cutoff = 1000 * 60 * 60 * 24 * (parseInt(config.timeagoCutoff, 10) || 30);
} }
$.timeago.settings.allowFuture = true;
$.fn.timeago = function () { $.fn.timeago = function () {
var els = $(this); var els = $(this);

@ -121,7 +121,16 @@ app.isConnected = false;
app.isConnected = false; app.isConnected = false;
} }
function onEventBanned() { function onEventBanned(data) {
window.location.href = config.relative_path + '/'; var message = data.until ? '[[error:user-banned-reason-until, ' + $.timeago(data.until) + ', ' + data.reason + ']]' : '[[error:user-banned-reason, ' + data.reason + ']]';
bootbox.alert({
title: '[[error:user-banned]]',
message: message,
closeButton: false,
callback: function () {
window.location.href = config.relative_path + '/';
},
});
} }
}()); }());

@ -13,6 +13,7 @@ var user = require('../user');
var plugins = require('../plugins'); var plugins = require('../plugins');
var utils = require('../utils'); var utils = require('../utils');
var Password = require('../password'); var Password = require('../password');
var translator = require('../translator');
var sockets = require('../socket.io'); var sockets = require('../socket.io');
@ -379,24 +380,13 @@ authenticationController.localLogin = function (req, username, password, next) {
if (!result.isAdmin && parseInt(meta.config.allowLocalLogin, 10) === 0) { if (!result.isAdmin && parseInt(meta.config.allowLocalLogin, 10) === 0) {
return next(new Error('[[error:local-login-disabled]]')); return next(new Error('[[error:local-login-disabled]]'));
} }
if (!userData || !userData.password) { if (!userData || !userData.password) {
return next(new Error('[[error:invalid-user-data]]')); return next(new Error('[[error:invalid-user-data]]'));
} }
if (result.banned) { if (result.banned) {
// Retrieve ban reason and show error return banUser(uid, next);
return user.getLatestBanInfo(uid, function (err, banInfo) {
if (err) {
if (err.message === 'no-ban-info') {
next(new Error('[[error:user-banned]]'));
} else {
next(err);
}
} else if (banInfo.reason) {
next(new Error('[[error:user-banned-reason, ' + banInfo.reason + ']]'));
} else {
next(new Error('[[error:user-banned]]'));
}
});
} }
Password.compare(password, userData.password, next); Password.compare(password, userData.password, next);
@ -437,5 +427,25 @@ authenticationController.logout = function (req, res, next) {
} }
}; };
function banUser(uid, next) {
user.getLatestBanInfo(uid, function (err, banInfo) {
if (err) {
if (err.message === 'no-ban-info') {
return next(new Error('[[error:user-banned]]'));
}
return next(err);
}
if (!banInfo.reason) {
translator.translate('[[user:info.banned-no-reason]]', function (translated) {
banInfo.reason = translated;
next(new Error(banInfo.expiry ? '[[error:user-banned-reason-until, ' + banInfo.expiry_readable + ', ' + banInfo.reason + ']]' : '[[error:user-banned-reason, ' + banInfo.reason + ']]'));
});
} else {
next(new Error(banInfo.expiry ? '[[error:user-banned-reason-until, ' + banInfo.expiry_readable + ', ' + banInfo.reason + ']]' : '[[error:user-banned-reason, ' + banInfo.reason + ']]'));
}
});
}
module.exports = authenticationController; module.exports = authenticationController;

@ -105,7 +105,7 @@ module.exports = function (middleware) {
function (results, next) { function (results, next) {
if (results.banned) { if (results.banned) {
req.logout(); req.logout();
return res.redirect('/?banned=' + (results.banReason || 'no-reason')); return res.redirect('/');
} }
results.user.isAdmin = results.isAdmin; results.user.isAdmin = results.isAdmin;

@ -3,10 +3,13 @@
var async = require('async'); var async = require('async');
var user = require('../../user'); var user = require('../../user');
var meta = require('../../meta');
var websockets = require('../index'); var websockets = require('../index');
var events = require('../../events'); var events = require('../../events');
var privileges = require('../../privileges'); var privileges = require('../../privileges');
var plugins = require('../../plugins'); var plugins = require('../../plugins');
var emailer = require('../../emailer');
var translator = require('../../translator');
module.exports = function (SocketUser) { module.exports = function (SocketUser) {
SocketUser.banUsers = function (socket, data, callback) { SocketUser.banUsers = function (socket, data, callback) {
@ -36,6 +39,9 @@ module.exports = function (SocketUser) {
}); });
next(); next();
}, },
function (next) {
user.auth.revokeAllSessions(uid, next);
},
], next); ], next);
}, callback); }, callback);
}; };
@ -93,10 +99,38 @@ module.exports = function (SocketUser) {
if (isAdmin) { if (isAdmin) {
return next(new Error('[[error:cant-ban-other-admins]]')); return next(new Error('[[error:cant-ban-other-admins]]'));
} }
user.getUserField(uid, 'username', next);
},
function (username, next) {
var siteTitle = meta.config.title || 'NodeBB';
var data = {
subject: '[[email:banned.subject, ' + siteTitle + ']]',
site_title: siteTitle,
username: username,
until: until ? new Date(until).toString() : false,
reason: reason,
};
emailer.send('banned', uid, data, next);
},
function (next) {
user.ban(uid, until, reason, next); user.ban(uid, until, reason, next);
}, },
function (next) { function (next) {
websockets.in('uid_' + uid).emit('event:banned'); if (!reason) {
return translator.translate('[[user:info.banned-no-reason]]', function (translated) {
next(false, translated);
});
}
next(false, reason);
},
function (_reason, next) {
websockets.in('uid_' + uid).emit('event:banned', {
until: until,
reason: _reason,
});
next(); next();
}, },
], callback); ], callback);

@ -67,7 +67,7 @@ module.exports = function (User) {
} }
// If they are banned, see if the ban has expired // If they are banned, see if the ban has expired
var stillBanned = !userData['banned:expire'] || Date.now() < userData['banned:expire']; var stillBanned = !parseInt(userData['banned:expire'], 10) || Date.now() < parseInt(userData['banned:expire'], 10);
if (stillBanned) { if (stillBanned) {
return next(null, true); return next(null, true);

@ -41,7 +41,7 @@ module.exports = function (User) {
uid: uid, uid: uid,
timestamp: timestamp, timestamp: timestamp,
expiry: parseInt(expiry, 10), expiry: parseInt(expiry, 10),
expiry_readable: new Date(parseInt(expiry, 10)).toString().replace(/:/g, '%3A'), expiry_readable: new Date(parseInt(expiry, 10)).toString(),
reason: validator.escape(String(reason)), reason: validator.escape(String(reason)),
}); });
}); });

@ -0,0 +1,18 @@
<p>
[[email:banned.text1, {username}, {site_title}]]
<!-- IF until -->
[[email:banned.text2, {until}]]
<!-- ENDIF until -->
</p>
<!-- IF reason -->
<p>
[[email:banned.text3]]
</p>
<p>
{reason}
</p>
<!-- ENDIF reason -->
<!-- IMPORT emails/partials/footer.tpl -->
Loading…
Cancel
Save