From 8bd63f61e058c688af8baf0baa89656c789ab9cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bar=C4=B1=C5=9F=20Soner=20U=C5=9Fakl=C4=B1?= Date: Sat, 25 Jul 2020 18:26:09 -0400 Subject: [PATCH] feat: resolve flag on delete/purge/ban/delete account --- src/flags.js | 21 ++++++++++++++++----- src/posts/delete.js | 5 +++++ src/socket.io/admin/user.js | 2 ++ src/socket.io/user.js | 4 ++++ src/socket.io/user/ban.js | 2 ++ src/user/delete.js | 8 +++++--- 6 files changed, 34 insertions(+), 8 deletions(-) diff --git a/src/flags.js b/src/flags.js index a2f55eb307..559214a3b4 100644 --- a/src/flags.js +++ b/src/flags.js @@ -381,10 +381,10 @@ Flags.getReports = async function (flagId) { Flags.addReport = async function (flagId, uid, reason, timestamp) { // adds to reporters/report zsets - await Promise.all([ - db.sortedSetAdd(`flags:byReporter:${uid}`, timestamp, flagId), - db.sortedSetAdd(`flag:${flagId}:reports`, timestamp, reason), - db.sortedSetAdd(`flag:${flagId}:reporters`, timestamp, uid), + await db.sortedSetAddBulk([ + [`flags:byReporter:${uid}`, timestamp, flagId], + [`flag:${flagId}:reports`, timestamp, reason], + [`flag:${flagId}:reporters`, timestamp, uid], ]); }; @@ -463,6 +463,9 @@ Flags.getTargetCid = async function (type, id) { Flags.update = async function (flagId, uid, changeset) { const current = await db.getObjectFields('flag:' + flagId, ['uid', 'state', 'assignee', 'type', 'targetId']); + if (!current.type) { + return; + } const now = changeset.datetime || Date.now(); const notifyAssignee = async function (assigneeId) { if (assigneeId === '' || parseInt(uid, 10) === parseInt(assigneeId, 10)) { @@ -525,8 +528,16 @@ Flags.update = async function (flagId, uid, changeset) { tasks.push(db.setObject('flag:' + flagId, changeset)); tasks.push(Flags.appendHistory(flagId, uid, changeset)); - tasks.push(plugins.fireHook('action:flags.update', { flagId: flagId, changeset: changeset, uid: uid })); await Promise.all(tasks); + + plugins.fireHook('action:flags.update', { flagId: flagId, changeset: changeset, uid: uid }); +}; + +Flags.resolveFlag = async function (type, id, uid) { + const flagId = await Flags.getFlagIdByTarget(type, id); + if (parseInt(flagId, 10)) { + await Flags.update(flagId, uid, { state: 'resolved' }); + } }; Flags.getHistory = async function (flagId) { diff --git a/src/posts/delete.js b/src/posts/delete.js index a64c74552c..e1429cd854 100644 --- a/src/posts/delete.js +++ b/src/posts/delete.js @@ -9,6 +9,7 @@ const user = require('../user'); const groups = require('../groups'); const notifications = require('../notifications'); const plugins = require('../plugins'); +const flags = require('../flags'); module.exports = function (Posts) { Posts.delete = async function (pid, uid) { @@ -38,6 +39,9 @@ module.exports = function (Posts) { ]); await categories.updateRecentTidForCid(postData.cid); plugins.fireHook('action:post.' + type, { post: _.clone(postData), uid: uid }); + if (type === 'delete') { + await flags.resolveFlag('post', pid, uid); + } return postData; } @@ -59,6 +63,7 @@ module.exports = function (Posts) { db.sortedSetsRemove(['posts:pid', 'posts:votes', 'posts:flagged'], pid), Posts.uploads.dissociateAll(pid), ]); + await flags.resolveFlag('post', pid, uid); plugins.fireHook('action:post.purge', { post: postData, uid: uid }); await db.delete('post:' + pid); }; diff --git a/src/socket.io/admin/user.js b/src/socket.io/admin/user.js index f9686d2a21..d728475414 100644 --- a/src/socket.io/admin/user.js +++ b/src/socket.io/admin/user.js @@ -10,6 +10,7 @@ const events = require('../../events'); const meta = require('../../meta'); const plugins = require('../../plugins'); const translator = require('../../translator'); +const flags = require('../../flags'); const User = module.exports; @@ -155,6 +156,7 @@ async function deleteUsers(socket, uids, method) { throw new Error('[[error:cant-delete-other-admins]]'); } async function doDelete(uid) { + await flags.resolveFlag('user', uid, socket.uid); const userData = await method(uid); await events.log({ type: 'user-delete', diff --git a/src/socket.io/user.js b/src/socket.io/user.js index 5a55769001..ec1ea3397a 100644 --- a/src/socket.io/user.js +++ b/src/socket.io/user.js @@ -17,6 +17,7 @@ const db = require('../database'); const userController = require('../controllers/user'); const privileges = require('../privileges'); const utils = require('../utils'); +const flags = require('../flags'); const SocketUser = module.exports; @@ -52,7 +53,10 @@ SocketUser.deleteAccount = async function (socket, data) { if (meta.config.allowAccountDelete !== 1) { throw new Error('[[error:no-privileges]]'); } + + await flags.resolveFlag('user', socket.uid, socket.uid); const userData = await user.deleteAccount(socket.uid); + require('./index').server.sockets.emit('event:user_status_change', { uid: socket.uid, status: 'offline' }); await events.log({ diff --git a/src/socket.io/user/ban.js b/src/socket.io/user/ban.js index c4509e7a77..4088f7ca3d 100644 --- a/src/socket.io/user/ban.js +++ b/src/socket.io/user/ban.js @@ -12,6 +12,7 @@ const plugins = require('../../plugins'); const emailer = require('../../emailer'); const translator = require('../../translator'); const utils = require('../../../public/src/utils'); +const flags = require('../../flags'); module.exports = function (SocketUser) { SocketUser.banUsers = async function (socket, data) { @@ -21,6 +22,7 @@ module.exports = function (SocketUser) { await toggleBan(socket.uid, data.uids, async function (uid) { await banUser(socket.uid, uid, data.until || 0, data.reason || ''); + await flags.resolveFlag('user', uid, socket.uid); await events.log({ type: 'user-ban', uid: socket.uid, diff --git a/src/user/delete.js b/src/user/delete.js index 57ed4adeb7..1925399c81 100644 --- a/src/user/delete.js +++ b/src/user/delete.js @@ -63,11 +63,13 @@ module.exports = function (User) { } async function deleteQueued(uid) { + let deleteIds = []; await batch.processSortedSet('post:queue', async function (ids) { const data = await db.getObjects(ids.map(id => 'post:queue:' + id)); - const deleteIds = data.filter(d => parseInt(d.uid, 10) === parseInt(uid, 10)).map(d => d.id); - await async.eachSeries(deleteIds, posts.removeFromQueue); - }, { alwaysStartAt: 0 }); + const userQueuedIds = data.filter(d => parseInt(d.uid, 10) === parseInt(uid, 10)).map(d => d.id); + deleteIds = deleteIds.concat(userQueuedIds); + }, { batch: 500 }); + await async.eachSeries(deleteIds, posts.removeFromQueue); } async function removeFromSortedSets(uid) {