mirror of
https://github.com/NodeBB/NodeBB.git
synced 2025-11-17 11:11:04 +01:00
committed by
GitHub
parent
f9c882cb1d
commit
49ba5af5fa
@@ -13,6 +13,11 @@ define('admin/advanced/events', function () {
|
|||||||
$('.events-list').empty();
|
$('.events-list').empty();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$('#filter').on('change', function () {
|
||||||
|
var filter = $(this).val();
|
||||||
|
ajaxify.go('admin/advanced/events' + (filter ? '?filter=' + filter : ''));
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
return Events;
|
return Events;
|
||||||
|
|||||||
@@ -14,24 +14,35 @@ eventsController.get = function (req, res, next) {
|
|||||||
var start = (page - 1) * itemsPerPage;
|
var start = (page - 1) * itemsPerPage;
|
||||||
var stop = start + itemsPerPage - 1;
|
var stop = start + itemsPerPage - 1;
|
||||||
|
|
||||||
|
var currentFilter = req.query.filter || '';
|
||||||
|
|
||||||
async.waterfall([
|
async.waterfall([
|
||||||
function (next) {
|
function (next) {
|
||||||
async.parallel({
|
async.parallel({
|
||||||
eventCount: function (next) {
|
eventCount: function (next) {
|
||||||
db.sortedSetCard('events:time', next);
|
db.sortedSetCard('events:time' + (currentFilter ? ':' + currentFilter : ''), next);
|
||||||
},
|
},
|
||||||
events: function (next) {
|
events: function (next) {
|
||||||
events.getEvents(start, stop, next);
|
events.getEvents(currentFilter, start, stop, next);
|
||||||
},
|
},
|
||||||
}, next);
|
}, next);
|
||||||
},
|
},
|
||||||
function (results) {
|
function (results) {
|
||||||
|
var types = [''].concat(events.types);
|
||||||
|
var filters = types.map(function (type) {
|
||||||
|
return {
|
||||||
|
value: type,
|
||||||
|
name: type || 'all',
|
||||||
|
selected: type === currentFilter,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
var pageCount = Math.max(1, Math.ceil(results.eventCount / itemsPerPage));
|
var pageCount = Math.max(1, Math.ceil(results.eventCount / itemsPerPage));
|
||||||
|
|
||||||
res.render('admin/advanced/events', {
|
res.render('admin/advanced/events', {
|
||||||
events: results.events,
|
events: results.events,
|
||||||
pagination: pagination.create(page, pageCount),
|
pagination: pagination.create(page, pageCount, req.query),
|
||||||
next: 20,
|
filters: filters,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
], next);
|
], next);
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
var async = require('async');
|
var async = require('async');
|
||||||
var validator = require('validator');
|
var validator = require('validator');
|
||||||
var winston = require('winston');
|
var winston = require('winston');
|
||||||
|
var _ = require('lodash');
|
||||||
|
|
||||||
var db = require('./database');
|
var db = require('./database');
|
||||||
var batch = require('./batch');
|
var batch = require('./batch');
|
||||||
@@ -12,6 +13,39 @@ var utils = require('./utils');
|
|||||||
|
|
||||||
var events = module.exports;
|
var events = module.exports;
|
||||||
|
|
||||||
|
events.types = [
|
||||||
|
'plugin-activate',
|
||||||
|
'plugin-deactivate',
|
||||||
|
'restart',
|
||||||
|
'build',
|
||||||
|
'config-change',
|
||||||
|
'settings-change',
|
||||||
|
'category-purge',
|
||||||
|
'privilege-change',
|
||||||
|
'post-delete',
|
||||||
|
'post-restore',
|
||||||
|
'post-purge',
|
||||||
|
'topic-delete',
|
||||||
|
'topic-restore',
|
||||||
|
'topic-purge',
|
||||||
|
'topic-rename',
|
||||||
|
'password-reset',
|
||||||
|
'user-ban',
|
||||||
|
'user-unban',
|
||||||
|
'user-delete',
|
||||||
|
'password-change',
|
||||||
|
'email-change',
|
||||||
|
'username-change',
|
||||||
|
'registration-approved',
|
||||||
|
'registration-rejected',
|
||||||
|
'accept-membership',
|
||||||
|
'reject-membership',
|
||||||
|
'theme-set',
|
||||||
|
'export:uploads',
|
||||||
|
'account-locked',
|
||||||
|
'getUsersCSV',
|
||||||
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Useful options in data: type, uid, ip, targetUid
|
* Useful options in data: type, uid, ip, targetUid
|
||||||
* Everything else gets stringified and shown as pretty JSON string
|
* Everything else gets stringified and shown as pretty JSON string
|
||||||
@@ -31,6 +65,9 @@ events.log = function (data, callback) {
|
|||||||
function (next) {
|
function (next) {
|
||||||
db.sortedSetAdd('events:time', data.timestamp, eid, next);
|
db.sortedSetAdd('events:time', data.timestamp, eid, next);
|
||||||
},
|
},
|
||||||
|
function (next) {
|
||||||
|
db.sortedSetAdd('events:time:' + data.type, data.timestamp, eid, next);
|
||||||
|
},
|
||||||
function (next) {
|
function (next) {
|
||||||
db.setObject('event:' + eid, data, next);
|
db.setObject('event:' + eid, data, next);
|
||||||
},
|
},
|
||||||
@@ -41,10 +78,10 @@ events.log = function (data, callback) {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
events.getEvents = function (start, stop, callback) {
|
events.getEvents = function (filter, start, stop, callback) {
|
||||||
async.waterfall([
|
async.waterfall([
|
||||||
function (next) {
|
function (next) {
|
||||||
db.getSortedSetRevRange('events:time', start, stop, next);
|
db.getSortedSetRevRange('events:time' + (filter ? ':' + filter : ''), start, stop, next);
|
||||||
},
|
},
|
||||||
function (eids, next) {
|
function (eids, next) {
|
||||||
var keys = eids.map(function (eid) {
|
var keys = eids.map(function (eid) {
|
||||||
@@ -123,15 +160,24 @@ function addUserData(eventsData, field, objectName, callback) {
|
|||||||
|
|
||||||
events.deleteEvents = function (eids, callback) {
|
events.deleteEvents = function (eids, callback) {
|
||||||
callback = callback || function () {};
|
callback = callback || function () {};
|
||||||
async.parallel([
|
var keys;
|
||||||
|
async.waterfall([
|
||||||
function (next) {
|
function (next) {
|
||||||
var keys = eids.map(function (eid) {
|
keys = eids.map(function (eid) {
|
||||||
return 'event:' + eid;
|
return 'event:' + eid;
|
||||||
});
|
});
|
||||||
|
db.getObjectsFields(keys, ['type'], next);
|
||||||
|
},
|
||||||
|
function (eventData, next) {
|
||||||
|
var sets = _.uniq(['events:time'].concat(eventData.map(e => 'events:time:' + e.type)));
|
||||||
|
async.parallel([
|
||||||
|
function (next) {
|
||||||
db.deleteAll(keys, next);
|
db.deleteAll(keys, next);
|
||||||
},
|
},
|
||||||
function (next) {
|
function (next) {
|
||||||
db.sortedSetRemove('events:time', eids, next);
|
db.sortedSetRemove(sets, eids, next);
|
||||||
|
},
|
||||||
|
], next);
|
||||||
},
|
},
|
||||||
], callback);
|
], callback);
|
||||||
};
|
};
|
||||||
@@ -146,7 +192,7 @@ events.deleteAll = function (callback) {
|
|||||||
|
|
||||||
events.output = function () {
|
events.output = function () {
|
||||||
console.log('\nDisplaying last ten administrative events...'.bold);
|
console.log('\nDisplaying last ten administrative events...'.bold);
|
||||||
events.getEvents(0, 9, function (err, events) {
|
events.getEvents('', 0, 9, function (err, events) {
|
||||||
if (err) {
|
if (err) {
|
||||||
winston.error('Error fetching events', err);
|
winston.error('Error fetching events', err);
|
||||||
throw err;
|
throw err;
|
||||||
|
|||||||
@@ -84,8 +84,10 @@ Categories.setPrivilege = function (socket, data, callback) {
|
|||||||
function onSetComplete() {
|
function onSetComplete() {
|
||||||
events.log({
|
events.log({
|
||||||
uid: socket.uid,
|
uid: socket.uid,
|
||||||
|
type: 'privilege-change',
|
||||||
ip: socket.ip,
|
ip: socket.ip,
|
||||||
privilege: data.privilege.toString(),
|
privilege: data.privilege.toString(),
|
||||||
|
cid: data.cid,
|
||||||
action: data.set ? 'grant' : 'rescind',
|
action: data.set ? 'grant' : 'rescind',
|
||||||
target: data.member,
|
target: data.member,
|
||||||
}, callback);
|
}, callback);
|
||||||
|
|||||||
46
src/upgrades/1.10.2/event_filters.js
Normal file
46
src/upgrades/1.10.2/event_filters.js
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
var db = require('../../database');
|
||||||
|
|
||||||
|
var async = require('async');
|
||||||
|
var batch = require('../../batch');
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
name: 'add filters to events',
|
||||||
|
timestamp: Date.UTC(2018, 9, 4),
|
||||||
|
method: function (callback) {
|
||||||
|
const progress = this.progress;
|
||||||
|
|
||||||
|
batch.processSortedSet('events:time', function (eids, next) {
|
||||||
|
async.eachSeries(eids, function (eid, next) {
|
||||||
|
progress.incr();
|
||||||
|
|
||||||
|
db.getObject('event:' + eid, function (err, eventData) {
|
||||||
|
if (err) {
|
||||||
|
return next(err);
|
||||||
|
}
|
||||||
|
if (!eventData) {
|
||||||
|
return db.sortedSetRemove('events:time', eid, next);
|
||||||
|
}
|
||||||
|
// privilege events we're missing type field
|
||||||
|
if (!eventData.type && eventData.privilege) {
|
||||||
|
eventData.type = 'privilege-change';
|
||||||
|
async.waterfall([
|
||||||
|
function (next) {
|
||||||
|
db.setObjectField('event:' + eid, 'type', 'privilege-change', next);
|
||||||
|
},
|
||||||
|
function (next) {
|
||||||
|
db.sortedSetAdd('events:time:' + eventData.type, eventData.timestamp, eid, next);
|
||||||
|
},
|
||||||
|
], next);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
db.sortedSetAdd('events:time:' + (eventData.type || ''), eventData.timestamp, eid, next);
|
||||||
|
});
|
||||||
|
}, next);
|
||||||
|
}, {
|
||||||
|
progress: this.progress,
|
||||||
|
}, callback);
|
||||||
|
},
|
||||||
|
};
|
||||||
@@ -1,8 +1,13 @@
|
|||||||
<div class="row events">
|
<div class="row events">
|
||||||
<div class="col-lg-9">
|
<div class="col-lg-9">
|
||||||
|
<select id="filter" class="form-control">
|
||||||
|
<!-- BEGIN filters -->
|
||||||
|
<option value="{filters.value}" <!-- IF filters.selected -->selected<!-- ENDIF filters.selected -->>{filters.name}</option>
|
||||||
|
<!-- END filters -->
|
||||||
|
</select>
|
||||||
<div class="panel panel-default">
|
<div class="panel panel-default">
|
||||||
<div class="panel-heading"><i class="fa fa-calendar-o"></i> [[admin/advanced/events:events]]</div>
|
<div class="panel-heading"><i class="fa fa-calendar-o"></i> [[admin/advanced/events:events]]</div>
|
||||||
<div class="panel-body" data-next="{next}">
|
<div class="panel-body">
|
||||||
<!-- IF !events.length -->
|
<!-- IF !events.length -->
|
||||||
<div class="alert alert-info">[[admin/advanced/events:no-events]]</div>
|
<div class="alert alert-info">[[admin/advanced/events:no-events]]</div>
|
||||||
<!-- ENDIF !events.length -->
|
<!-- ENDIF !events.length -->
|
||||||
|
|||||||
Reference in New Issue
Block a user