diff --git a/public/src/admin/advanced/events.js b/public/src/admin/advanced/events.js new file mode 100644 index 0000000000..039b105bcb --- /dev/null +++ b/public/src/admin/advanced/events.js @@ -0,0 +1,43 @@ +"use strict"; +/* global define, socket, app, templates */ + + +define('admin/advanced/events', ['forum/infinitescroll'], function(infinitescroll) { + var Events = {}; + + Events.init = function() { + + $('[data-action="clear"]').on('click', function() { + socket.emit('admin.deleteAllEvents', function(err) { + if (err) { + return app.alertError(err.message); + } + $('.events-list').empty(); + }); + }); + + infinitescroll.init(function(direction) { + if (direction < 0 || !$('.events').length) { + return; + } + + infinitescroll.loadMore('admin.getMoreEvents', $('[data-next]').attr('data-next'), function(data, done) { + console.log(data.events); + if (data.events && data.events.length) { + templates.parse('admin/advanced/events', 'events', {events: data.events}, function(html) { + console.log(html); + $('.events-list').append(html); + done(); + }); + + $('[data-next]').attr('data-next', data.next); + } else { + done(); + } + }); + }); + + }; + + return Events; +}); diff --git a/src/controllers/admin.js b/src/controllers/admin.js index 5ccfa3a6df..6779185f0a 100644 --- a/src/controllers/admin.js +++ b/src/controllers/admin.js @@ -174,14 +174,14 @@ adminController.database.get = function(req, res, next) { }; adminController.events.get = function(req, res, next) { - events.getLog(-1, 5000, function(err, data) { - if(err || !data) { + events.getEvents(0, 19, function(err, events) { + if(err || !events) { return next(err); } res.render('admin/advanced/events', { - eventdata: data.data, - next: data.next + events: events, + next: 20 }); }); }; diff --git a/src/events.js b/src/events.js index bab042f28e..682e9549db 100644 --- a/src/events.js +++ b/src/events.js @@ -1,154 +1,128 @@ 'use strict'; -var fs = require('fs'), - winston = require('winston'), - path = require('path'), - nconf = require('nconf'), - user = require('./user'); +var async = require('async'), + db = require('./database'), + batch = require('./batch'), + user = require('./user'), + utils = require('../public/src/utils'); -(function(events) { - var logFileName = 'logs/events.log'; - - events.logPasswordChange = function(uid) { - events.logWithUser(uid, 'changed password'); - }; - - events.logAdminChangeUserPassword = function(adminUid, theirUid, callback) { - logAdminEvent(adminUid, theirUid, 'changed password of', callback); - }; - - events.logAdminUserDelete = function(adminUid, theirUid, callback) { - logAdminEvent(adminUid, theirUid, 'deleted', callback); - }; - function logAdminEvent(adminUid, theirUid, message, callback) { - user.getMultipleUserFields([adminUid, theirUid], ['username'], function(err, userData) { - if(err) { - return winston.error('Error logging event. ' + err.message); +(function(events) { + events.log = function(data, callback) { + callback = callback || function() {}; + + async.waterfall([ + function(next) { + db.incrObjectField('global', 'nextEid', next); + }, + function(eid, next) { + data.timestamp = Date.now(); + data.eid = eid; + + async.parallel([ + function(next) { + db.sortedSetAdd('events:time', data.timestamp, eid, next); + }, + function(next) { + db.setObject('event:' + eid, data, next); + } + ], next); } - - var msg = userData[0].username + '(uid ' + adminUid + ') ' + message + ' ' + userData[1].username + '(uid ' + theirUid + ')'; - events.log(msg, callback); + ], function(err, result) { + callback(err); }); - } - - events.logPasswordReset = function(uid) { - events.logWithUser(uid, 'reset password'); - }; - - events.logEmailChange = function(uid, oldEmail, newEmail) { - events.logWithUser(uid,'changed email from "' + oldEmail + '" to "' + newEmail +'"'); - }; - - events.logUsernameChange = function(uid, oldUsername, newUsername) { - events.logWithUser(uid,'changed username from "' + oldUsername + '" to "' + newUsername +'"'); - }; - - events.logAdminLogin = function(uid) { - events.logWithUser(uid, 'logged into admin panel'); - }; - - events.logPostEdit = function(uid, pid) { - events.logWithUser(uid, 'edited post (pid ' + pid + ')'); - }; - - events.logPostDelete = function(uid, pid) { - events.logWithUser(uid, 'deleted post (pid ' + pid + ')'); - }; - - events.logPostRestore = function(uid, pid) { - events.logWithUser(uid, 'restored post (pid ' + pid + ')'); - }; - - events.logPostPurge = function(uid, pid) { - events.logWithUser(uid, 'purged post (pid ' + pid + ')'); - }; - - events.logTopicMove = function(uid, tid) { - events.logWithUser(uid, 'moved topic (tid ' + tid + ')'); }; - events.logTopicDelete = function(uid, tid) { - events.logWithUser(uid, 'deleted topic (tid ' + tid + ')'); - }; - - events.logTopicRestore = function(uid, tid) { - events.logWithUser(uid, 'restored topic (tid ' + tid + ')'); - }; - - events.logAccountLock = function(uid, until) { - var date = new Date(); - date.setTime(date.getTime() + until); - - events.logWithUser(uid, 'locked out until ' + date.toString()); - }; - - events.logWithUser = function(uid, string) { - user.getUserField(uid, 'username', function(err, username) { - if(err) { - return winston.error('Error logging event. ' + err.message); + events.getEvents = function(start, stop, callback) { + async.waterfall([ + function(next) { + db.getSortedSetRevRange('events:time', start, stop, next); + }, + function(eids, next) { + var keys = eids.map(function(eid) { + return 'event:' + eid; + }); + db.getObjects(keys, next); + }, + function(eventsData, next) { + eventsData.forEach(function(event) { + var e = utils.merge(event); + e.eid = e.uid = e.type = e.ip = undefined; + event.jsonString = JSON.stringify(e, null, 4); + event.timestampISO = new Date(parseInt(event.timestamp, 10)).toUTCString(); + }); + addUserData(eventsData, 'uid', 'user', next); + }, + function(eventsData, next) { + addUserData(eventsData, 'targetUid', 'targetUser', next); } - - var msg = username + '(uid ' + uid + ') ' + string; - events.log(msg); - }); + ], callback); }; - events.log = function(msg, callback) { - var logFile = path.join(nconf.get('base_dir'), logFileName); - - msg = '[' + new Date().toUTCString() + '] - ' + msg; - - fs.appendFile(logFile, msg + '\n', function(err) { - if(err) { - winston.error('Error logging event. ' + err.message); - if (typeof callback === 'function') { - callback(err); - } - return; - } - - if (typeof callback === 'function') { - callback(); - } + function addUserData(eventsData, field, objectName, callback) { + var uids = eventsData.map(function(event) { + return event && event[field]; + }).filter(function(uid, index, array) { + return uid && array.indexOf(uid) === index; }); - }; - events.getLog = function(end, len, callback) { - var logFile = path.join(nconf.get('base_dir'), logFileName); + if (!uids.length) { + return callback(null, eventsData); + } - fs.stat(logFile, function(err, stat) { - if (err) { - return callback(null, 'No logs found!'); + async.parallel({ + isAdmin: function(next) { + user.isAdministrator(uids, next); + }, + userData: function(next) { + user.getMultipleUserFields(uids, ['username', 'userslug', 'picture'], next); } - - var buffer = ''; - var size = stat.size; - if (end === -1) { - end = size; + }, function(err, results) { + if (err) { + return callback(err); } - end = parseInt(end, 10); - var start = Math.max(0, end - len); + var userData = results.userData; - var rs = fs.createReadStream(logFile, {start: start, end: end}); - rs.addListener('data', function(lines) { - buffer += lines.toString(); + var map = {}; + userData.forEach(function(user, index) { + user.isAdmin = results.isAdmin[index]; + map[user.uid] = user; }); - rs.addListener('end', function() { - var firstNewline = buffer.indexOf('\n'); - if (firstNewline !== -1) { - buffer = buffer.slice(firstNewline); - buffer = buffer.split('\n').reverse().join('\n'); + eventsData.forEach(function(event) { + if (map[event[field]]) { + event[objectName] = map[event[field]]; } - - callback(null, {data: buffer, next: end - buffer.length}); }); + callback(null, eventsData); }); + } + + events.deleteEvents = function(eids, callback) { + callback = callback || function() {}; + async.parallel([ + function(next) { + var keys = eids.map(function(eid) { + return 'event:' + eid; + }); + db.deleteAll(keys, next); + }, + function(next) { + db.sortedSetRemove('events:time', eids, next); + } + ], callback); + }; + + events.deleteAll = function(callback) { + callback = callback || function() {}; + batch.processSortedSet('events:time', function(eids, next) { + events.deleteEvents(eids, callback); + }, {alwaysStartAt: 0}, callback); }; + }(module.exports)); diff --git a/src/favourites.js b/src/favourites.js index 0673626f51..6de70d33f3 100644 --- a/src/favourites.js +++ b/src/favourites.js @@ -43,10 +43,6 @@ var async = require('async'), db.sortedSetAdd('users:reputation', newreputation, postData.uid); - if (type === 'downvote') { - banUserForLowReputation(postData.uid, newreputation); - } - adjustPostVotes(pid, uid, type, unvote, function(err, votes) { postData.votes = votes; callback(err, { @@ -62,23 +58,6 @@ var async = require('async'), }); } - function banUserForLowReputation(uid, newreputation) { - if (parseInt(meta.config['autoban:downvote'], 10) === 1 && newreputation < parseInt(meta.config['autoban:downvote:threshold'], 10)) { - user.getUserField(uid, 'banned', function(err, banned) { - if (err || parseInt(banned, 10) === 1) { - return; - } - var adminUser = require('./socket.io/admin/user'); - adminUser.banUser(uid, function(err) { - if (err) { - return winston.error(err.message); - } - winston.info('uid ' + uid + ' was banned for reaching ' + newreputation + ' reputation'); - }); - }); - } - } - function adjustPostVotes(pid, uid, type, unvote, callback) { var notType = (type === 'upvote' ? 'downvote' : 'upvote'); diff --git a/src/notifications.js b/src/notifications.js index 2de4ec1709..96502508f7 100644 --- a/src/notifications.js +++ b/src/notifications.js @@ -311,8 +311,6 @@ var async = require('async'), if (process.env.NODE_ENV === 'development') { winston.info('[notifications.prune] Notification pruning completed. ' + numPruned + ' expired notification' + (numPruned !== 1 ? 's' : '') + ' removed.'); } - var diff = process.hrtime(start); - events.log('Pruning '+ numPruned + ' notifications took : ' + (diff[0] * 1e3 + diff[1] / 1e6) + ' ms'); }); }); }; diff --git a/src/postTools.js b/src/postTools.js index 692878734a..c00a8a4b9c 100644 --- a/src/postTools.js +++ b/src/postTools.js @@ -106,7 +106,7 @@ var winston = require('winston'), return callback(err); } results.content = results.postData.content; - //events.logPostEdit(uid, pid); + plugins.fireHook('action:post.edit', postData); callback(null, results); }); @@ -146,7 +146,6 @@ var winston = require('winston'), return callback(err); } - events[isDelete ? 'logPostDelete' : 'logPostRestore'](uid, pid); if (isDelete) { posts.delete(pid, callback); } else { @@ -165,7 +164,7 @@ var winston = require('winston'), if (err || !canEdit) { return callback(err || new Error('[[error:no-privileges]]')); } - events.logPostPurge(uid, pid); + posts.purge(pid, callback); }); }; diff --git a/src/routes/authentication.js b/src/routes/authentication.js index 5754ee3353..649d6d87dd 100644 --- a/src/routes/authentication.js +++ b/src/routes/authentication.js @@ -68,7 +68,7 @@ }); }; - Auth.login = function(username, password, next) { + Auth.login = function(req, username, password, next) { if (!username || !password) { return next(new Error('[[error:invalid-password]]')); } @@ -85,7 +85,7 @@ return next(new Error('[[error:no-user]]')); } uid = _uid; - user.auth.logAttempt(uid, next); + user.auth.logAttempt(uid, req.ip, next); }, function(next) { db.getObjectFields('user:' + uid, ['password', 'banned'], next); @@ -109,7 +109,7 @@ ], next); }; - passport.use(new passportLocal(Auth.login)); + passport.use(new passportLocal({passReqToCallback: true}, Auth.login)); passport.serializeUser(function(user, done) { done(null, user.uid); diff --git a/src/socket.io/admin.js b/src/socket.io/admin.js index 36efef49f9..a770af5c53 100644 --- a/src/socket.io/admin.js +++ b/src/socket.io/admin.js @@ -49,7 +49,11 @@ SocketAdmin.before = function(socket, method, next) { }; SocketAdmin.reload = function(socket, data, callback) { - events.logWithUser(socket.uid, ' is reloading NodeBB'); + events.log({ + type: 'reload', + uid: socket.uid, + ip: socket.ip + }); if (process.send) { process.send({ action: 'reload' @@ -60,7 +64,11 @@ SocketAdmin.reload = function(socket, data, callback) { }; SocketAdmin.restart = function(socket, data, callback) { - events.logWithUser(socket.uid, ' is restarting NodeBB'); + events.log({ + type: 'restart', + uid: socket.uid, + ip: socket.ip + }); meta.restart(); }; @@ -274,10 +282,21 @@ function getMonthlyPageViews(callback) { } SocketAdmin.getMoreEvents = function(socket, next, callback) { - if (parseInt(next, 10) < 0) { + var start = parseInt(next, 10); + if (start < 0) { return callback(null, {data: [], next: next}); } - events.getLog(next, 5000, callback); + var end = next + 10; + events.getEvents(start, end, function(err, events) { + if (err) { + return callback(err); + } + callback(null, {events: events, next: end + 1}); + }); +}; + +SocketAdmin.deleteAllEvents = function(socket, data, callback) { + events.deleteAll(callback); }; SocketAdmin.dismissFlag = function(socket, pid, callback) { diff --git a/src/socket.io/admin/user.js b/src/socket.io/admin/user.js index 9189727fbb..3a194044ea 100644 --- a/src/socket.io/admin/user.js +++ b/src/socket.io/admin/user.js @@ -157,7 +157,7 @@ User.deleteUsers = function(socket, uids, callback) { async.each(uids, function(uid, next) { user.isAdministrator(uid, function(err, isAdmin) { if (err || isAdmin) { - return callback(err || new Error('[[error:cant-ban-other-admins]]')); + return callback(err || new Error('[[error:cant-delete-other-admins]]')); } user.delete(uid, function(err) { @@ -165,7 +165,12 @@ User.deleteUsers = function(socket, uids, callback) { return next(err); } - events.logAdminUserDelete(socket.uid, uid); + events.log({ + type: 'user-delete', + uid: socket.uid, + targetUid: uid, + ip: socket.ip + }); websockets.logoutUser(uid); next(); diff --git a/src/socket.io/posts.js b/src/socket.io/posts.js index d0f5b3b589..590b10da0f 100644 --- a/src/socket.io/posts.js +++ b/src/socket.io/posts.js @@ -16,6 +16,7 @@ var async = require('async'), groups = require('../groups'), user = require('../user'), websockets = require('./index'), + events = require('../events'), utils = require('../../public/src/utils'), SocketPosts = {}; @@ -138,7 +139,38 @@ SocketPosts.upvote = function(socket, data, callback) { }; SocketPosts.downvote = function(socket, data, callback) { - favouriteCommand(socket, 'downvote', 'voted', '', data, callback); + function banUserForLowReputation(uid, callback) { + if (parseInt(meta.config['autoban:downvote'], 10) === 1) { + user.getUserFields(uid, ['reputation', 'banned'], function(err, userData) { + if (err || parseInt(userData.banned, 10) === 1 || parseInt(userData.reputation) >= parseInt(meta.config['autoban:downvote:threshold'], 10)) { + return callback(err); + } + + var adminUser = require('./admin/user'); + adminUser.banUser(uid, function(err) { + if (err) { + return callback(err); + } + events.log({ + type: 'banned', + reason: 'low-reputation', + uid: socket.uid, + ip: socket.ip, + targetUid: data.uid, + reputation: userData.reputation + }); + callback(); + }); + }); + } + } + + favouriteCommand(socket, 'downvote', 'voted', '', data, function(err) { + if (err) { + return callback(err); + } + banUserForLowReputation(data.uid, callback); + }); }; SocketPosts.unvote = function(socket, data, callback) { @@ -309,9 +341,16 @@ function deleteOrRestore(command, socket, data, callback) { return callback(err); } - var eventName = command === 'restore' ? 'event:post_restored' : 'event:post_deleted'; + var eventName = command === 'delete' ? 'event:post_deleted' : 'event:post_restored'; websockets.in('topic_' + data.tid).emit(eventName, postData); + events.log({ + type: command === 'delete' ? 'post-delete' : 'post-restore', + uid: socket.uid, + pid: data.pid, + ip: socket.ip + }); + callback(); }); } @@ -327,6 +366,13 @@ SocketPosts.purge = function(socket, data, callback) { websockets.in('topic_' + data.tid).emit('event:post_purged', data.pid); + events.log({ + type: 'post-purge', + uid: socket.uid, + pid: data.pid, + ip: socket.ip + }); + callback(); }); }; diff --git a/src/socket.io/topics.js b/src/socket.io/topics.js index 9f96f17f29..687a7361a5 100644 --- a/src/socket.io/topics.js +++ b/src/socket.io/topics.js @@ -15,6 +15,7 @@ var nconf = require('nconf'), user = require('../user'), db = require('../database'), meta = require('../meta'), + events = require('../events'), utils = require('../../public/src/utils'), SocketPosts = require('./posts'), @@ -259,7 +260,21 @@ function doTopicAction(action, socket, data, callback) { } if(typeof threadTools[action] === 'function') { - threadTools[action](tid, socket.uid, next); + threadTools[action](tid, socket.uid, function(err) { + if (err) { + return next(err); + } + + if (action === 'delete' || action === 'restore' || action === 'purge') { + events.log({ + type: 'topic-' + action, + uid: socket.uid, + ip: socket.ip, + tid: tid + }); + } + next(); + }); } }); }, callback); diff --git a/src/socket.io/user.js b/src/socket.io/user.js index d28421c383..d879813bae 100644 --- a/src/socket.io/user.js +++ b/src/socket.io/user.js @@ -12,6 +12,7 @@ var async = require('async'), utils = require('../../public/src/utils'), websockets = require('./index'), meta = require('../meta'), + events = require('../events'), SocketUser = {}; SocketUser.exists = function(socket, data, callback) { @@ -56,7 +57,7 @@ SocketUser.emailConfirm = function(socket, data, callback) { SocketUser.search = function(socket, data, callback) { if (!data) { - return callback(new Error('[[error:invalid-data]]')) + return callback(new Error('[[error:invalid-data]]')); } if (!socket.uid) { return callback(new Error('[[error:not-logged-in]]')); @@ -87,7 +88,16 @@ SocketUser.reset.valid = function(socket, code, callback) { SocketUser.reset.commit = function(socket, data, callback) { if(data && data.code && data.password) { - user.reset.commit(data.code, data.password, callback); + user.reset.commit(data.code, data.password, function(err) { + if (err) { + return callback(err); + } + events.log({ + type: 'password-reset', + uid: socket.uid, + ip: socket.ip + }); + }); } }; @@ -109,12 +119,74 @@ SocketUser.checkStatus = function(socket, uid, callback) { }; SocketUser.changePassword = function(socket, data, callback) { - if (data && socket.uid) { - user.changePassword(socket.uid, data, callback); + if (!data || !data.uid) { + return callback(new Error('[[error:invalid-data]]')); + } + if (!socket.uid) { + return callback('[[error:invalid-uid]]'); } + + user.changePassword(socket.uid, data, function(err) { + if (err) { + return callback(err); + } + + events.log({ + type: 'password-change', + uid: socket.uid, + targetUid: data.uid, + ip: socket.ip + }); + }); }; SocketUser.updateProfile = function(socket, data, callback) { + function update(oldUserData) { + function done(err, userData) { + if (err) { + return callback(err); + } + + if (userData.email !== oldUserData.email) { + events.log({ + type: 'email-change', + uid: socket.uid, + targetUid: data.uid, + ip: socket.ip, + oldEmail: oldUserData.email, + newEmail: userData.email + }); + } + + if (userData.username !== oldUserData.username) { + events.log({ + type: 'username-change', + uid: socket.uid, + targetUid: data.uid, + ip: socket.ip, + oldUsername: oldUserData.username, + newUsername: userData.username + }); + } + } + + if (socket.uid === parseInt(data.uid, 10)) { + return user.updateProfile(socket.uid, data, done); + } + + user.isAdministrator(socket.uid, function(err, isAdmin) { + if (err) { + return callback(err); + } + + if (!isAdmin) { + return callback(new Error('[[error:no-privileges]]')); + } + + user.updateProfile(data.uid, data, done); + }); + } + if (!socket.uid) { return callback('[[error:invalid-uid]]'); } @@ -123,20 +195,12 @@ SocketUser.updateProfile = function(socket, data, callback) { return callback(new Error('[[error:invalid-data]]')); } - if (socket.uid === parseInt(data.uid, 10)) { - return user.updateProfile(socket.uid, data, callback); - } - - user.isAdministrator(socket.uid, function(err, isAdmin) { + user.getUserFields(data.uid, ['email', 'username'], function(err, oldUserData) { if (err) { return callback(err); } - if (!isAdmin) { - return callback(new Error('[[error:no-privileges]]')); - } - - user.updateProfile(data.uid, data, callback); + update(oldUserData, callback); }); }; diff --git a/src/threadTools.js b/src/threadTools.js index 1fe1369d35..077abc54e6 100644 --- a/src/threadTools.js +++ b/src/threadTools.js @@ -56,8 +56,6 @@ var winston = require('winston'), plugins.fireHook('action:topic.restore', topicData); } - events[isDelete ? 'logTopicDelete' : 'logTopicRestore'](uid, tid); - emitTo('topic_' + tid); emitTo('category_' + topicData.cid); @@ -214,8 +212,6 @@ var winston = require('winston'), topics.setTopicField(tid, 'cid', cid, callback); - events.logTopicMove(uid, tid); - plugins.fireHook('action:topic.move', { tid: tid, fromCid: oldCid, diff --git a/src/user/auth.js b/src/user/auth.js index b275882cf1..48f0c8fc2c 100644 --- a/src/user/auth.js +++ b/src/user/auth.js @@ -8,7 +8,7 @@ var async = require('async'), module.exports = function(User) { User.auth = {}; - User.auth.logAttempt = function(uid, callback) { + User.auth.logAttempt = function(uid, ip, callback) { db.exists('lockout:' + uid, function(err, exists) { if (err) { return callback(err); @@ -30,12 +30,15 @@ module.exports = function(User) { return callback(err); } var duration = 1000 * 60 * (meta.config.lockoutDuration || 60); - + db.delete('loginAttempts:' + uid); db.pexpire('lockout:' + uid, duration); - - events.logAccountLock(uid, duration); - callback(new Error('account-locked')); + events.log({ + type: 'account-locked', + uid: uid, + ip: ip + }); + callback(new Error('[[error:account-locked]]')); }); } else { db.pexpire('loginAttempts:' + uid, 1000 * 60 * 60); diff --git a/src/user/profile.js b/src/user/profile.js index 8c44b86a6f..461f1d9bb8 100644 --- a/src/user/profile.js +++ b/src/user/profile.js @@ -148,8 +148,6 @@ module.exports = function(User) { return callback(err); } - events.logEmailChange(uid, userData.email, newEmail); - var gravatarpicture = User.createGravatarURLFromEmail(newEmail); async.parallel([ function(next) { @@ -183,9 +181,13 @@ module.exports = function(User) { if (!newUsername) { return callback(); } + User.getUserFields(uid, ['username', 'userslug'], function(err, userData) { function update(field, object, value, callback) { - async.parallel([ + async.series([ + function(next) { + db.deleteObjectField(field + ':uid', userData[field], next); + }, function(next) { User.setUserField(uid, field, value, next); }, @@ -198,7 +200,6 @@ module.exports = function(User) { if (err) { return callback(err); } - var userslug = utils.slugify(newUsername); async.parallel([ function(next) { @@ -206,25 +207,15 @@ module.exports = function(User) { return next(); } - db.deleteObjectField('username:uid', userData.username, function(err) { - if (err) { - return next(err); - } - events.logUsernameChange(uid, userData.username, newUsername); - update('username', 'username:uid', newUsername, next); - }); + update('username', 'username:uid', newUsername, next); }, function(next) { - if (userslug === userData.userslug) { + var newUserslug = utils.slugify(newUsername); + if (newUserslug === userData.userslug) { return next(); } - db.deleteObjectField('userslug:uid', userData.userslug, function(err) { - if (err) { - return next(err); - } - update('userslug', 'userslug:uid', userslug, next); - }); + update('userslug', 'userslug:uid', newUserslug, next); } ], callback); }); @@ -261,23 +252,11 @@ module.exports = function(User) { function hashAndSetPassword(callback) { User.hashPassword(data.newPassword, function(err, hash) { - if(err) { + if (err) { return callback(err); } - User.setUserField(data.uid, 'password', hash, function(err) { - if(err) { - return callback(err); - } - - if(parseInt(uid, 10) === parseInt(data.uid, 10)) { - events.logPasswordChange(data.uid); - } else { - events.logAdminChangeUserPassword(uid, data.uid); - } - - callback(); - }); + User.setUserField(data.uid, 'password', hash, callback); }); } diff --git a/src/user/reset.js b/src/user/reset.js index 2e1a7ab80e..c65e77a570 100644 --- a/src/user/reset.js +++ b/src/user/reset.js @@ -83,7 +83,6 @@ var async = require('async'), return callback(err); } user.setUserField(uid, 'password', hash); - events.logPasswordReset(uid); db.deleteObjectField('reset:uid', code); db.deleteObjectField('reset:expiry', code); diff --git a/src/views/admin/advanced/events.tpl b/src/views/admin/advanced/events.tpl index 03e3b7f4eb..e3231b0099 100644 --- a/src/views/admin/advanced/events.tpl +++ b/src/views/admin/advanced/events.tpl @@ -1,31 +1,32 @@
-
+
Events
-
{eventdata}
+ +
There are no events
+ +
+ +
+ #{events.eid} {events.type} + {events.user.username} (uid {events.user.uid}) (IP {events.ip}) + {events.timestampISO} +

+
{events.jsonString}
+
+ +
+
+
+
+
+
+
Events Control Panel
+
+
- - \ No newline at end of file