1 import * as express from 'express'
2 import { body, param, query } from 'express-validator'
4 areAbusePredefinedReasonsValid,
7 isAbuseModerationCommentValid,
8 isAbusePredefinedReasonValid,
11 isAbuseTimestampCoherent,
12 isAbuseTimestampValid,
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 import { HttpStatusCode } from '../../../shared/core-utils/miscs/http-error-codes'
24 const abuseReportValidator = [
28 .withMessage('Should have a valid accountId'),
32 .custom(isIdOrUUIDValid)
33 .withMessage('Should have a valid videoId'),
36 .customSanitizer(toIntOrNull)
37 .custom(isAbuseTimestampValid)
38 .withMessage('Should have valid starting time value'),
41 .customSanitizer(toIntOrNull)
42 .custom(isAbuseTimestampValid)
43 .withMessage('Should have valid ending time value')
45 .custom(isAbuseTimestampCoherent)
46 .withMessage('Should have a startAt timestamp beginning before endAt'),
51 .withMessage('Should have a valid commentId'),
54 .custom(isAbuseReasonValid)
55 .withMessage('Should have a valid reason'),
57 body('predefinedReasons')
59 .custom(areAbusePredefinedReasonsValid)
60 .withMessage('Should have a valid list of predefined reasons'),
62 async (req: express.Request, res: express.Response, next: express.NextFunction) => {
63 logger.debug('Checking abuseReport parameters', { parameters: req.body })
65 if (areValidationErrors(req, res)) return
67 const body: AbuseCreate = req.body
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
73 if (!body.video?.id && !body.account?.id && !body.comment?.id) {
74 res.status(HttpStatusCode.BAD_REQUEST_400)
75 .json({ error: 'video id or account id or comment id is required.' })
84 const abuseGetValidator = [
85 param('id').custom(isIdValid).not().isEmpty().withMessage('Should have a valid id'),
87 async (req: express.Request, res: express.Response, next: express.NextFunction) => {
88 logger.debug('Checking abuseGetValidator parameters', { parameters: req.body })
90 if (areValidationErrors(req, res)) return
91 if (!await doesAbuseExist(req.params.id, res)) return
97 const abuseUpdateValidator = [
98 param('id').custom(isIdValid).not().isEmpty().withMessage('Should have a valid id'),
102 .custom(isAbuseStateValid).withMessage('Should have a valid abuse state'),
103 body('moderationComment')
105 .custom(isAbuseModerationCommentValid).withMessage('Should have a valid moderation comment'),
107 async (req: express.Request, res: express.Response, next: express.NextFunction) => {
108 logger.debug('Checking abuseUpdateValidator parameters', { parameters: req.body })
110 if (areValidationErrors(req, res)) return
111 if (!await doesAbuseExist(req.params.id, res)) return
117 const abuseListForAdminsValidator = [
120 .custom(isIdValid).withMessage('Should have a valid id'),
123 .custom(isAbuseFilterValid)
124 .withMessage('Should have a valid filter'),
125 query('predefinedReason')
127 .custom(isAbusePredefinedReasonValid)
128 .withMessage('Should have a valid predefinedReason'),
131 .custom(exists).withMessage('Should have a valid search'),
134 .custom(isAbuseStateValid).withMessage('Should have a valid abuse state'),
137 .custom(isAbuseVideoIsValid).withMessage('Should have a valid "video is" attribute'),
138 query('searchReporter')
140 .custom(exists).withMessage('Should have a valid reporter search'),
141 query('searchReportee')
143 .custom(exists).withMessage('Should have a valid reportee search'),
146 .custom(exists).withMessage('Should have a valid video search'),
147 query('searchVideoChannel')
149 .custom(exists).withMessage('Should have a valid video channel search'),
151 (req: express.Request, res: express.Response, next: express.NextFunction) => {
152 logger.debug('Checking abuseListForAdminsValidator parameters', { parameters: req.body })
154 if (areValidationErrors(req, res)) return
160 const abuseListForUserValidator = [
163 .custom(isIdValid).withMessage('Should have a valid id'),
167 .custom(exists).withMessage('Should have a valid search'),
171 .custom(isAbuseStateValid).withMessage('Should have a valid abuse state'),
173 (req: express.Request, res: express.Response, next: express.NextFunction) => {
174 logger.debug('Checking abuseListForUserValidator parameters', { parameters: req.body })
176 if (areValidationErrors(req, res)) return
182 const getAbuseValidator = [
183 param('id').custom(isIdValid).not().isEmpty().withMessage('Should have a valid id'),
185 async (req: express.Request, res: express.Response, next: express.NextFunction) => {
186 logger.debug('Checking getAbuseValidator parameters', { parameters: req.body })
188 if (areValidationErrors(req, res)) return
189 if (!await doesAbuseExist(req.params.id, res)) return
191 const user = res.locals.oauth.token.user
192 const abuse = res.locals.abuse
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}`
198 return res.status(HttpStatusCode.FORBIDDEN_403)
199 .json({ error: message })
206 const checkAbuseValidForMessagesValidator = [
207 (req: express.Request, res: express.Response, next: express.NextFunction) => {
208 logger.debug('Checking checkAbuseValidForMessagesValidator parameters', { parameters: req.body })
210 const abuse = res.locals.abuse
211 if (abuse.ReporterAccount.isOwned() === false) {
212 return res.status(HttpStatusCode.BAD_REQUEST_400)
214 error: 'This abuse was created by a user of your instance.'
222 const addAbuseMessageValidator = [
223 body('message').custom(isAbuseMessageValid).not().isEmpty().withMessage('Should have a valid abuse message'),
225 (req: express.Request, res: express.Response, next: express.NextFunction) => {
226 logger.debug('Checking addAbuseMessageValidator parameters', { parameters: req.body })
228 if (areValidationErrors(req, res)) return
234 const deleteAbuseMessageValidator = [
235 param('messageId').custom(isIdValid).not().isEmpty().withMessage('Should have a valid message id'),
237 async (req: express.Request, res: express.Response, next: express.NextFunction) => {
238 logger.debug('Checking deleteAbuseMessageValidator parameters', { parameters: req.body })
240 if (areValidationErrors(req, res)) return
242 const user = res.locals.oauth.token.user
243 const abuse = res.locals.abuse
245 const messageId = parseInt(req.params.messageId + '', 10)
246 const abuseMessage = await AbuseMessageModel.loadByIdAndAbuseId(messageId, abuse.id)
249 return res.status(HttpStatusCode.NOT_FOUND_404)
250 .json({ error: 'Abuse message not found' })
253 if (user.hasRight(UserRight.MANAGE_ABUSES) !== true && abuseMessage.accountId !== user.Account.id) {
254 return res.status(HttpStatusCode.FORBIDDEN_403)
255 .json({ error: 'Cannot delete this abuse message' })
258 res.locals.abuseMessage = abuseMessage
264 // ---------------------------------------------------------------------------
267 abuseListForAdminsValidator,
268 abuseReportValidator,
270 addAbuseMessageValidator,
271 checkAbuseValidForMessagesValidator,
272 abuseUpdateValidator,
273 deleteAbuseMessageValidator,
274 abuseListForUserValidator,