]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blame - server/middlewares/validators/abuse.ts
Support short uuid for GET video/playlist
[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 {
7a4ea932 4 areAbusePredefinedReasonsValid,
57f6896f 5 isAbuseFilterValid,
edbc9325 6 isAbuseMessageValid,
d95d1559 7 isAbuseModerationCommentValid,
d95d1559
C
8 isAbusePredefinedReasonValid,
9 isAbuseReasonValid,
10 isAbuseStateValid,
11 isAbuseTimestampCoherent,
12 isAbuseTimestampValid,
13 isAbuseVideoIsValid
14} from '@server/helpers/custom-validators/abuses'
d4a8e7a6 15import { exists, isIdOrUUIDValid, isIdValid, toCompleteUUID, toIntOrNull } from '@server/helpers/custom-validators/misc'
d95d1559 16import { logger } from '@server/helpers/logger'
edbc9325
C
17import { AbuseMessageModel } from '@server/models/abuse/abuse-message'
18import { AbuseCreate, UserRight } from '@shared/models'
2d53be02 19import { HttpStatusCode } from '../../../shared/core-utils/miscs/http-error-codes'
10363c74 20import { areValidationErrors, doesAbuseExist, doesAccountIdExist, doesCommentIdExist, doesVideoExist } from './shared'
d95d1559
C
21
22const abuseReportValidator = [
57f6896f
C
23 body('account.id')
24 .optional()
25 .custom(isIdValid)
26 .withMessage('Should have a valid accountId'),
27
28 body('video.id')
29 .optional()
d4a8e7a6 30 .customSanitizer(toCompleteUUID)
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) {
76148b27 73 res.fail({ message: 'video id or account id or comment id is required.' })
57f6896f
C
74 return
75 }
d95d1559
C
76
77 return next()
78 }
79]
80
81const abuseGetValidator = [
d95d1559
C
82 param('id').custom(isIdValid).not().isEmpty().withMessage('Should have a valid id'),
83
84 async (req: express.Request, res: express.Response, next: express.NextFunction) => {
85 logger.debug('Checking abuseGetValidator parameters', { parameters: req.body })
86
87 if (areValidationErrors(req, res)) return
57f6896f 88 if (!await doesAbuseExist(req.params.id, res)) return
d95d1559
C
89
90 return next()
91 }
92]
93
94const abuseUpdateValidator = [
d95d1559 95 param('id').custom(isIdValid).not().isEmpty().withMessage('Should have a valid id'),
57f6896f 96
d95d1559
C
97 body('state')
98 .optional()
57f6896f 99 .custom(isAbuseStateValid).withMessage('Should have a valid abuse state'),
d95d1559
C
100 body('moderationComment')
101 .optional()
57f6896f 102 .custom(isAbuseModerationCommentValid).withMessage('Should have a valid moderation comment'),
d95d1559
C
103
104 async (req: express.Request, res: express.Response, next: express.NextFunction) => {
105 logger.debug('Checking abuseUpdateValidator parameters', { parameters: req.body })
106
107 if (areValidationErrors(req, res)) return
57f6896f 108 if (!await doesAbuseExist(req.params.id, res)) return
d95d1559
C
109
110 return next()
111 }
112]
113
edbc9325 114const abuseListForAdminsValidator = [
d95d1559
C
115 query('id')
116 .optional()
117 .custom(isIdValid).withMessage('Should have a valid id'),
57f6896f
C
118 query('filter')
119 .optional()
120 .custom(isAbuseFilterValid)
121 .withMessage('Should have a valid filter'),
d95d1559
C
122 query('predefinedReason')
123 .optional()
124 .custom(isAbusePredefinedReasonValid)
125 .withMessage('Should have a valid predefinedReason'),
126 query('search')
127 .optional()
128 .custom(exists).withMessage('Should have a valid search'),
129 query('state')
130 .optional()
310b5219 131 .custom(isAbuseStateValid).withMessage('Should have a valid abuse state'),
d95d1559
C
132 query('videoIs')
133 .optional()
134 .custom(isAbuseVideoIsValid).withMessage('Should have a valid "video is" attribute'),
135 query('searchReporter')
136 .optional()
137 .custom(exists).withMessage('Should have a valid reporter search'),
138 query('searchReportee')
139 .optional()
140 .custom(exists).withMessage('Should have a valid reportee search'),
141 query('searchVideo')
142 .optional()
143 .custom(exists).withMessage('Should have a valid video search'),
144 query('searchVideoChannel')
145 .optional()
146 .custom(exists).withMessage('Should have a valid video channel search'),
147
148 (req: express.Request, res: express.Response, next: express.NextFunction) => {
edbc9325 149 logger.debug('Checking abuseListForAdminsValidator parameters', { parameters: req.body })
d95d1559
C
150
151 if (areValidationErrors(req, res)) return
152
153 return next()
154 }
155]
156
edbc9325
C
157const abuseListForUserValidator = [
158 query('id')
159 .optional()
160 .custom(isIdValid).withMessage('Should have a valid id'),
161
162 query('search')
163 .optional()
164 .custom(exists).withMessage('Should have a valid search'),
165
166 query('state')
167 .optional()
168 .custom(isAbuseStateValid).withMessage('Should have a valid abuse state'),
169
170 (req: express.Request, res: express.Response, next: express.NextFunction) => {
171 logger.debug('Checking abuseListForUserValidator parameters', { parameters: req.body })
172
173 if (areValidationErrors(req, res)) return
174
175 return next()
176 }
177]
178
179const getAbuseValidator = [
180 param('id').custom(isIdValid).not().isEmpty().withMessage('Should have a valid id'),
181
182 async (req: express.Request, res: express.Response, next: express.NextFunction) => {
183 logger.debug('Checking getAbuseValidator parameters', { parameters: req.body })
184
185 if (areValidationErrors(req, res)) return
186 if (!await doesAbuseExist(req.params.id, res)) return
187
188 const user = res.locals.oauth.token.user
189 const abuse = res.locals.abuse
190
191 if (user.hasRight(UserRight.MANAGE_ABUSES) !== true && abuse.reporterAccountId !== user.Account.id) {
192 const message = `User ${user.username} does not have right to get abuse ${abuse.id}`
193 logger.warn(message)
194
76148b27
RK
195 return res.fail({
196 status: HttpStatusCode.FORBIDDEN_403,
197 message
198 })
edbc9325
C
199 }
200
201 return next()
202 }
203]
204
94148c90
C
205const checkAbuseValidForMessagesValidator = [
206 (req: express.Request, res: express.Response, next: express.NextFunction) => {
207 logger.debug('Checking checkAbuseValidForMessagesValidator parameters', { parameters: req.body })
208
209 const abuse = res.locals.abuse
210 if (abuse.ReporterAccount.isOwned() === false) {
76148b27 211 return res.fail({ message: 'This abuse was created by a user of your instance.' })
94148c90
C
212 }
213
214 return next()
215 }
216]
217
edbc9325
C
218const addAbuseMessageValidator = [
219 body('message').custom(isAbuseMessageValid).not().isEmpty().withMessage('Should have a valid abuse message'),
220
221 (req: express.Request, res: express.Response, next: express.NextFunction) => {
222 logger.debug('Checking addAbuseMessageValidator parameters', { parameters: req.body })
223
224 if (areValidationErrors(req, res)) return
225
226 return next()
227 }
228]
229
230const deleteAbuseMessageValidator = [
231 param('messageId').custom(isIdValid).not().isEmpty().withMessage('Should have a valid message id'),
232
233 async (req: express.Request, res: express.Response, next: express.NextFunction) => {
234 logger.debug('Checking deleteAbuseMessageValidator parameters', { parameters: req.body })
235
236 if (areValidationErrors(req, res)) return
237
238 const user = res.locals.oauth.token.user
239 const abuse = res.locals.abuse
240
241 const messageId = parseInt(req.params.messageId + '', 10)
242 const abuseMessage = await AbuseMessageModel.loadByIdAndAbuseId(messageId, abuse.id)
243
244 if (!abuseMessage) {
76148b27
RK
245 return res.fail({
246 status: HttpStatusCode.NOT_FOUND_404,
247 message: 'Abuse message not found'
248 })
edbc9325
C
249 }
250
251 if (user.hasRight(UserRight.MANAGE_ABUSES) !== true && abuseMessage.accountId !== user.Account.id) {
76148b27
RK
252 return res.fail({
253 status: HttpStatusCode.FORBIDDEN_403,
254 message: 'Cannot delete this abuse message'
255 })
edbc9325
C
256 }
257
258 res.locals.abuseMessage = abuseMessage
259
260 return next()
261 }
262]
263
d95d1559
C
264// ---------------------------------------------------------------------------
265
266export {
edbc9325 267 abuseListForAdminsValidator,
d95d1559
C
268 abuseReportValidator,
269 abuseGetValidator,
edbc9325 270 addAbuseMessageValidator,
94148c90 271 checkAbuseValidForMessagesValidator,
d95d1559 272 abuseUpdateValidator,
edbc9325
C
273 deleteAbuseMessageValidator,
274 abuseListForUserValidator,
7a4ea932 275 getAbuseValidator
d95d1559 276}