]>
Commit | Line | Data |
---|---|---|
d95d1559 C |
1 | import * as express from 'express' |
2 | import { body, param, query } from 'express-validator' | |
3 | import { | |
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' | |
15 | import { exists, isIdOrUUIDValid, isIdValid, toIntOrNull } from '@server/helpers/custom-validators/misc' | |
57f6896f | 16 | import { doesCommentIdExist } from '@server/helpers/custom-validators/video-comments' |
d95d1559 | 17 | import { logger } from '@server/helpers/logger' |
57f6896f | 18 | import { doesAbuseExist, doesAccountIdExist, doesVideoAbuseExist, doesVideoExist } from '@server/helpers/middlewares' |
edbc9325 C |
19 | import { AbuseMessageModel } from '@server/models/abuse/abuse-message' |
20 | import { AbuseCreate, UserRight } from '@shared/models' | |
d95d1559 C |
21 | import { areValidationErrors } from './utils' |
22 | ||
23 | const 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 | ||
83 | const 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 | ||
96 | const 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 | 116 | const 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 |
159 | const 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 | ||
181 | const 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 |
204 | const 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 |
219 | const 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 | ||
231 | const 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 | ||
261 | const 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 | ||
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'), | |
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 | ||
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'), | |
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 | ||
329 | const 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 | ||
370 | export { | |
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 | } |