1 import * as express from 'express'
2 import { body, param, query } from 'express-validator'
6 isAbuseModerationCommentValid,
7 areAbusePredefinedReasonsValid,
8 isAbusePredefinedReasonValid,
11 isAbuseTimestampCoherent,
12 isAbuseTimestampValid,
14 } from '@server/helpers/custom-validators/abuses'
15 import { exists, isIdOrUUIDValid, isIdValid, toIntOrNull } from '@server/helpers/custom-validators/misc'
16 import { doesCommentIdExist } from '@server/helpers/custom-validators/video-comments'
17 import { logger } from '@server/helpers/logger'
18 import { doesAbuseExist, doesAccountIdExist, doesVideoAbuseExist, doesVideoExist } from '@server/helpers/middlewares'
19 import { AbuseMessageModel } from '@server/models/abuse/abuse-message'
20 import { AbuseCreate, UserRight } from '@shared/models'
21 import { areValidationErrors } from './utils'
23 const abuseReportValidator = [
27 .withMessage('Should have a valid accountId'),
31 .custom(isIdOrUUIDValid)
32 .withMessage('Should have a valid videoId'),
35 .customSanitizer(toIntOrNull)
36 .custom(isAbuseTimestampValid)
37 .withMessage('Should have valid starting time value'),
40 .customSanitizer(toIntOrNull)
41 .custom(isAbuseTimestampValid)
42 .withMessage('Should have valid ending time value')
44 .custom(isAbuseTimestampCoherent)
45 .withMessage('Should have a startAt timestamp beginning before endAt'),
50 .withMessage('Should have a valid commentId'),
53 .custom(isAbuseReasonValid)
54 .withMessage('Should have a valid reason'),
56 body('predefinedReasons')
58 .custom(areAbusePredefinedReasonsValid)
59 .withMessage('Should have a valid list of predefined reasons'),
61 async (req: express.Request, res: express.Response, next: express.NextFunction) => {
62 logger.debug('Checking abuseReport parameters', { parameters: req.body })
64 if (areValidationErrors(req, res)) return
66 const body: AbuseCreate = req.body
68 if (body.video?.id && !await doesVideoExist(body.video.id, res)) return
69 if (body.account?.id && !await doesAccountIdExist(body.account.id, res)) return
70 if (body.comment?.id && !await doesCommentIdExist(body.comment.id, res)) return
72 if (!body.video?.id && !body.account?.id && !body.comment?.id) {
74 .json({ error: 'video id or account id or comment id is required.' })
83 const abuseGetValidator = [
84 param('id').custom(isIdValid).not().isEmpty().withMessage('Should have a valid id'),
86 async (req: express.Request, res: express.Response, next: express.NextFunction) => {
87 logger.debug('Checking abuseGetValidator parameters', { parameters: req.body })
89 if (areValidationErrors(req, res)) return
90 if (!await doesAbuseExist(req.params.id, res)) return
96 const abuseUpdateValidator = [
97 param('id').custom(isIdValid).not().isEmpty().withMessage('Should have a valid id'),
101 .custom(isAbuseStateValid).withMessage('Should have a valid abuse state'),
102 body('moderationComment')
104 .custom(isAbuseModerationCommentValid).withMessage('Should have a valid moderation comment'),
106 async (req: express.Request, res: express.Response, next: express.NextFunction) => {
107 logger.debug('Checking abuseUpdateValidator parameters', { parameters: req.body })
109 if (areValidationErrors(req, res)) return
110 if (!await doesAbuseExist(req.params.id, res)) return
116 const abuseListForAdminsValidator = [
119 .custom(isIdValid).withMessage('Should have a valid id'),
122 .custom(isAbuseFilterValid)
123 .withMessage('Should have a valid filter'),
124 query('predefinedReason')
126 .custom(isAbusePredefinedReasonValid)
127 .withMessage('Should have a valid predefinedReason'),
130 .custom(exists).withMessage('Should have a valid search'),
133 .custom(isAbuseStateValid).withMessage('Should have a valid abuse state'),
136 .custom(isAbuseVideoIsValid).withMessage('Should have a valid "video is" attribute'),
137 query('searchReporter')
139 .custom(exists).withMessage('Should have a valid reporter search'),
140 query('searchReportee')
142 .custom(exists).withMessage('Should have a valid reportee search'),
145 .custom(exists).withMessage('Should have a valid video search'),
146 query('searchVideoChannel')
148 .custom(exists).withMessage('Should have a valid video channel search'),
150 (req: express.Request, res: express.Response, next: express.NextFunction) => {
151 logger.debug('Checking abuseListForAdminsValidator parameters', { parameters: req.body })
153 if (areValidationErrors(req, res)) return
159 const abuseListForUserValidator = [
162 .custom(isIdValid).withMessage('Should have a valid id'),
166 .custom(exists).withMessage('Should have a valid search'),
170 .custom(isAbuseStateValid).withMessage('Should have a valid abuse state'),
172 (req: express.Request, res: express.Response, next: express.NextFunction) => {
173 logger.debug('Checking abuseListForUserValidator parameters', { parameters: req.body })
175 if (areValidationErrors(req, res)) return
181 const getAbuseValidator = [
182 param('id').custom(isIdValid).not().isEmpty().withMessage('Should have a valid id'),
184 async (req: express.Request, res: express.Response, next: express.NextFunction) => {
185 logger.debug('Checking getAbuseValidator parameters', { parameters: req.body })
187 if (areValidationErrors(req, res)) return
188 if (!await doesAbuseExist(req.params.id, res)) return
190 const user = res.locals.oauth.token.user
191 const abuse = res.locals.abuse
193 if (user.hasRight(UserRight.MANAGE_ABUSES) !== true && abuse.reporterAccountId !== user.Account.id) {
194 const message = `User ${user.username} does not have right to get abuse ${abuse.id}`
197 return res.status(403).json({ error: message })
204 const checkAbuseValidForMessagesValidator = [
205 (req: express.Request, res: express.Response, next: express.NextFunction) => {
206 logger.debug('Checking checkAbuseValidForMessagesValidator parameters', { parameters: req.body })
208 const abuse = res.locals.abuse
209 if (abuse.ReporterAccount.isOwned() === false) {
210 return res.status(400).json({
211 error: 'This abuse was created by a user of your instance.'
219 const addAbuseMessageValidator = [
220 body('message').custom(isAbuseMessageValid).not().isEmpty().withMessage('Should have a valid abuse message'),
222 (req: express.Request, res: express.Response, next: express.NextFunction) => {
223 logger.debug('Checking addAbuseMessageValidator parameters', { parameters: req.body })
225 if (areValidationErrors(req, res)) return
231 const deleteAbuseMessageValidator = [
232 param('messageId').custom(isIdValid).not().isEmpty().withMessage('Should have a valid message id'),
234 async (req: express.Request, res: express.Response, next: express.NextFunction) => {
235 logger.debug('Checking deleteAbuseMessageValidator parameters', { parameters: req.body })
237 if (areValidationErrors(req, res)) return
239 const user = res.locals.oauth.token.user
240 const abuse = res.locals.abuse
242 const messageId = parseInt(req.params.messageId + '', 10)
243 const abuseMessage = await AbuseMessageModel.loadByIdAndAbuseId(messageId, abuse.id)
246 return res.status(404).json({ error: 'Abuse message not found' })
249 if (user.hasRight(UserRight.MANAGE_ABUSES) !== true && abuseMessage.accountId !== user.Account.id) {
250 return res.status(403).json({ error: 'Cannot delete this abuse message' })
253 res.locals.abuseMessage = abuseMessage
259 // FIXME: deprecated in 2.3. Remove these validators
261 const videoAbuseReportValidator = [
263 .custom(isIdOrUUIDValid)
266 .withMessage('Should have a valid videoId'),
268 .custom(isAbuseReasonValid)
269 .withMessage('Should have a valid reason'),
270 body('predefinedReasons')
272 .custom(areAbusePredefinedReasonsValid)
273 .withMessage('Should have a valid list of predefined reasons'),
276 .customSanitizer(toIntOrNull)
277 .custom(isAbuseTimestampValid)
278 .withMessage('Should have valid starting time value'),
281 .customSanitizer(toIntOrNull)
282 .custom(isAbuseTimestampValid)
283 .withMessage('Should have valid ending time value'),
285 async (req: express.Request, res: express.Response, next: express.NextFunction) => {
286 logger.debug('Checking videoAbuseReport parameters', { parameters: req.body })
288 if (areValidationErrors(req, res)) return
289 if (!await doesVideoExist(req.params.videoId, res)) return
295 const videoAbuseGetValidator = [
296 param('videoId').custom(isIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid videoId'),
297 param('id').custom(isIdValid).not().isEmpty().withMessage('Should have a valid id'),
299 async (req: express.Request, res: express.Response, next: express.NextFunction) => {
300 logger.debug('Checking videoAbuseGetValidator parameters', { parameters: req.body })
302 if (areValidationErrors(req, res)) return
303 if (!await doesVideoAbuseExist(req.params.id, req.params.videoId, res)) return
309 const videoAbuseUpdateValidator = [
310 param('videoId').custom(isIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid videoId'),
311 param('id').custom(isIdValid).not().isEmpty().withMessage('Should have a valid id'),
314 .custom(isAbuseStateValid).withMessage('Should have a valid video abuse state'),
315 body('moderationComment')
317 .custom(isAbuseModerationCommentValid).withMessage('Should have a valid video moderation comment'),
319 async (req: express.Request, res: express.Response, next: express.NextFunction) => {
320 logger.debug('Checking videoAbuseUpdateValidator parameters', { parameters: req.body })
322 if (areValidationErrors(req, res)) return
323 if (!await doesVideoAbuseExist(req.params.id, req.params.videoId, res)) return
329 const videoAbuseListValidator = [
332 .custom(isIdValid).withMessage('Should have a valid id'),
333 query('predefinedReason')
335 .custom(isAbusePredefinedReasonValid)
336 .withMessage('Should have a valid predefinedReason'),
339 .custom(exists).withMessage('Should have a valid search'),
342 .custom(isAbuseStateValid).withMessage('Should have a valid video abuse state'),
345 .custom(isAbuseVideoIsValid).withMessage('Should have a valid "video is" attribute'),
346 query('searchReporter')
348 .custom(exists).withMessage('Should have a valid reporter search'),
349 query('searchReportee')
351 .custom(exists).withMessage('Should have a valid reportee search'),
354 .custom(exists).withMessage('Should have a valid video search'),
355 query('searchVideoChannel')
357 .custom(exists).withMessage('Should have a valid video channel search'),
359 (req: express.Request, res: express.Response, next: express.NextFunction) => {
360 logger.debug('Checking videoAbuseListValidator parameters', { parameters: req.body })
362 if (areValidationErrors(req, res)) return
368 // ---------------------------------------------------------------------------
371 abuseListForAdminsValidator,
372 abuseReportValidator,
374 addAbuseMessageValidator,
375 checkAbuseValidForMessagesValidator,
376 abuseUpdateValidator,
377 deleteAbuseMessageValidator,
378 abuseListForUserValidator,
380 videoAbuseReportValidator,
381 videoAbuseGetValidator,
382 videoAbuseUpdateValidator,
383 videoAbuseListValidator