mirror of
				https://github.com/NodeBB/NodeBB.git
				synced 2025-10-31 02:55:58 +01:00 
			
		
		
		
	refactor: topic tools' actions to use api lib
This commit is contained in:
		| @@ -4,6 +4,8 @@ const user = require('../user'); | |||||||
| const topics = require('../topics'); | const topics = require('../topics'); | ||||||
| const posts = require('../posts'); | const posts = require('../posts'); | ||||||
| const meta = require('../meta'); | const meta = require('../meta'); | ||||||
|  | const events = require('../events'); | ||||||
|  | const privileges = require('../privileges'); | ||||||
|  |  | ||||||
| const controllerHelpers = require('../controllers/helpers'); | const controllerHelpers = require('../controllers/helpers'); | ||||||
| const socketHelpers = require('../socket.io/helpers'); | const socketHelpers = require('../socket.io/helpers'); | ||||||
| @@ -75,3 +77,84 @@ topicsAPI.reply = async function (caller, data) { | |||||||
|  |  | ||||||
| 	return postObj[0]; | 	return postObj[0]; | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | topicsAPI.delete = async function (caller, data) { | ||||||
|  | 	await doTopicAction('delete', 'event:topic_deleted', caller, { | ||||||
|  | 		tids: [data.tid], | ||||||
|  | 	}); | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | topicsAPI.restore = async function (caller, data) { | ||||||
|  | 	await doTopicAction('restore', 'event:topic_restored', caller, { | ||||||
|  | 		tids: [data.tid], | ||||||
|  | 	}); | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | topicsAPI.purge = async function (caller, data) { | ||||||
|  | 	await doTopicAction('purge', 'event:topic_purged', caller, { | ||||||
|  | 		tids: [data.tid], | ||||||
|  | 	}); | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | topicsAPI.pin = async function (caller, data) { | ||||||
|  | 	await doTopicAction('pin', 'event:topic_pinned', caller, { | ||||||
|  | 		tids: [data.tid], | ||||||
|  | 	}); | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | topicsAPI.unpin = async function (caller, data) { | ||||||
|  | 	await doTopicAction('unpin', 'event:topic_unpinned', caller, { | ||||||
|  | 		tids: [data.tid], | ||||||
|  | 	}); | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | topicsAPI.lock = async function (caller, data) { | ||||||
|  | 	await doTopicAction('lock', 'event:topic_locked', caller, { | ||||||
|  | 		tids: [data.tid], | ||||||
|  | 	}); | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | topicsAPI.unlock = async function (caller, data) { | ||||||
|  | 	await doTopicAction('unlock', 'event:topic_unlocked', caller, { | ||||||
|  | 		tids: [data.tid], | ||||||
|  | 	}); | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | async function doTopicAction(action, event, caller, { tids }) { | ||||||
|  | 	if (!Array.isArray(tids)) { | ||||||
|  | 		throw new Error('[[error:invalid-tid]]'); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	const exists = (await Promise.all(tids.map(async tid => await topics.exists(tid)))).every(Boolean); | ||||||
|  | 	if (!exists) { | ||||||
|  | 		throw new Error('[[error:no-topic]]'); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if (typeof topics.tools[action] !== 'function') { | ||||||
|  | 		return; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	const uids = await user.getUidsFromSet('users:online', 0, -1); | ||||||
|  |  | ||||||
|  | 	await Promise.all(tids.map(async function (tid) { | ||||||
|  | 		const title = await topics.getTopicField(tid, 'title'); | ||||||
|  | 		const data = await topics.tools[action](tid, caller.uid); | ||||||
|  | 		const notifyUids = await privileges.categories.filterUids('topics:read', data.cid, uids); | ||||||
|  | 		socketHelpers.emitToUids(event, data, notifyUids); | ||||||
|  | 		await logTopicAction(action, caller, tid, title); | ||||||
|  | 	})); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | async function logTopicAction(action, req, tid, title) { | ||||||
|  | 	var actionsToLog = ['delete', 'restore', 'purge']; | ||||||
|  | 	if (!actionsToLog.includes(action)) { | ||||||
|  | 		return; | ||||||
|  | 	} | ||||||
|  | 	await events.log({ | ||||||
|  | 		type: 'topic-' + action, | ||||||
|  | 		uid: req.uid, | ||||||
|  | 		ip: req.ip, | ||||||
|  | 		tid: tid, | ||||||
|  | 		title: String(title), | ||||||
|  | 	}); | ||||||
|  | } | ||||||
|   | |||||||
| @@ -2,12 +2,8 @@ | |||||||
|  |  | ||||||
| const api = require('../../api'); | const api = require('../../api'); | ||||||
| const topics = require('../../topics'); | const topics = require('../../topics'); | ||||||
| const user = require('../../user'); |  | ||||||
| const events = require('../../events'); |  | ||||||
| const privileges = require('../../privileges'); |  | ||||||
|  |  | ||||||
| const helpers = require('../helpers'); | const helpers = require('../helpers'); | ||||||
| const socketHelpers = require('../../socket.io/helpers'); |  | ||||||
|  |  | ||||||
| const Topics = module.exports; | const Topics = module.exports; | ||||||
|  |  | ||||||
| @@ -26,51 +22,37 @@ Topics.reply = async (req, res) => { | |||||||
| }; | }; | ||||||
|  |  | ||||||
| Topics.delete = async (req, res) => { | Topics.delete = async (req, res) => { | ||||||
| 	await doTopicAction('delete', 'event:topic_deleted', req, { | 	await api.topics.delete(req, req.params); | ||||||
| 		tids: [req.params.tid], |  | ||||||
| 	}); |  | ||||||
| 	helpers.formatApiResponse(200, res); | 	helpers.formatApiResponse(200, res); | ||||||
| }; | }; | ||||||
|  |  | ||||||
| Topics.restore = async (req, res) => { | Topics.restore = async (req, res) => { | ||||||
| 	await doTopicAction('restore', 'event:topic_restored', req, { | 	await api.topics.restore(req, req.params); | ||||||
| 		tids: [req.params.tid], |  | ||||||
| 	}); |  | ||||||
| 	helpers.formatApiResponse(200, res); | 	helpers.formatApiResponse(200, res); | ||||||
| }; | }; | ||||||
|  |  | ||||||
| Topics.purge = async (req, res) => { | Topics.purge = async (req, res) => { | ||||||
| 	await doTopicAction('purge', 'event:topic_purged', req, { | 	await api.topics.purge(req, req.params); | ||||||
| 		tids: [req.params.tid], |  | ||||||
| 	}); |  | ||||||
| 	helpers.formatApiResponse(200, res); | 	helpers.formatApiResponse(200, res); | ||||||
| }; | }; | ||||||
|  |  | ||||||
| Topics.pin = async (req, res) => { | Topics.pin = async (req, res) => { | ||||||
| 	await doTopicAction('pin', 'event:topic_pinned', req, { | 	await api.topics.pin(req, req.params); | ||||||
| 		tids: [req.params.tid], |  | ||||||
| 	}); |  | ||||||
| 	helpers.formatApiResponse(200, res); | 	helpers.formatApiResponse(200, res); | ||||||
| }; | }; | ||||||
|  |  | ||||||
| Topics.unpin = async (req, res) => { | Topics.unpin = async (req, res) => { | ||||||
| 	await doTopicAction('unpin', 'event:topic_unpinned', req, { | 	await api.topics.unpin(req, req.params); | ||||||
| 		tids: [req.params.tid], |  | ||||||
| 	}); |  | ||||||
| 	helpers.formatApiResponse(200, res); | 	helpers.formatApiResponse(200, res); | ||||||
| }; | }; | ||||||
|  |  | ||||||
| Topics.lock = async (req, res) => { | Topics.lock = async (req, res) => { | ||||||
| 	await doTopicAction('lock', 'event:topic_locked', req, { | 	await api.topics.lock(req, req.params); | ||||||
| 		tids: [req.params.tid], |  | ||||||
| 	}); |  | ||||||
| 	helpers.formatApiResponse(200, res); | 	helpers.formatApiResponse(200, res); | ||||||
| }; | }; | ||||||
|  |  | ||||||
| Topics.unlock = async (req, res) => { | Topics.unlock = async (req, res) => { | ||||||
| 	await doTopicAction('unlock', 'event:topic_unlocked', req, { | 	await api.topics.unlock(req, req.params); | ||||||
| 		tids: [req.params.tid], |  | ||||||
| 	}); |  | ||||||
| 	helpers.formatApiResponse(200, res); | 	helpers.formatApiResponse(200, res); | ||||||
| }; | }; | ||||||
|  |  | ||||||
| @@ -98,37 +80,3 @@ Topics.deleteTags = async (req, res) => { | |||||||
| 	await topics.deleteTopicTags(req.params.tid); | 	await topics.deleteTopicTags(req.params.tid); | ||||||
| 	helpers.formatApiResponse(200, res); | 	helpers.formatApiResponse(200, res); | ||||||
| }; | }; | ||||||
|  |  | ||||||
| async function doTopicAction(action, event, socket, { tids }) { |  | ||||||
| 	if (!Array.isArray(tids)) { |  | ||||||
| 		throw new Error('[[error:invalid-tid]]'); |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if (typeof topics.tools[action] !== 'function') { |  | ||||||
| 		return; |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	const uids = await user.getUidsFromSet('users:online', 0, -1); |  | ||||||
|  |  | ||||||
| 	await Promise.all(tids.map(async function (tid) { |  | ||||||
| 		const title = await topics.getTopicField(tid, 'title'); |  | ||||||
| 		const data = await topics.tools[action](tid, socket.uid); |  | ||||||
| 		const notifyUids = await privileges.categories.filterUids('topics:read', data.cid, uids); |  | ||||||
| 		socketHelpers.emitToUids(event, data, notifyUids); |  | ||||||
| 		await logTopicAction(action, socket, tid, title); |  | ||||||
| 	})); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| async function logTopicAction(action, req, tid, title) { |  | ||||||
| 	var actionsToLog = ['delete', 'restore', 'purge']; |  | ||||||
| 	if (!actionsToLog.includes(action)) { |  | ||||||
| 		return; |  | ||||||
| 	} |  | ||||||
| 	await events.log({ |  | ||||||
| 		type: 'topic-' + action, |  | ||||||
| 		uid: req.uid, |  | ||||||
| 		ip: req.ip, |  | ||||||
| 		tid: tid, |  | ||||||
| 		title: String(title), |  | ||||||
| 	}); |  | ||||||
| } |  | ||||||
|   | |||||||
| @@ -12,16 +12,16 @@ module.exports = function () { | |||||||
|  |  | ||||||
| 	setupApiRoute(router, 'post', '/', [...middlewares, middleware.checkRequired.bind(null, ['cid', 'title', 'content'])], controllers.write.topics.create); | 	setupApiRoute(router, 'post', '/', [...middlewares, middleware.checkRequired.bind(null, ['cid', 'title', 'content'])], controllers.write.topics.create); | ||||||
| 	setupApiRoute(router, 'post', '/:tid', [...middlewares, middleware.checkRequired.bind(null, ['content']), middleware.assert.topic], controllers.write.topics.reply); | 	setupApiRoute(router, 'post', '/:tid', [...middlewares, middleware.checkRequired.bind(null, ['content']), middleware.assert.topic], controllers.write.topics.reply); | ||||||
| 	setupApiRoute(router, 'delete', '/:tid', [...middlewares, middleware.assert.topic], controllers.write.topics.purge); | 	setupApiRoute(router, 'delete', '/:tid', [...middlewares], controllers.write.topics.purge); | ||||||
|  |  | ||||||
| 	setupApiRoute(router, 'put', '/:tid/state', [...middlewares, middleware.assert.topic], controllers.write.topics.restore); | 	setupApiRoute(router, 'put', '/:tid/state', [...middlewares], controllers.write.topics.restore); | ||||||
| 	setupApiRoute(router, 'delete', '/:tid/state', [...middlewares, middleware.assert.topic], controllers.write.topics.delete); | 	setupApiRoute(router, 'delete', '/:tid/state', [...middlewares], controllers.write.topics.delete); | ||||||
|  |  | ||||||
| 	setupApiRoute(router, 'put', '/:tid/pin', [...middlewares, middleware.assert.topic], controllers.write.topics.pin); | 	setupApiRoute(router, 'put', '/:tid/pin', [...middlewares], controllers.write.topics.pin); | ||||||
| 	setupApiRoute(router, 'delete', '/:tid/pin', [...middlewares, middleware.assert.topic], controllers.write.topics.unpin); | 	setupApiRoute(router, 'delete', '/:tid/pin', [...middlewares], controllers.write.topics.unpin); | ||||||
|  |  | ||||||
| 	setupApiRoute(router, 'put', '/:tid/lock', [...middlewares, middleware.assert.topic], controllers.write.topics.lock); | 	setupApiRoute(router, 'put', '/:tid/lock', [...middlewares], controllers.write.topics.lock); | ||||||
| 	setupApiRoute(router, 'delete', '/:tid/lock', [...middlewares, middleware.assert.topic], controllers.write.topics.unlock); | 	setupApiRoute(router, 'delete', '/:tid/lock', [...middlewares], controllers.write.topics.unlock); | ||||||
|  |  | ||||||
| 	setupApiRoute(router, 'put', '/:tid/follow', [...middlewares, middleware.assert.topic], controllers.write.topics.follow); | 	setupApiRoute(router, 'put', '/:tid/follow', [...middlewares, middleware.assert.topic], controllers.write.topics.follow); | ||||||
| 	setupApiRoute(router, 'delete', '/:tid/follow', [...middlewares, middleware.assert.topic], controllers.write.topics.unfollow); | 	setupApiRoute(router, 'delete', '/:tid/follow', [...middlewares, middleware.assert.topic], controllers.write.topics.unfollow); | ||||||
|   | |||||||
| @@ -1,11 +1,9 @@ | |||||||
| 'use strict'; | 'use strict'; | ||||||
|  |  | ||||||
| const user = require('../../user'); | const api = require('../../api'); | ||||||
| const topics = require('../../topics'); | const topics = require('../../topics'); | ||||||
| const events = require('../../events'); |  | ||||||
| const privileges = require('../../privileges'); | const privileges = require('../../privileges'); | ||||||
| const plugins = require('../../plugins'); | const plugins = require('../../plugins'); | ||||||
| const socketHelpers = require('../helpers'); |  | ||||||
| const sockets = require('..'); | const sockets = require('..'); | ||||||
|  |  | ||||||
| module.exports = function (SocketTopics) { | module.exports = function (SocketTopics) { | ||||||
| @@ -36,77 +34,39 @@ module.exports = function (SocketTopics) { | |||||||
|  |  | ||||||
| 	SocketTopics.delete = async function (socket, data) { | 	SocketTopics.delete = async function (socket, data) { | ||||||
| 		sockets.warnDeprecated(socket, 'DELETE /api/v3/topics/state'); | 		sockets.warnDeprecated(socket, 'DELETE /api/v3/topics/state'); | ||||||
| 		await SocketTopics.doTopicAction('delete', 'event:topic_deleted', socket, data); | 		await api.topics.delete(socket, data); | ||||||
| 	}; | 	}; | ||||||
|  |  | ||||||
| 	SocketTopics.restore = async function (socket, data) { | 	SocketTopics.restore = async function (socket, data) { | ||||||
| 		sockets.warnDeprecated(socket, 'PUT /api/v3/topics/state'); | 		sockets.warnDeprecated(socket, 'PUT /api/v3/topics/state'); | ||||||
| 		await SocketTopics.doTopicAction('restore', 'event:topic_restored', socket, data); | 		await api.topics.restore(socket, data); | ||||||
| 	}; | 	}; | ||||||
|  |  | ||||||
| 	SocketTopics.purge = async function (socket, data) { | 	SocketTopics.purge = async function (socket, data) { | ||||||
| 		sockets.warnDeprecated(socket, 'DELETE /api/v3/topics'); | 		sockets.warnDeprecated(socket, 'DELETE /api/v3/topics'); | ||||||
| 		await SocketTopics.doTopicAction('purge', 'event:topic_purged', socket, data); | 		await api.topics.purge(socket, data); | ||||||
| 	}; | 	}; | ||||||
|  |  | ||||||
| 	SocketTopics.lock = async function (socket, data) { | 	SocketTopics.lock = async function (socket, data) { | ||||||
| 		sockets.warnDeprecated(socket, 'PUT /api/v3/topics/lock'); | 		sockets.warnDeprecated(socket, 'PUT /api/v3/topics/lock'); | ||||||
| 		await SocketTopics.doTopicAction('lock', 'event:topic_locked', socket, data); | 		await api.topics.lock(socket, data); | ||||||
| 	}; | 	}; | ||||||
|  |  | ||||||
| 	SocketTopics.unlock = async function (socket, data) { | 	SocketTopics.unlock = async function (socket, data) { | ||||||
| 		sockets.warnDeprecated(socket, 'DELETE /api/v3/topics/lock'); | 		sockets.warnDeprecated(socket, 'DELETE /api/v3/topics/lock'); | ||||||
| 		await SocketTopics.doTopicAction('unlock', 'event:topic_unlocked', socket, data); | 		await api.topics.unlock(socket, data); | ||||||
| 	}; | 	}; | ||||||
|  |  | ||||||
| 	SocketTopics.pin = async function (socket, data) { | 	SocketTopics.pin = async function (socket, data) { | ||||||
| 		sockets.warnDeprecated(socket, 'PUT /api/v3/topics/pin'); | 		sockets.warnDeprecated(socket, 'PUT /api/v3/topics/pin'); | ||||||
| 		await SocketTopics.doTopicAction('pin', 'event:topic_pinned', socket, data); | 		await api.topics.pin(socket, data); | ||||||
| 	}; | 	}; | ||||||
|  |  | ||||||
| 	SocketTopics.unpin = async function (socket, data) { | 	SocketTopics.unpin = async function (socket, data) { | ||||||
| 		sockets.warnDeprecated(socket, 'DELETE /api/v3/topics/pin'); | 		sockets.warnDeprecated(socket, 'DELETE /api/v3/topics/pin'); | ||||||
| 		await SocketTopics.doTopicAction('unpin', 'event:topic_unpinned', socket, data); | 		await api.topics.unpin(socket, data); | ||||||
| 	}; | 	}; | ||||||
|  |  | ||||||
| 	SocketTopics.doTopicAction = async function (action, event, socket, data) { |  | ||||||
| 		if (!socket.uid) { |  | ||||||
| 			throw new Error('[[error:no-privileges]]'); |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		if (!data || !Array.isArray(data.tids)) { |  | ||||||
| 			throw new Error('[[error:invalid-tid]]'); |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		if (typeof topics.tools[action] !== 'function') { |  | ||||||
| 			return; |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		const uids = await user.getUidsFromSet('users:online', 0, -1); |  | ||||||
|  |  | ||||||
| 		await Promise.all(data.tids.map(async function (tid) { |  | ||||||
| 			const title = await topics.getTopicField(tid, 'title'); |  | ||||||
| 			const data = await topics.tools[action](tid, socket.uid); |  | ||||||
| 			const notifyUids = await privileges.categories.filterUids('topics:read', data.cid, uids); |  | ||||||
| 			socketHelpers.emitToUids(event, data, notifyUids); |  | ||||||
| 			await logTopicAction(action, socket, tid, title); |  | ||||||
| 		})); |  | ||||||
| 	}; |  | ||||||
|  |  | ||||||
| 	async function logTopicAction(action, socket, tid, title) { |  | ||||||
| 		var actionsToLog = ['delete', 'restore', 'purge']; |  | ||||||
| 		if (!actionsToLog.includes(action)) { |  | ||||||
| 			return; |  | ||||||
| 		} |  | ||||||
| 		await events.log({ |  | ||||||
| 			type: 'topic-' + action, |  | ||||||
| 			uid: socket.uid, |  | ||||||
| 			ip: socket.ip, |  | ||||||
| 			tid: tid, |  | ||||||
| 			title: String(title), |  | ||||||
| 		}); |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	SocketTopics.orderPinnedTopics = async function (socket, data) { | 	SocketTopics.orderPinnedTopics = async function (socket, data) { | ||||||
| 		if (!Array.isArray(data)) { | 		if (!Array.isArray(data)) { | ||||||
| 			throw new Error('[[error:invalid-data]]'); | 			throw new Error('[[error:invalid-data]]'); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user