]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blame - server/middlewares/validators/abuse.ts
Merge branch 'release/3.2.0' into develop
[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'
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'
7a4ea932 18import { doesAbuseExist, doesAccountIdExist, doesVideoExist } from '@server/helpers/middlewares'
edbc9325
C
19import { AbuseMessageModel } from '@server/models/abuse/abuse-message'
20import { AbuseCreate, UserRight } from '@shared/models'
d95d1559 21import { areValidationErrors } from './utils'
2d53be02 22import { HttpStatusCode } from '../../../shared/core-utils/miscs/http-error-codes'
d95d1559
C
23
24const abuseReportValidator = [
57f6896f
C
25 body('account.id')
26 .optional()
27 .custom(isIdValid)
28 .withMessage('Should have a valid accountId'),
29
30 body('video.id')
31 .optional()
d95d1559 32 .custom(isIdOrUUIDValid)
d95d1559 33 .withMessage('Should have a valid videoId'),
57f6896f 34 body('video.startAt')
d95d1559
C
35 .optional()
36 .customSanitizer(toIntOrNull)
37 .custom(isAbuseTimestampValid)
38 .withMessage('Should have valid starting time value'),
57f6896f 39 body('video.endAt')
d95d1559
C
40 .optional()
41 .customSanitizer(toIntOrNull)
42 .custom(isAbuseTimestampValid)
43 .withMessage('Should have valid ending time value')
44 .bail()
45 .custom(isAbuseTimestampCoherent)
46 .withMessage('Should have a startAt timestamp beginning before endAt'),
47
57f6896f
C
48 body('comment.id')
49 .optional()
50 .custom(isIdValid)
51 .withMessage('Should have a valid commentId'),
52
53 body('reason')
54 .custom(isAbuseReasonValid)
55 .withMessage('Should have a valid reason'),
56
57 body('predefinedReasons')
58 .optional()
edbc9325 59 .custom(areAbusePredefinedReasonsValid)
57f6896f
C
60 .withMessage('Should have a valid list of predefined reasons'),
61
d95d1559
C
62 async (req: express.Request, res: express.Response, next: express.NextFunction) => {
63 logger.debug('Checking abuseReport parameters', { parameters: req.body })
64
65 if (areValidationErrors(req, res)) return
d95d1559 66
57f6896f
C
67 const body: AbuseCreate = req.body
68
69 if (body.video?.id && !await doesVideoExist(body.video.id, res)) return
70 if (body.account?.id && !await doesAccountIdExist(body.account.id, res)) return
71 if (body.comment?.id && !await doesCommentIdExist(body.comment.id, res)) return
72
73 if (!body.video?.id && !body.account?.id && !body.comment?.id) {
2d53be02
RK
74 res.status(HttpStatusCode.BAD_REQUEST_400)
75 .json({ error: 'video id or account id or comment id is required.' })
57f6896f
C
76
77 return
78 }
d95d1559
C
79
80 return next()
81 }
82]
83
84const abuseGetValidator = [
d95d1559
C
85 param('id').custom(isIdValid).not().isEmpty().withMessage('Should have a valid id'),
86
87 async (req: express.Request, res: express.Response, next: express.NextFunction) => {
88 logger.debug('Checking abuseGetValidator parameters', { parameters: req.body })
89
90 if (areValidationErrors(req, res)) return
57f6896f 91 if (!await doesAbuseExist(req.params.id, res)) return
d95d1559
C
92
93 return next()
94 }
95]
96
97const abuseUpdateValidator = [
d95d1559 98 param('id').custom(isIdValid).not().isEmpty().withMessage('Should have a valid id'),
57f6896f 99
d95d1559
C
100 body('state')
101 .optional()
57f6896f 102 .custom(isAbuseStateValid).withMessage('Should have a valid abuse state'),
d95d1559
C
103 body('moderationComment')
104 .optional()
57f6896f 105 .custom(isAbuseModerationCommentValid).withMessage('Should have a valid moderation comment'),
d95d1559
C
106
107 async (req: express.Request, res: express.Response, next: express.NextFunction) => {
108 logger.debug('Checking abuseUpdateValidator parameters', { parameters: req.body })
109
110 if (areValidationErrors(req, res)) return
57f6896f 111 if (!await doesAbuseExist(req.params.id, res)) return
d95d1559
C
112
113 return next()
114 }
115]
116
edbc9325 117const abuseListForAdminsValidator = [
d95d1559
C
118 query('id')
119 .optional()
120 .custom(isIdValid).withMessage('Should have a valid id'),
57f6896f
C
121 query('filter')
122 .optional()
123 .custom(isAbuseFilterValid)
124 .withMessage('Should have a valid filter'),
d95d1559
C
125 query('predefinedReason')
126 .optional()
127 .custom(isAbusePredefinedReasonValid)
128 .withMessage('Should have a valid predefinedReason'),
129 query('search')
130 .optional()
131 .custom(exists).withMessage('Should have a valid search'),
132 query('state')
133 .optional()
310b5219 134 .custom(isAbuseStateValid).withMessage('Should have a valid abuse state'),
d95d1559
C
135 query('videoIs')
136 .optional()
137 .custom(isAbuseVideoIsValid).withMessage('Should have a valid "video is" attribute'),
138 query('searchReporter')
139 .optional()
140 .custom(exists).withMessage('Should have a valid reporter search'),
141 query('searchReportee')
142 .optional()
143 .custom(exists).withMessage('Should have a valid reportee search'),
144 query('searchVideo')
145 .optional()
146 .custom(exists).withMessage('Should have a valid video search'),
147 query('searchVideoChannel')
148 .optional()
149 .custom(exists).withMessage('Should have a valid video channel search'),
150
151 (req: express.Request, res: express.Response, next: express.NextFunction) => {
edbc9325 152 logger.debug('Checking abuseListForAdminsValidator parameters', { parameters: req.body })
d95d1559
C
153
154 if (areValidationErrors(req, res)) return
155
156 return next()
157 }
158]
159
edbc9325
C
160const abuseListForUserValidator = [
161 query('id')
162 .optional()
163 .custom(isIdValid).withMessage('Should have a valid id'),
164
165 query('search')
166 .optional()
167 .custom(exists).withMessage('Should have a valid search'),
168
169 query('state')
170 .optional()
171 .custom(isAbuseStateValid).withMessage('Should have a valid abuse state'),
172
173 (req: express.Request, res: express.Response, next: express.NextFunction) => {
174 logger.debug('Checking abuseListForUserValidator parameters', { parameters: req.body })
175
176 if (areValidationErrors(req, res)) return
177
178 return next()
179 }
180]
181
182const getAbuseValidator = [
183 param('id').custom(isIdValid).not().isEmpty().withMessage('Should have a valid id'),
184
185 async (req: express.Request, res: express.Response, next: express.NextFunction) => {
186 logger.debug('Checking getAbuseValidator parameters', { parameters: req.body })
187
188 if (areValidationErrors(req, res)) return
189 if (!await doesAbuseExist(req.params.id, res)) return
190
191 const user = res.locals.oauth.token.user
192 const abuse = res.locals.abuse
193
194 if (user.hasRight(UserRight.MANAGE_ABUSES) !== true && abuse.reporterAccountId !== user.Account.id) {
195 const message = `User ${user.username} does not have right to get abuse ${abuse.id}`
196 logger.warn(message)
197
2d53be02
RK
198 return res.status(HttpStatusCode.FORBIDDEN_403)
199 .json({ error: message })
edbc9325
C
200 }
201
202 return next()
203 }
204]
205
94148c90
C
206const checkAbuseValidForMessagesValidator = [
207 (req: express.Request, res: express.Response, next: express.NextFunction) => {
208 logger.debug('Checking checkAbuseValidForMessagesValidator parameters', { parameters: req.body })
209
210 const abuse = res.locals.abuse
211 if (abuse.ReporterAccount.isOwned() === false) {
2d53be02
RK
212 return res.status(HttpStatusCode.BAD_REQUEST_400)
213 .json({
214 error: 'This abuse was created by a user of your instance.'
215 })
94148c90
C
216 }
217
218 return next()
219 }
220]
221
edbc9325
C
222const addAbuseMessageValidator = [
223 body('message').custom(isAbuseMessageValid).not().isEmpty().withMessage('Should have a valid abuse message'),
224
225 (req: express.Request, res: express.Response, next: express.NextFunction) => {
226 logger.debug('Checking addAbuseMessageValidator parameters', { parameters: req.body })
227
228 if (areValidationErrors(req, res)) return
229
230 return next()
231 }
232]
233
234const deleteAbuseMessageValidator = [
235 param('messageId').custom(isIdValid).not().isEmpty().withMessage('Should have a valid message id'),
236
237 async (req: express.Request, res: express.Response, next: express.NextFunction) => {
238 logger.debug('Checking deleteAbuseMessageValidator parameters', { parameters: req.body })
239
240 if (areValidationErrors(req, res)) return
241
242 const user = res.locals.oauth.token.user
243 const abuse = res.locals.abuse
244
245 const messageId = parseInt(req.params.messageId + '', 10)
246 const abuseMessage = await AbuseMessageModel.loadByIdAndAbuseId(messageId, abuse.id)
247
248 if (!abuseMessage) {
2d53be02
RK
249 return res.status(HttpStatusCode.NOT_FOUND_404)
250 .json({ error: 'Abuse message not found' })
edbc9325
C
251 }
252
253 if (user.hasRight(UserRight.MANAGE_ABUSES) !== true && abuseMessage.accountId !== user.Account.id) {
2d53be02
RK
254 return res.status(HttpStatusCode.FORBIDDEN_403)
255 .json({ error: 'Cannot delete this abuse message' })
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}