]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blob - server/middlewares/validators/abuse.ts
Fix video tag validator
[github/Chocobozzz/PeerTube.git] / server / middlewares / validators / abuse.ts
1 import * as express from 'express'
2 import { body, param, query } from 'express-validator'
3 import {
4 areAbusePredefinedReasonsValid,
5 isAbuseFilterValid,
6 isAbuseMessageValid,
7 isAbuseModerationCommentValid,
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'
16 import { doesCommentIdExist } from '@server/helpers/custom-validators/video-comments'
17 import { logger } from '@server/helpers/logger'
18 import { doesAbuseExist, doesAccountIdExist, 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'
22
23 const abuseReportValidator = [
24 body('account.id')
25 .optional()
26 .custom(isIdValid)
27 .withMessage('Should have a valid accountId'),
28
29 body('video.id')
30 .optional()
31 .custom(isIdOrUUIDValid)
32 .withMessage('Should have a valid videoId'),
33 body('video.startAt')
34 .optional()
35 .customSanitizer(toIntOrNull)
36 .custom(isAbuseTimestampValid)
37 .withMessage('Should have valid starting time value'),
38 body('video.endAt')
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
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()
58 .custom(areAbusePredefinedReasonsValid)
59 .withMessage('Should have a valid list of predefined reasons'),
60
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
65
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 }
78
79 return next()
80 }
81 ]
82
83 const abuseGetValidator = [
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
90 if (!await doesAbuseExist(req.params.id, res)) return
91
92 return next()
93 }
94 ]
95
96 const abuseUpdateValidator = [
97 param('id').custom(isIdValid).not().isEmpty().withMessage('Should have a valid id'),
98
99 body('state')
100 .optional()
101 .custom(isAbuseStateValid).withMessage('Should have a valid abuse state'),
102 body('moderationComment')
103 .optional()
104 .custom(isAbuseModerationCommentValid).withMessage('Should have a valid moderation comment'),
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
110 if (!await doesAbuseExist(req.params.id, res)) return
111
112 return next()
113 }
114 ]
115
116 const abuseListForAdminsValidator = [
117 query('id')
118 .optional()
119 .custom(isIdValid).withMessage('Should have a valid id'),
120 query('filter')
121 .optional()
122 .custom(isAbuseFilterValid)
123 .withMessage('Should have a valid filter'),
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()
133 .custom(isAbuseStateValid).withMessage('Should have a valid abuse state'),
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) => {
151 logger.debug('Checking abuseListForAdminsValidator parameters', { parameters: req.body })
152
153 if (areValidationErrors(req, res)) return
154
155 return next()
156 }
157 ]
158
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
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({
211 error: 'This abuse was created by a user of your instance.'
212 })
213 }
214
215 return next()
216 }
217 ]
218
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
259 // ---------------------------------------------------------------------------
260
261 export {
262 abuseListForAdminsValidator,
263 abuseReportValidator,
264 abuseGetValidator,
265 addAbuseMessageValidator,
266 checkAbuseValidForMessagesValidator,
267 abuseUpdateValidator,
268 deleteAbuseMessageValidator,
269 abuseListForUserValidator,
270 getAbuseValidator
271 }