From 421ba6e1a29fd41a2c53d33edd98b23755f4cd52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bar=C4=B1=C5=9F=20Soner=20U=C5=9Fakl=C4=B1?= Date: Fri, 18 Mar 2022 15:54:40 -0400 Subject: [PATCH] feat: new admin events, closes #10405 --- src/api/posts.js | 19 +++++++++++++++++++ src/events.js | 10 ++++++++++ src/posts/edit.js | 2 ++ src/socket.io/posts.js | 22 ++++++++++++++++++++++ src/socket.io/topics.js | 12 +++++++++++- src/socket.io/topics/merge.js | 8 ++++++++ src/socket.io/topics/move.js | 17 +++++++++++++++++ 7 files changed, 89 insertions(+), 1 deletion(-) diff --git a/src/api/posts.js b/src/api/posts.js index ef664c10e7..abd40eda38 100644 --- a/src/api/posts.js +++ b/src/api/posts.js @@ -70,6 +70,18 @@ postsAPI.edit = async function (caller, data) { if (editResult.topic.isMainPost) { await topics.thumbs.migrate(data.uuid, editResult.topic.tid); } + const selfPost = parseInt(caller.uid, 10) === parseInt(editResult.post.uid, 10); + if (!selfPost && editResult.post.changed) { + await events.log({ + type: `post-edit`, + uid: caller.uid, + ip: caller.ip, + pid: editResult.post.pid, + oldContent: editResult.post.oldContent, + newContent: editResult.post.newContent, + }); + } + if (editResult.topic.renamed) { await events.log({ type: 'topic-rename', @@ -227,6 +239,13 @@ postsAPI.move = async function (caller, data) { const [postDeleted, topicDeleted] = await Promise.all([ posts.getPostField(data.pid, 'deleted'), topics.getTopicField(data.tid, 'deleted'), + await events.log({ + type: `post-move`, + uid: caller.uid, + ip: caller.ip, + pid: data.pid, + toTid: data.tid, + }), ]); if (!postDeleted && !topicDeleted) { diff --git a/src/events.js b/src/events.js index b4ce5e3fbd..637f53acf6 100644 --- a/src/events.js +++ b/src/events.js @@ -26,11 +26,21 @@ events.types = [ 'post-delete', 'post-restore', 'post-purge', + 'post-edit', + 'post-move', 'post-change-owner', + 'post-queue-reply-accept', + 'post-queue-topic-accept', + 'post-queue-reply-reject', + 'post-queue-topic-reject', 'topic-delete', 'topic-restore', 'topic-purge', 'topic-rename', + 'topic-merge', + 'topic-fork', + 'topic-move', + 'topic-move-all', 'password-reset', 'user-makeAdmin', 'user-removeAdmin', diff --git a/src/posts/edit.js b/src/posts/edit.js index 8de8f9da1a..f325e23269 100644 --- a/src/posts/edit.js +++ b/src/posts/edit.js @@ -73,6 +73,8 @@ module.exports = function (Posts) { returnPostData.topic = topic; returnPostData.editedISO = utils.toISOString(editPostData.edited); returnPostData.changed = contentChanged; + returnPostData.oldContent = oldContent; + returnPostData.newContent = data.content; await topics.notifyFollowers(returnPostData, data.uid, { type: 'post-edit', diff --git a/src/socket.io/posts.js b/src/socket.io/posts.js index 322e058935..05341be0ae 100644 --- a/src/socket.io/posts.js +++ b/src/socket.io/posts.js @@ -11,6 +11,7 @@ const topics = require('../topics'); const user = require('../user'); const notifications = require('../notifications'); const utils = require('../utils'); +const events = require('../events'); const SocketPosts = module.exports; @@ -108,6 +109,7 @@ SocketPosts.accept = async function (socket, data) { if (result && socket.uid !== parseInt(result.uid, 10)) { await sendQueueNotification('post-queue-accepted', result.uid, `/post/${result.pid}`); } + await logQueueEvent(socket, result, 'accept'); }; SocketPosts.reject = async function (socket, data) { @@ -116,8 +118,28 @@ SocketPosts.reject = async function (socket, data) { if (result && socket.uid !== parseInt(result.uid, 10)) { await sendQueueNotification('post-queue-rejected', result.uid, '/'); } + await logQueueEvent(socket, result, 'reject'); }; +async function logQueueEvent(socket, result, type) { + await events.log({ + type: `post-queue-${result.type}-${type}`, + uid: socket.uid, + ip: socket.ip, + content: result.data.content, + targetUid: result.uid, + ...(result.type === 'topic' ? + { + cid: result.data.cid, + title: result.data.title, + } : + { + tid: result.data.tid, + }), + ...(result.pid ? { pid: result.pid } : {}), + }); +} + SocketPosts.notify = async function (socket, data) { await canEditQueue(socket, data, 'notify'); const result = await posts.getFromQueue(data.id); diff --git a/src/socket.io/topics.js b/src/socket.io/topics.js index 4183063b1f..df20a6d657 100644 --- a/src/socket.io/topics.js +++ b/src/socket.io/topics.js @@ -9,6 +9,7 @@ const user = require('../user'); const meta = require('../meta'); const privileges = require('../privileges'); const cache = require('../cache'); +const events = require('../events'); const SocketTopics = module.exports; @@ -46,7 +47,16 @@ SocketTopics.createTopicFromPosts = async function (socket, data) { throw new Error('[[error:invalid-data]]'); } - return await topics.createTopicFromPosts(socket.uid, data.title, data.pids, data.fromTid); + const result = await topics.createTopicFromPosts(socket.uid, data.title, data.pids, data.fromTid); + await events.log({ + type: `topic-fork`, + uid: socket.uid, + ip: socket.ip, + pids: String(data.pids), + fromTid: data.fromTid, + toTid: result.tid, + }); + return result; }; SocketTopics.isFollowed = async function (socket, tid) { diff --git a/src/socket.io/topics/merge.js b/src/socket.io/topics/merge.js index 8fa275042a..238faa563d 100644 --- a/src/socket.io/topics/merge.js +++ b/src/socket.io/topics/merge.js @@ -2,6 +2,7 @@ const topics = require('../../topics'); const privileges = require('../../privileges'); +const events = require('../../events'); module.exports = function (SocketTopics) { SocketTopics.merge = async function (socket, data) { @@ -16,6 +17,13 @@ module.exports = function (SocketTopics) { throw new Error('[[error:invalid-data]]'); } const mergeIntoTid = await topics.merge(data.tids, socket.uid, data.options); + await events.log({ + type: `topic-merge`, + uid: socket.uid, + ip: socket.ip, + mergeIntoTid: mergeIntoTid, + tids: String(data.tids), + }); return mergeIntoTid; }; }; diff --git a/src/socket.io/topics/move.js b/src/socket.io/topics/move.js index 261dba980f..5caeaad9f3 100644 --- a/src/socket.io/topics/move.js +++ b/src/socket.io/topics/move.js @@ -6,6 +6,7 @@ const topics = require('../../topics'); const categories = require('../../categories'); const privileges = require('../../privileges'); const socketHelpers = require('../helpers'); +const events = require('../../events'); module.exports = function (SocketTopics) { SocketTopics.move = async function (socket, data) { @@ -34,6 +35,15 @@ module.exports = function (SocketTopics) { if (!topicData.deleted) { socketHelpers.sendNotificationToTopicOwner(tid, socket.uid, 'move', 'notifications:moved_your_topic'); } + + await events.log({ + type: `topic-move`, + uid: socket.uid, + ip: socket.ip, + tid: tid, + fromCid: topicData.cid, + toCid: data.cid, + }); }); }; @@ -52,5 +62,12 @@ module.exports = function (SocketTopics) { await async.eachLimit(tids, 50, async (tid) => { await topics.tools.move(tid, data); }); + await events.log({ + type: `topic-move-all`, + uid: socket.uid, + ip: socket.ip, + fromCid: data.currentCid, + toCid: data.cid, + }); }; };