| 
									
										
										
										
											2020-05-01 15:58:01 -04:00
										 |  |  | 'use strict'; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-01 10:37:42 -05:00
										 |  |  | const validator = require('validator'); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-16 10:34:37 -04:00
										 |  |  | const api = require('../../api'); | 
					
						
							| 
									
										
										
										
											2020-05-01 15:58:01 -04:00
										 |  |  | const topics = require('../../topics'); | 
					
						
							| 
									
										
										
										
											2020-12-03 15:04:23 -05:00
										 |  |  | const privileges = require('../../privileges'); | 
					
						
							| 
									
										
										
										
											2020-05-01 15:58:01 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | const helpers = require('../helpers'); | 
					
						
							| 
									
										
										
										
											2020-12-09 16:46:19 -05:00
										 |  |  | const middleware = require('../../middleware'); | 
					
						
							| 
									
										
										
										
											2020-12-01 10:37:42 -05:00
										 |  |  | const uploadsController = require('../uploads'); | 
					
						
							| 
									
										
										
										
											2020-05-01 15:58:01 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | const Topics = module.exports; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-29 10:31:53 -05:00
										 |  |  | Topics.get = async (req, res) => { | 
					
						
							|  |  |  | 	helpers.formatApiResponse(200, res, await api.topics.get(req, req.params)); | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-01 15:58:01 -04:00
										 |  |  | Topics.create = async (req, res) => { | 
					
						
							| 
									
										
										
										
											2020-10-16 10:34:37 -04:00
										 |  |  | 	const payload = await api.topics.create(req, req.body); | 
					
						
							|  |  |  | 	if (payload.queued) { | 
					
						
							|  |  |  | 		helpers.formatApiResponse(202, res, payload); | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		helpers.formatApiResponse(200, res, payload); | 
					
						
							| 
									
										
										
										
											2020-05-01 15:58:01 -04:00
										 |  |  | 	} | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Topics.reply = async (req, res) => { | 
					
						
							| 
									
										
										
										
											2020-10-16 11:01:10 -04:00
										 |  |  | 	const payload = await api.topics.reply(req, { ...req.body, tid: req.params.tid }); | 
					
						
							|  |  |  | 	helpers.formatApiResponse(200, res, payload); | 
					
						
							| 
									
										
										
										
											2020-05-01 15:58:01 -04:00
										 |  |  | }; | 
					
						
							| 
									
										
										
										
											2020-10-02 16:35:45 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | Topics.delete = async (req, res) => { | 
					
						
							| 
									
										
										
										
											2020-10-16 21:36:59 -04:00
										 |  |  | 	await api.topics.delete(req, { tids: [req.params.tid] }); | 
					
						
							| 
									
										
										
										
											2020-10-02 16:35:45 -04:00
										 |  |  | 	helpers.formatApiResponse(200, res); | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Topics.restore = async (req, res) => { | 
					
						
							| 
									
										
										
										
											2020-10-16 21:36:59 -04:00
										 |  |  | 	await api.topics.restore(req, { tids: [req.params.tid] }); | 
					
						
							| 
									
										
										
										
											2020-10-02 16:35:45 -04:00
										 |  |  | 	helpers.formatApiResponse(200, res); | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Topics.purge = async (req, res) => { | 
					
						
							| 
									
										
										
										
											2020-10-16 21:36:59 -04:00
										 |  |  | 	await api.topics.purge(req, { tids: [req.params.tid] }); | 
					
						
							| 
									
										
										
										
											2020-10-02 16:35:45 -04:00
										 |  |  | 	helpers.formatApiResponse(200, res); | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Topics.pin = async (req, res) => { | 
					
						
							| 
									
										
										
										
											2020-11-20 11:31:14 -05:00
										 |  |  | 	// Pin expiry was not available w/ sockets hence not included in api lib method
 | 
					
						
							|  |  |  | 	if (req.body.expiry) { | 
					
						
							| 
									
										
										
										
											2020-12-01 16:25:13 -05:00
										 |  |  | 		await topics.tools.setPinExpiry(req.params.tid, req.body.expiry, req.uid); | 
					
						
							| 
									
										
										
										
											2020-11-20 11:31:14 -05:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2020-12-01 16:25:13 -05:00
										 |  |  | 	await api.topics.pin(req, {	tids: [req.params.tid] }); | 
					
						
							| 
									
										
										
										
											2020-11-20 11:31:14 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-02 16:35:45 -04:00
										 |  |  | 	helpers.formatApiResponse(200, res); | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Topics.unpin = async (req, res) => { | 
					
						
							| 
									
										
										
										
											2020-10-16 21:36:59 -04:00
										 |  |  | 	await api.topics.unpin(req, { tids: [req.params.tid] }); | 
					
						
							| 
									
										
										
										
											2020-10-02 16:35:45 -04:00
										 |  |  | 	helpers.formatApiResponse(200, res); | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Topics.lock = async (req, res) => { | 
					
						
							| 
									
										
										
										
											2020-10-16 21:36:59 -04:00
										 |  |  | 	await api.topics.lock(req, { tids: [req.params.tid] }); | 
					
						
							| 
									
										
										
										
											2020-10-02 16:35:45 -04:00
										 |  |  | 	helpers.formatApiResponse(200, res); | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Topics.unlock = async (req, res) => { | 
					
						
							| 
									
										
										
										
											2020-10-16 21:36:59 -04:00
										 |  |  | 	await api.topics.unlock(req, { tids: [req.params.tid] }); | 
					
						
							| 
									
										
										
										
											2020-10-02 16:35:45 -04:00
										 |  |  | 	helpers.formatApiResponse(200, res); | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-06 11:36:52 -04:00
										 |  |  | Topics.follow = async (req, res) => { | 
					
						
							| 
									
										
										
										
											2020-10-16 12:30:14 -04:00
										 |  |  | 	await api.topics.follow(req, req.params); | 
					
						
							| 
									
										
										
										
											2020-10-06 11:36:52 -04:00
										 |  |  | 	helpers.formatApiResponse(200, res); | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Topics.ignore = async (req, res) => { | 
					
						
							| 
									
										
										
										
											2020-10-16 12:30:14 -04:00
										 |  |  | 	await api.topics.ignore(req, req.params); | 
					
						
							| 
									
										
										
										
											2020-10-06 11:36:52 -04:00
										 |  |  | 	helpers.formatApiResponse(200, res); | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Topics.unfollow = async (req, res) => { | 
					
						
							| 
									
										
										
										
											2020-10-16 12:30:14 -04:00
										 |  |  | 	await api.topics.unfollow(req, req.params); | 
					
						
							| 
									
										
										
										
											2020-10-06 11:36:52 -04:00
										 |  |  | 	helpers.formatApiResponse(200, res); | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-06 11:54:25 -04:00
										 |  |  | Topics.addTags = async (req, res) => { | 
					
						
							| 
									
										
										
										
											2021-01-12 17:38:35 -05:00
										 |  |  | 	if (!await privileges.topics.canEdit(req.params.tid, req.user.uid)) { | 
					
						
							|  |  |  | 		return helpers.formatApiResponse(403, res); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-06 11:54:25 -04:00
										 |  |  | 	await topics.createTags(req.body.tags, req.params.tid, Date.now()); | 
					
						
							|  |  |  | 	helpers.formatApiResponse(200, res); | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Topics.deleteTags = async (req, res) => { | 
					
						
							| 
									
										
										
										
											2021-01-12 17:38:35 -05:00
										 |  |  | 	if (!await privileges.topics.canEdit(req.params.tid, req.user.uid)) { | 
					
						
							|  |  |  | 		return helpers.formatApiResponse(403, res); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-06 11:54:25 -04:00
										 |  |  | 	await topics.deleteTopicTags(req.params.tid); | 
					
						
							|  |  |  | 	helpers.formatApiResponse(200, res); | 
					
						
							|  |  |  | }; | 
					
						
							| 
									
										
										
										
											2020-12-01 10:37:42 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-03 15:04:23 -05:00
										 |  |  | Topics.getThumbs = async (req, res) => { | 
					
						
							| 
									
										
										
										
											2021-01-17 15:43:21 -05:00
										 |  |  | 	if (isFinite(req.params.tid)) {	// post_uuids can be passed in occasionally, in that case no checks are necessary
 | 
					
						
							|  |  |  | 		const [exists, canRead] = await Promise.all([ | 
					
						
							|  |  |  | 			topics.exists(req.params.tid), | 
					
						
							|  |  |  | 			privileges.topics.can('topics:read', req.params.tid, req.uid), | 
					
						
							|  |  |  | 		]); | 
					
						
							|  |  |  | 		if (!exists || !canRead) { | 
					
						
							|  |  |  | 			return helpers.formatApiResponse(403, res); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2021-01-12 17:38:35 -05:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-03 15:04:23 -05:00
										 |  |  | 	helpers.formatApiResponse(200, res, await topics.thumbs.get(req.params.tid)); | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-04 16:42:39 -05:00
										 |  |  | Topics.addThumb = async (req, res) => { | 
					
						
							| 
									
										
										
										
											2020-12-04 09:37:50 -05:00
										 |  |  | 	await checkThumbPrivileges({ tid: req.params.tid, uid: req.user.uid, res }); | 
					
						
							| 
									
										
										
										
											2020-12-03 16:48:57 -05:00
										 |  |  | 	if (res.headersSent) { | 
					
						
							|  |  |  | 		return; | 
					
						
							| 
									
										
										
										
											2020-12-03 15:04:23 -05:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-04 16:42:39 -05:00
										 |  |  | 	const files = await uploadsController.uploadThumb(req, res);	// response is handled here
 | 
					
						
							| 
									
										
										
										
											2020-12-01 10:37:42 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// Add uploaded files to topic zset
 | 
					
						
							| 
									
										
										
										
											2020-12-04 11:47:22 -05:00
										 |  |  | 	if (files && files.length) { | 
					
						
							|  |  |  | 		await Promise.all(files.map(async (fileObj) => { | 
					
						
							| 
									
										
										
										
											2020-12-09 15:47:58 -05:00
										 |  |  | 			await topics.thumbs.associate({ | 
					
						
							|  |  |  | 				id: req.params.tid, | 
					
						
							|  |  |  | 				path: fileObj.path || null, | 
					
						
							|  |  |  | 				url: fileObj.url, | 
					
						
							|  |  |  | 			}); | 
					
						
							| 
									
										
										
										
											2020-12-04 11:47:22 -05:00
										 |  |  | 		})); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2020-12-01 10:37:42 -05:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-04 09:37:50 -05:00
										 |  |  | Topics.migrateThumbs = async (req, res) => { | 
					
						
							|  |  |  | 	await Promise.all([ | 
					
						
							|  |  |  | 		checkThumbPrivileges({ tid: req.params.tid, uid: req.user.uid, res }), | 
					
						
							|  |  |  | 		checkThumbPrivileges({ tid: req.body.tid, uid: req.user.uid, res }), | 
					
						
							|  |  |  | 	]); | 
					
						
							|  |  |  | 	if (res.headersSent) { | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	await topics.thumbs.migrate(req.params.tid, req.body.tid); | 
					
						
							|  |  |  | 	helpers.formatApiResponse(200, res); | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-01 10:37:42 -05:00
										 |  |  | Topics.deleteThumb = async (req, res) => { | 
					
						
							| 
									
										
										
										
											2020-12-09 15:47:58 -05:00
										 |  |  | 	if (!req.body.path.startsWith('http')) { | 
					
						
							| 
									
										
										
										
											2021-02-04 00:01:39 -07:00
										 |  |  | 		await middleware.assert.path(req, res, () => {}); | 
					
						
							| 
									
										
										
										
											2020-12-09 15:47:58 -05:00
										 |  |  | 		if (res.headersSent) { | 
					
						
							|  |  |  | 			return; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-04 09:37:50 -05:00
										 |  |  | 	await checkThumbPrivileges({ tid: req.params.tid, uid: req.user.uid, res }); | 
					
						
							| 
									
										
										
										
											2020-12-03 16:48:57 -05:00
										 |  |  | 	if (res.headersSent) { | 
					
						
							|  |  |  | 		return; | 
					
						
							| 
									
										
										
										
											2020-12-03 15:04:23 -05:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-03 13:50:30 -05:00
										 |  |  | 	await topics.thumbs.delete(req.params.tid, req.body.path); | 
					
						
							| 
									
										
										
										
											2020-12-01 10:37:42 -05:00
										 |  |  | 	helpers.formatApiResponse(200, res, await topics.thumbs.get(req.params.tid)); | 
					
						
							|  |  |  | }; | 
					
						
							| 
									
										
										
										
											2020-12-03 16:48:57 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-04 09:37:50 -05:00
										 |  |  | async function checkThumbPrivileges({ tid, uid, res }) { | 
					
						
							| 
									
										
										
										
											2021-02-04 02:07:29 -07:00
										 |  |  | 	// req.params.tid could be either a tid (pushing a new thumb to an existing topic)
 | 
					
						
							|  |  |  | 	// or a post UUID (a new topic being composed)
 | 
					
						
							| 
									
										
										
										
											2020-12-04 09:37:50 -05:00
										 |  |  | 	const isUUID = validator.isUUID(tid); | 
					
						
							| 
									
										
										
										
											2020-12-03 16:48:57 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// Sanity-check the tid if it's strictly not a uuid
 | 
					
						
							| 
									
										
										
										
											2020-12-04 09:37:50 -05:00
										 |  |  | 	if (!isUUID && (isNaN(parseInt(tid, 10)) || !await topics.exists(tid))) { | 
					
						
							| 
									
										
										
										
											2020-12-03 16:48:57 -05:00
										 |  |  | 		return helpers.formatApiResponse(404, res, new Error('[[error:no-topic]]')); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// While drafts are not protected, tids are
 | 
					
						
							| 
									
										
										
										
											2020-12-04 09:37:50 -05:00
										 |  |  | 	if (!isUUID && !await privileges.topics.canEdit(tid, uid)) { | 
					
						
							| 
									
										
										
										
											2020-12-03 16:48:57 -05:00
										 |  |  | 		return helpers.formatApiResponse(403, res, new Error('[[error:no-privileges]]')); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2021-01-13 10:09:17 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | Topics.getEvents = async (req, res) => { | 
					
						
							|  |  |  | 	if (!await privileges.topics.can('topics:read', req.params.tid, req.uid)) { | 
					
						
							|  |  |  | 		return helpers.formatApiResponse(403, res); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	helpers.formatApiResponse(200, res, await topics.events.get(req.params.tid)); | 
					
						
							|  |  |  | }; |