]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blame - server/middlewares/validators/abuse.ts
Add openapi doc
[github/Chocobozzz/PeerTube.git] / server / middlewares / validators / abuse.ts
CommitLineData
d95d1559
C
1import * as express from 'express'
2import { body, param, query } from 'express-validator'
3import {
57f6896f 4 isAbuseFilterValid,
edbc9325 5 isAbuseMessageValid,
d95d1559 6 isAbuseModerationCommentValid,
edbc9325 7 areAbusePredefinedReasonsValid,
d95d1559
C
8 isAbusePredefinedReasonValid,
9 isAbuseReasonValid,
10 isAbuseStateValid,
11 isAbuseTimestampCoherent,
12 isAbuseTimestampValid,
13 isAbuseVideoIsValid
14} from '@server/helpers/custom-validators/abuses'
15import { exists, isIdOrUUIDValid, isIdValid, toIntOrNull } from '@server/helpers/custom-validators/misc'
57f6896f 16import { doesCommentIdExist } from '@server/helpers/custom-validators/video-comments'
d95d1559 17import { logger } from '@server/helpers/logger'
57f6896f 18import { doesAbuseExist, doesAccountIdExist, doesVideoAbuseExist, doesVideoExist } from '@server/helpers/middlewares'
edbc9325
C
19import { AbuseMessageModel } from '@server/models/abuse/abuse-message'
20import { AbuseCreate, UserRight } from '@shared/models'
d95d1559
C
21import { areValidationErrors } from './utils'
22
23const abuseReportValidator = [
57f6896f
C
24 body('account.id')
25 .optional()
26 .custom(isIdValid)
27 .withMessage('Should have a valid accountId'),
28
29 body('video.id')
30 .optional()
d95d1559 31 .custom(isIdOrUUIDValid)
d95d1559 32 .withMessage('Should have a valid videoId'),
57f6896f 33 body('video.startAt')
d95d1559
C
34 .optional()
35 .customSanitizer(toIntOrNull)
36 .custom(isAbuseTimestampValid)
37 .withMessage('Should have valid starting time value'),
57f6896f 38 body('video.endAt')
d95d1559
C
39 .optional()
40 .customSanitizer(toIntOrNull)
41 .custom(isAbuseTimestampValid)
42 .withMessage('Should have valid ending time value')
43 .bail()
44 .custom(isAbuseTimestampCoherent)
45 .withMessage('Should have a startAt timestamp beginning before endAt'),
46
57f6896f
C
47 body('comment.id')
48 .optional()
49 .custom(isIdValid)
50 .withMessage('Should have a valid commentId'),
51
52 body('reason')
53 .custom(isAbuseReasonValid)
54 .withMessage('Should have a valid reason'),
55
56 body('predefinedReasons')
57 .optional()
edbc9325 58 .custom(areAbusePredefinedReasonsValid)
57f6896f
C
59 .withMessage('Should have a valid list of predefined reasons'),
60
d95d1559
C
61 async (req: express.Request, res: express.Response, next: express.NextFunction) => {
62 logger.debug('Checking abuseReport parameters', { parameters: req.body })
63
64 if (areValidationErrors(req, res)) return
d95d1559 65
57f6896f
C
66 const body: AbuseCreate = req.body
67
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
71
72 if (!body.video?.id && !body.account?.id && !body.comment?.id) {
73 res.status(400)
74 .json({ error: 'video id or account id or comment id is required.' })
75
76 return
77 }
d95d1559
C
78
79 return next()
80 }
81]
82
83const abuseGetValidator = [
d95d1559
C
84 param('id').custom(isIdValid).not().isEmpty().withMessage('Should have a valid id'),
85
86 async (req: express.Request, res: express.Response, next: express.NextFunction) => {
87 logger.debug('Checking abuseGetValidator parameters', { parameters: req.body })
88
89 if (areValidationErrors(req, res)) return
57f6896f 90 if (!await doesAbuseExist(req.params.id, res)) return
d95d1559
C
91
92 return next()
93 }
94]
95
96const abuseUpdateValidator = [
d95d1559 97 param('id').custom(isIdValid).not().isEmpty().withMessage('Should have a valid id'),
57f6896f 98
d95d1559
C
99 body('state')
100 .optional()
57f6896f 101 .custom(isAbuseStateValid).withMessage('Should have a valid abuse state'),
d95d1559
C
102 body('moderationComment')
103 .optional()
57f6896f 104 .custom(isAbuseModerationCommentValid).withMessage('Should have a valid moderation comment'),
d95d1559
C
105
106 async (req: express.Request, res: express.Response, next: express.NextFunction) => {
107 logger.debug('Checking abuseUpdateValidator parameters', { parameters: req.body })
108
109 if (areValidationErrors(req, res)) return
57f6896f 110 if (!await doesAbuseExist(req.params.id, res)) return
d95d1559
C
111
112 return next()
113 }
114]
115
edbc9325 116const abuseListForAdminsValidator = [
d95d1559
C
117 query('id')
118 .optional()
119 .custom(isIdValid).withMessage('Should have a valid id'),
57f6896f
C
120 query('filter')
121 .optional()
122 .custom(isAbuseFilterValid)
123 .withMessage('Should have a valid filter'),
d95d1559
C
124 query('predefinedReason')
125 .optional()
126 .custom(isAbusePredefinedReasonValid)
127 .withMessage('Should have a valid predefinedReason'),
128 query('search')
129 .optional()
130 .custom(exists).withMessage('Should have a valid search'),
131 query('state')
132 .optional()
310b5219 133 .custom(isAbuseStateValid).withMessage('Should have a valid abuse state'),
d95d1559
C
134 query('videoIs')
135 .optional()
136 .custom(isAbuseVideoIsValid).withMessage('Should have a valid "video is" attribute'),
137 query('searchReporter')
138 .optional()
139 .custom(exists).withMessage('Should have a valid reporter search'),
140 query('searchReportee')
141 .optional()
142 .custom(exists).withMessage('Should have a valid reportee search'),
143 query('searchVideo')
144 .optional()
145 .custom(exists).withMessage('Should have a valid video search'),
146 query('searchVideoChannel')
147 .optional()
148 .custom(exists).withMessage('Should have a valid video channel search'),
149
150 (req: express.Request, res: express.Response, next: express.NextFunction) => {
edbc9325 151 logger.debug('Checking abuseListForAdminsValidator parameters', { parameters: req.body })
d95d1559
C
152
153 if (areValidationErrors(req, res)) return
154
155 return next()
156 }
157]
158
edbc9325
C
159const abuseListForUserValidator = [
160 query('id')
161 .optional()
162 .custom(isIdValid).withMessage('Should have a valid id'),
163
164 query('search')
165 .optional()
166 .custom(exists).withMessage('Should have a valid search'),
167
168 query('state')
169 .optional()
170 .custom(isAbuseStateValid).withMessage('Should have a valid abuse state'),
171
172 (req: express.Request, res: express.Response, next: express.NextFunction) => {
173 logger.debug('Checking abuseListForUserValidator parameters', { parameters: req.body })
174
175 if (areValidationErrors(req, res)) return
176
177 return next()
178 }
179]
180
181const getAbuseValidator = [
182 param('id').custom(isIdValid).not().isEmpty().withMessage('Should have a valid id'),
183
184 async (req: express.Request, res: express.Response, next: express.NextFunction) => {
185 logger.debug('Checking getAbuseValidator parameters', { parameters: req.body })
186
187 if (areValidationErrors(req, res)) return
188 if (!await doesAbuseExist(req.params.id, res)) return
189
190 const user = res.locals.oauth.token.user
191 const abuse = res.locals.abuse
192
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}`
195 logger.warn(message)
196
197 return res.status(403).json({ error: message })
198 }
199
200 return next()
201 }
202]
203
94148c90
C
204const checkAbuseValidForMessagesValidator = [
205 (req: express.Request, res: express.Response, next: express.NextFunction) => {
206 logger.debug('Checking checkAbuseValidForMessagesValidator parameters', { parameters: req.body })
207
208 const abuse = res.locals.abuse
209 if (abuse.ReporterAccount.isOwned() === false) {
210 return res.status(400).json({
668b7f09 211 error: 'This abuse was created by a user of your instance.'
94148c90
C
212 })
213 }
214
215 return next()
216 }
217]
218
edbc9325
C
219const addAbuseMessageValidator = [
220 body('message').custom(isAbuseMessageValid).not().isEmpty().withMessage('Should have a valid abuse message'),
221
222 (req: express.Request, res: express.Response, next: express.NextFunction) => {
223 logger.debug('Checking addAbuseMessageValidator parameters', { parameters: req.body })
224
225 if (areValidationErrors(req, res)) return
226
227 return next()
228 }
229]
230
231const deleteAbuseMessageValidator = [
232 param('messageId').custom(isIdValid).not().isEmpty().withMessage('Should have a valid message id'),
233
234 async (req: express.Request, res: express.Response, next: express.NextFunction) => {
235 logger.debug('Checking deleteAbuseMessageValidator parameters', { parameters: req.body })
236
237 if (areValidationErrors(req, res)) return
238
239 const user = res.locals.oauth.token.user
240 const abuse = res.locals.abuse
241
242 const messageId = parseInt(req.params.messageId + '', 10)
243 const abuseMessage = await AbuseMessageModel.loadByIdAndAbuseId(messageId, abuse.id)
244
245 if (!abuseMessage) {
246 return res.status(404).json({ error: 'Abuse message not found' })
247 }
248
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' })
251 }
252
253 res.locals.abuseMessage = abuseMessage
254
255 return next()
256 }
257]
258
d95d1559
C
259// FIXME: deprecated in 2.3. Remove these validators
260
261const videoAbuseReportValidator = [
262 param('videoId')
263 .custom(isIdOrUUIDValid)
264 .not()
265 .isEmpty()
266 .withMessage('Should have a valid videoId'),
267 body('reason')
268 .custom(isAbuseReasonValid)
269 .withMessage('Should have a valid reason'),
270 body('predefinedReasons')
271 .optional()
edbc9325 272 .custom(areAbusePredefinedReasonsValid)
d95d1559
C
273 .withMessage('Should have a valid list of predefined reasons'),
274 body('startAt')
275 .optional()
276 .customSanitizer(toIntOrNull)
277 .custom(isAbuseTimestampValid)
278 .withMessage('Should have valid starting time value'),
279 body('endAt')
280 .optional()
281 .customSanitizer(toIntOrNull)
282 .custom(isAbuseTimestampValid)
57f6896f 283 .withMessage('Should have valid ending time value'),
d95d1559
C
284
285 async (req: express.Request, res: express.Response, next: express.NextFunction) => {
286 logger.debug('Checking videoAbuseReport parameters', { parameters: req.body })
287
288 if (areValidationErrors(req, res)) return
289 if (!await doesVideoExist(req.params.videoId, res)) return
290
291 return next()
292 }
293]
294
295const 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'),
298
299 async (req: express.Request, res: express.Response, next: express.NextFunction) => {
300 logger.debug('Checking videoAbuseGetValidator parameters', { parameters: req.body })
301
302 if (areValidationErrors(req, res)) return
303 if (!await doesVideoAbuseExist(req.params.id, req.params.videoId, res)) return
304
305 return next()
306 }
307]
308
309const 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'),
312 body('state')
313 .optional()
314 .custom(isAbuseStateValid).withMessage('Should have a valid video abuse state'),
315 body('moderationComment')
316 .optional()
317 .custom(isAbuseModerationCommentValid).withMessage('Should have a valid video moderation comment'),
318
319 async (req: express.Request, res: express.Response, next: express.NextFunction) => {
320 logger.debug('Checking videoAbuseUpdateValidator parameters', { parameters: req.body })
321
322 if (areValidationErrors(req, res)) return
323 if (!await doesVideoAbuseExist(req.params.id, req.params.videoId, res)) return
324
325 return next()
326 }
327]
328
329const videoAbuseListValidator = [
330 query('id')
331 .optional()
332 .custom(isIdValid).withMessage('Should have a valid id'),
333 query('predefinedReason')
334 .optional()
335 .custom(isAbusePredefinedReasonValid)
336 .withMessage('Should have a valid predefinedReason'),
337 query('search')
338 .optional()
339 .custom(exists).withMessage('Should have a valid search'),
340 query('state')
341 .optional()
342 .custom(isAbuseStateValid).withMessage('Should have a valid video abuse state'),
343 query('videoIs')
344 .optional()
345 .custom(isAbuseVideoIsValid).withMessage('Should have a valid "video is" attribute'),
346 query('searchReporter')
347 .optional()
348 .custom(exists).withMessage('Should have a valid reporter search'),
349 query('searchReportee')
350 .optional()
351 .custom(exists).withMessage('Should have a valid reportee search'),
352 query('searchVideo')
353 .optional()
354 .custom(exists).withMessage('Should have a valid video search'),
355 query('searchVideoChannel')
356 .optional()
357 .custom(exists).withMessage('Should have a valid video channel search'),
358
359 (req: express.Request, res: express.Response, next: express.NextFunction) => {
360 logger.debug('Checking videoAbuseListValidator parameters', { parameters: req.body })
361
362 if (areValidationErrors(req, res)) return
363
364 return next()
365 }
366]
367
368// ---------------------------------------------------------------------------
369
370export {
edbc9325 371 abuseListForAdminsValidator,
d95d1559
C
372 abuseReportValidator,
373 abuseGetValidator,
edbc9325 374 addAbuseMessageValidator,
94148c90 375 checkAbuseValidForMessagesValidator,
d95d1559 376 abuseUpdateValidator,
edbc9325
C
377 deleteAbuseMessageValidator,
378 abuseListForUserValidator,
379 getAbuseValidator,
d95d1559
C
380 videoAbuseReportValidator,
381 videoAbuseGetValidator,
382 videoAbuseUpdateValidator,
383 videoAbuseListValidator
384}