diff --git a/public/src/forum/accountedit.js b/public/src/forum/accountedit.js
index 0deeda57c7..13bab6cf9d 100644
--- a/public/src/forum/accountedit.js
+++ b/public/src/forum/accountedit.js
@@ -190,10 +190,11 @@ define(['forum/accountheader', 'uploader'], function(header, uploader) {
$('#changePasswordBtn').on('click', function() {
- if (passwordvalid && passwordsmatch && currentPassword.val()) {
+ if (passwordvalid && passwordsmatch && (currentPassword.val() || app.isAdmin)) {
socket.emit('user.changePassword', {
'currentPassword': currentPassword.val(),
- 'newPassword': password.val()
+ 'newPassword': password.val(),
+ 'uid': templates.get('theirid')
}, function(err) {
currentPassword.val('');
@@ -203,12 +204,10 @@ define(['forum/accountheader', 'uploader'], function(header, uploader) {
passwordvalid = false;
if (err) {
- app.alertError(err.message);
- return;
+ return app.alertError(err.message);
}
app.alertSuccess('Your password is updated!');
-
});
}
return false;
diff --git a/public/src/forum/admin/groups.js b/public/src/forum/admin/groups.js
index 7d21ee8742..ad530c12a9 100644
--- a/public/src/forum/admin/groups.js
+++ b/public/src/forum/admin/groups.js
@@ -58,15 +58,14 @@ define(function() {
listEl.on('click', 'button[data-action]', function() {
var action = this.getAttribute('data-action'),
- parent = $(this).parents('li[data-gid]'),
- gid = parent.attr('data-gid'),
- system = parseInt(parent.attr('data-system'), 10) === 1;
+ gid = $(this).parents('li[data-gid]').attr('data-gid');
switch (action) {
case 'delete':
bootbox.confirm('Are you sure you wish to delete this group?', function(confirm) {
if (confirm) {
socket.emit('admin.groups.delete', gid, function(err, data) {
+ console.log(err, data);
if(err) {
return app.alertError(err.message);
}
@@ -107,8 +106,6 @@ define(function() {
detailsModal.attr('data-gid', groupObj.gid);
detailsModal.modal('show');
-
- $('.hide-if-system')[system ? 'hide' : 'show']();
});
break;
}
diff --git a/public/src/forum/popular.js b/public/src/forum/popular.js
index f85e38ccb2..c4817bbd71 100644
--- a/public/src/forum/popular.js
+++ b/public/src/forum/popular.js
@@ -21,6 +21,10 @@ define(['forum/recent'], function(recent) {
});
function loadMoreTopics() {
+ if(!$('#topics-container').length) {
+ return;
+ }
+
loadingMoreTopics = true;
socket.emit('topics.loadMoreFromSet', {
set: 'topics:' + $('.nav-pills .active a').html().toLowerCase(),
diff --git a/public/src/forum/recent.js b/public/src/forum/recent.js
index 15e1d63ceb..8837c41367 100644
--- a/public/src/forum/recent.js
+++ b/public/src/forum/recent.js
@@ -92,6 +92,10 @@ define(function() {
}
Recent.loadMoreTopics = function() {
+ if(!$('#topics-container').length) {
+ return;
+ }
+
loadingMoreTopics = true;
socket.emit('topics.loadMoreRecentTopics', {
after: $('#topics-container').attr('data-nextstart'),
diff --git a/public/src/forum/unread.js b/public/src/forum/unread.js
index 4f3024fbab..3ed2baf5cc 100644
--- a/public/src/forum/unread.js
+++ b/public/src/forum/unread.js
@@ -44,6 +44,9 @@ define(['forum/recent'], function(recent) {
});
function loadMoreTopics() {
+ if(!$('#topics-container').length) {
+ return;
+ }
loadingMoreTopics = true;
socket.emit('topics.loadMoreUnreadTopics', {
after: $('#topics-container').attr('data-nextstart')
diff --git a/public/templates/admin/groups.tpl b/public/templates/admin/groups.tpl
index 6c87898da0..bd21db2b9f 100644
--- a/public/templates/admin/groups.tpl
+++ b/public/templates/admin/groups.tpl
@@ -5,7 +5,7 @@
- -
+
-
{groups.name}
@@ -69,7 +69,7 @@
-
\ No newline at end of file
+
diff --git a/src/events.js b/src/events.js
index e7ac7356e2..825db1c832 100644
--- a/src/events.js
+++ b/src/events.js
@@ -13,6 +13,17 @@ var fs = require('fs'),
logWithUser(uid, 'changed password');
}
+ events.logAdminChangeUserPassword = function(adminUid, theirUid) {
+ user.getMultipleUserFields([adminUid, theirUid], ['username'], function(err, userData) {
+ if(err) {
+ return winston.error('Error logging event. ' + err.message);
+ }
+
+ var msg = userData[0].username + '(uid ' + adminUid + ') changed password of ' + userData[1].username + '(uid ' + theirUid + ')';
+ events.log(msg);
+ });
+ }
+
events.logPasswordReset = function(uid) {
logWithUser(uid, 'reset password');
}
@@ -53,11 +64,10 @@ var fs = require('fs'),
user.getUserField(uid, 'username', function(err, username) {
if(err) {
- winston.error('Error logging event. ' + err.message);
- return;
+ return winston.error('Error logging event. ' + err.message);
}
- var msg = '[' + new Date().toUTCString() + '] - ' + username + '(uid ' + uid + ') ' + string;
+ var msg = username + '(uid ' + uid + ') ' + string;
events.log(msg);
});
}
@@ -65,6 +75,8 @@ var fs = require('fs'),
events.log = function(msg) {
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);
diff --git a/src/groups.js b/src/groups.js
index a9148084e6..8d9b50067c 100644
--- a/src/groups.js
+++ b/src/groups.js
@@ -13,16 +13,14 @@
expand: options.expand
}, next);
}, function (err, groups) {
- groups.forEach(function(group, g, arr) {
- if (parseInt(group.deleted, 10) === 1) {
- delete arr[g];
- }
- if (parseInt(group.hidden, 10) === 1) {
- group.deletable = 0;
+ // Remove deleted and hidden groups from this list
+ callback(err, groups.filter(function (group) {
+ if (parseInt(group.deleted, 10) === 1 || parseInt(group.hidden, 10) === 1) {
+ return false;
+ } else {
+ return true;
}
- });
-
- callback(err, groups);
+ }));
});
} else {
callback(null, []);
diff --git a/src/routes/admin.js b/src/routes/admin.js
index c0afc39b4b..61e15a0f02 100644
--- a/src/routes/admin.js
+++ b/src/routes/admin.js
@@ -375,7 +375,10 @@ var nconf = require('nconf'),
if(err) {
return next(err);
}
- res.json(200, {eventdata: data.toString()});
+ if(data) {
+ data = data.toString().split('\n').reverse().join('\n');
+ }
+ res.json(200, {eventdata: data});
});
});
diff --git a/src/user.js b/src/user.js
index 13d3669f2c..a3edb449d1 100644
--- a/src/user.js
+++ b/src/user.js
@@ -424,27 +424,59 @@ var bcrypt = require('bcryptjs'),
};
User.changePassword = function(uid, data, callback) {
+ if(!data || !data.uid) {
+ return callback(new Error('invalid-uid'));
+ }
+
+ function hashAndSetPassword(callback) {
+ User.hashPassword(data.newPassword, function(err, hash) {
+ 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();
+ });
+ });
+ }
+
if (!utils.isPasswordValid(data.newPassword)) {
return callback(new Error('Invalid password!'));
}
- User.getUserField(uid, 'password', function(err, currentPassword) {
- bcrypt.compare(data.currentPassword, currentPassword, function(err, res) {
- if (err) {
- return callback(err);
+ if(parseInt(uid, 10) !== parseInt(data.uid, 10)) {
+ User.isAdministrator(uid, function(err, isAdmin) {
+ if(err || !isAdmin) {
+ return callback(err || new Error('not-allowed'));
}
- if (res) {
- User.hashPassword(data.newPassword, function(err, hash) {
- User.setUserField(uid, 'password', hash);
- events.logPasswordChange(uid);
- callback(null);
- });
- } else {
- callback(new Error('Your current password is not correct!'));
+ hashAndSetPassword(callback);
+ });
+ } else {
+ User.getUserField(uid, 'password', function(err, currentPassword) {
+ if(err) {
+ return callback(err);
}
+
+ bcrypt.compare(data.currentPassword, currentPassword, function(err, res) {
+ if (err || !res) {
+ return callback(err || new Error('Your current password is not correct!'));
+ }
+
+ hashAndSetPassword(callback);
+ });
});
- });
+ }
};
User.setUserField = function(uid, field, value, callback) {