mirror of
https://github.com/NodeBB/NodeBB.git
synced 2025-11-01 03:26:04 +01:00
closes #5542
This commit is contained in:
@@ -149,5 +149,6 @@
|
|||||||
"info.username-history": "Username History",
|
"info.username-history": "Username History",
|
||||||
"info.email-history": "Email History",
|
"info.email-history": "Email History",
|
||||||
"info.moderation-note": "Moderation Note",
|
"info.moderation-note": "Moderation Note",
|
||||||
"info.moderation-note.success": "Moderation note saved"
|
"info.moderation-note.success": "Moderation note saved",
|
||||||
|
"info.moderation-note.add": "Add note"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,19 @@ define('forum/account/info', ['forum/account/header', 'components'], function (h
|
|||||||
if (err) {
|
if (err) {
|
||||||
return app.alertError(err.message);
|
return app.alertError(err.message);
|
||||||
}
|
}
|
||||||
|
$('[component="account/moderation-note"]').val('');
|
||||||
app.alertSuccess('[[user:info.moderation-note.success]]');
|
app.alertSuccess('[[user:info.moderation-note.success]]');
|
||||||
|
var timestamp = Date.now();
|
||||||
|
var data = [{
|
||||||
|
note: note,
|
||||||
|
user: app.user,
|
||||||
|
timestamp: timestamp,
|
||||||
|
timestampISO: utils.toISOString(timestamp),
|
||||||
|
}];
|
||||||
|
app.parseAndTranslate('account/info', 'moderationNotes', { moderationNotes: data }, function (html) {
|
||||||
|
$('[component="account/moderation-note/list"]').prepend(html);
|
||||||
|
html.find('.timeago').timeago();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,14 +2,19 @@
|
|||||||
|
|
||||||
var async = require('async');
|
var async = require('async');
|
||||||
|
|
||||||
|
var db = require('../../database');
|
||||||
var user = require('../../user');
|
var user = require('../../user');
|
||||||
var helpers = require('../helpers');
|
var helpers = require('../helpers');
|
||||||
var accountHelpers = require('./helpers');
|
var accountHelpers = require('./helpers');
|
||||||
|
var pagination = require('../../pagination');
|
||||||
|
|
||||||
var infoController = {};
|
var infoController = module.exports;
|
||||||
|
|
||||||
infoController.get = function (req, res, callback) {
|
infoController.get = function (req, res, callback) {
|
||||||
var userData;
|
var userData;
|
||||||
|
var page = Math.max(1, req.query.page || 1);
|
||||||
|
var itemsPerPage = 10;
|
||||||
|
|
||||||
async.waterfall([
|
async.waterfall([
|
||||||
function (next) {
|
function (next) {
|
||||||
accountHelpers.getUserDataByUserSlug(req.params.userslug, req.uid, next);
|
accountHelpers.getUserDataByUserSlug(req.params.userslug, req.uid, next);
|
||||||
@@ -19,11 +24,27 @@ infoController.get = function (req, res, callback) {
|
|||||||
if (!userData) {
|
if (!userData) {
|
||||||
return callback();
|
return callback();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var start = (page - 1) * itemsPerPage;
|
||||||
|
var stop = start + itemsPerPage - 1;
|
||||||
async.parallel({
|
async.parallel({
|
||||||
history: async.apply(user.getModerationHistory, userData.uid),
|
history: async.apply(user.getModerationHistory, userData.uid),
|
||||||
sessions: async.apply(user.auth.getSessions, userData.uid, req.sessionID),
|
sessions: async.apply(user.auth.getSessions, userData.uid, req.sessionID),
|
||||||
usernames: async.apply(user.getHistory, 'user:' + userData.uid + ':usernames'),
|
usernames: async.apply(user.getHistory, 'user:' + userData.uid + ':usernames'),
|
||||||
emails: async.apply(user.getHistory, 'user:' + userData.uid + ':emails'),
|
emails: async.apply(user.getHistory, 'user:' + userData.uid + ':emails'),
|
||||||
|
notes: function (next) {
|
||||||
|
if (!userData.isAdminOrGlobalModeratorOrModerator) {
|
||||||
|
return setImmediate(next);
|
||||||
|
}
|
||||||
|
async.parallel({
|
||||||
|
notes: function (next) {
|
||||||
|
user.getModerationNotes(userData.uid, start, stop, next);
|
||||||
|
},
|
||||||
|
count: function (next) {
|
||||||
|
db.sortedSetCard('uid:' + userData.uid + ':moderation:notes', next);
|
||||||
|
},
|
||||||
|
}, next);
|
||||||
|
},
|
||||||
}, next);
|
}, next);
|
||||||
},
|
},
|
||||||
], function (err, data) {
|
], function (err, data) {
|
||||||
@@ -35,11 +56,15 @@ infoController.get = function (req, res, callback) {
|
|||||||
userData.sessions = data.sessions;
|
userData.sessions = data.sessions;
|
||||||
userData.usernames = data.usernames;
|
userData.usernames = data.usernames;
|
||||||
userData.emails = data.emails;
|
userData.emails = data.emails;
|
||||||
|
|
||||||
|
if (userData.isAdminOrGlobalModeratorOrModerator) {
|
||||||
|
userData.moderationNotes = data.notes.notes;
|
||||||
|
var pageCount = Math.ceil(data.notes.count / itemsPerPage);
|
||||||
|
userData.pagination = pagination.create(page, pageCount, req.query);
|
||||||
|
}
|
||||||
userData.title = '[[pages:account/info]]';
|
userData.title = '[[pages:account/info]]';
|
||||||
userData.breadcrumbs = helpers.buildBreadcrumbs([{ text: userData.username, url: '/user/' + userData.userslug }, { text: '[[user:account_info]]' }]);
|
userData.breadcrumbs = helpers.buildBreadcrumbs([{ text: userData.username, url: '/user/' + userData.userslug }, { text: '[[user:account_info]]' }]);
|
||||||
|
|
||||||
res.render('account/info', userData);
|
res.render('account/info', userData);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = infoController;
|
|
||||||
|
|||||||
@@ -316,7 +316,7 @@ SocketUser.getUserByEmail = function (socket, email, callback) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
SocketUser.setModerationNote = function (socket, data, callback) {
|
SocketUser.setModerationNote = function (socket, data, callback) {
|
||||||
if (!socket.uid || !data || !data.uid) {
|
if (!socket.uid || !data || !data.uid || !data.note) {
|
||||||
return callback(new Error('[[error:invalid-data]]'));
|
return callback(new Error('[[error:invalid-data]]'));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -335,11 +335,13 @@ SocketUser.setModerationNote = function (socket, data, callback) {
|
|||||||
if (!allowed) {
|
if (!allowed) {
|
||||||
return next(new Error('[[error:no-privileges]]'));
|
return next(new Error('[[error:no-privileges]]'));
|
||||||
}
|
}
|
||||||
if (data.note) {
|
|
||||||
user.setUserField(data.uid, 'moderationNote', data.note, next);
|
var note = {
|
||||||
} else {
|
uid: socket.uid,
|
||||||
db.deleteObjectField('user:' + data.uid, 'moderationNote', next);
|
note: data.note,
|
||||||
}
|
timestamp: Date.now(),
|
||||||
|
};
|
||||||
|
db.sortedSetAdd('uid:' + data.uid + ':moderation:notes', note.timestamp, JSON.stringify(note), next);
|
||||||
},
|
},
|
||||||
], callback);
|
], callback);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ var Upgrade = {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
version: 'develop', // rename this to whatever the next NodeBB version is (breaking)
|
version: 'develop', // rename this to whatever the next NodeBB version is (breaking)
|
||||||
upgrades: ['flags_refactor', 'post_votes_zset'],
|
upgrades: ['flags_refactor', 'post_votes_zset', 'moderation_history_refactor'],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|||||||
30
src/upgrades/1.5.0/moderation_history_refactor.js
Normal file
30
src/upgrades/1.5.0/moderation_history_refactor.js
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
/* jslint node: true */
|
||||||
|
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var db = require('../../database');
|
||||||
|
var batch = require('../../batch');
|
||||||
|
|
||||||
|
var async = require('async');
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
name: 'Update moderation notes to zset',
|
||||||
|
timestamp: Date.UTC(2017, 2, 22),
|
||||||
|
method: function (callback) {
|
||||||
|
batch.processSortedSet('users:joindate', function (ids, next) {
|
||||||
|
async.each(ids, function (uid, next) {
|
||||||
|
db.getObjectField('user:' + uid, 'moderationNote', function (err, moderationNote) {
|
||||||
|
if (err || !moderationNote) {
|
||||||
|
return next(err);
|
||||||
|
}
|
||||||
|
var note = {
|
||||||
|
uid: 1,
|
||||||
|
note: moderationNote,
|
||||||
|
timestamp: Date.now(),
|
||||||
|
};
|
||||||
|
db.sortedSetAdd('uid:' + uid + ':moderation:notes', note.timestamp, JSON.stringify(note), next);
|
||||||
|
});
|
||||||
|
}, next);
|
||||||
|
}, callback);
|
||||||
|
},
|
||||||
|
};
|
||||||
@@ -7,6 +7,7 @@ var validator = require('validator');
|
|||||||
var db = require('../database');
|
var db = require('../database');
|
||||||
var posts = require('../posts');
|
var posts = require('../posts');
|
||||||
var topics = require('../topics');
|
var topics = require('../topics');
|
||||||
|
var utils = require('../../public/src/utils');
|
||||||
|
|
||||||
module.exports = function (User) {
|
module.exports = function (User) {
|
||||||
User.getLatestBanInfo = function (uid, callback) {
|
User.getLatestBanInfo = function (uid, callback) {
|
||||||
@@ -74,7 +75,7 @@ module.exports = function (User) {
|
|||||||
}
|
}
|
||||||
callback(null, data.map(function (set) {
|
callback(null, data.map(function (set) {
|
||||||
set.timestamp = set.score;
|
set.timestamp = set.score;
|
||||||
set.timestampISO = new Date(set.score).toISOString();
|
set.timestampISO = utils.toISOString(set.score);
|
||||||
set.value = validator.escape(String(set.value.split(':')[0]));
|
set.value = validator.escape(String(set.value.split(':')[0]));
|
||||||
delete set.score;
|
delete set.score;
|
||||||
return set;
|
return set;
|
||||||
@@ -138,4 +139,36 @@ module.exports = function (User) {
|
|||||||
return banObj;
|
return banObj;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
User.getModerationNotes = function (uid, start, stop, callback) {
|
||||||
|
var noteData;
|
||||||
|
async.waterfall([
|
||||||
|
function (next) {
|
||||||
|
db.getSortedSetRevRange('uid:' + uid + ':moderation:notes', start, stop, next);
|
||||||
|
},
|
||||||
|
function (notes, next) {
|
||||||
|
var uids = [];
|
||||||
|
noteData = notes.map(function (note) {
|
||||||
|
try {
|
||||||
|
var data = JSON.parse(note);
|
||||||
|
uids.push(data.uid);
|
||||||
|
data.timestampISO = utils.toISOString(data.timestamp);
|
||||||
|
return data;
|
||||||
|
} catch (err) {
|
||||||
|
return next(err);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
User.getUsersFields(uids, ['uid', 'username', 'userslug', 'picture'], next);
|
||||||
|
},
|
||||||
|
function (userData, next) {
|
||||||
|
noteData.forEach(function (note, index) {
|
||||||
|
if (note) {
|
||||||
|
note.user = userData[index];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
next(null, noteData);
|
||||||
|
},
|
||||||
|
], callback);
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user