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 { logger } from '@server/helpers/logger'
17 import { AbuseMessageModel } from '@server/models/abuse/abuse-message'
18 import { AbuseCreate, UserRight } from '@shared/models'
19 import { HttpStatusCode } from '../../../shared/core-utils/miscs/http-error-codes'
20 import { areValidationErrors, doesAbuseExist, doesAccountIdExist, doesCommentIdExist, doesVideoExist } from './shared'
22 const abuseReportValidator = [
26 .withMessage('Should have a valid accountId'),
30 .custom(isIdOrUUIDValid)
31 .withMessage('Should have a valid videoId'),
34 .customSanitizer(toIntOrNull)
35 .custom(isAbuseTimestampValid)
36 .withMessage('Should have valid starting time value'),
39 .customSanitizer(toIntOrNull)
40 .custom(isAbuseTimestampValid)
41 .withMessage('Should have valid ending time value')
43 .custom(isAbuseTimestampCoherent)
44 .withMessage('Should have a startAt timestamp beginning before endAt'),
49 .withMessage('Should have a valid commentId'),
52 .custom(isAbuseReasonValid)
53 .withMessage('Should have a valid reason'),
55 body('predefinedReasons')
57 .custom(areAbusePredefinedReasonsValid)
58 .withMessage('Should have a valid list of predefined reasons'),
60 async (req: express.Request, res: express.Response, next: express.NextFunction) => {
61 logger.debug('Checking abuseReport parameters', { parameters: req.body })
63 if (areValidationErrors(req, res)) return
65 const body: AbuseCreate = req.body
67 if (body.video?.id && !await doesVideoExist(body.video.id, res)) return
68 if (body.account?.id && !await doesAccountIdExist(body.account.id, res)) return
69 if (body.comment?.id && !await doesCommentIdExist(body.comment.id, res)) return
71 if (!body.video?.id && !body.account?.id && !body.comment?.id) {
72 res.fail({ message: 'video id or account id or comment id is required.' })
80 const abuseGetValidator = [
81 param('id').custom(isIdValid).not().isEmpty().withMessage('Should have a valid id'),
83 async (req: express.Request, res: express.Response, next: express.NextFunction) => {
84 logger.debug('Checking abuseGetValidator parameters', { parameters: req.body })
86 if (areValidationErrors(req, res)) return
87 if (!await doesAbuseExist(req.params.id, res)) return
93 const abuseUpdateValidator = [
94 param('id').custom(isIdValid).not().isEmpty().withMessage('Should have a valid id'),
98 .custom(isAbuseStateValid).withMessage('Should have a valid abuse state'),
99 body('moderationComment')
101 .custom(isAbuseModerationCommentValid).withMessage('Should have a valid moderation comment'),
103 async (req: express.Request, res: express.Response, next: express.NextFunction) => {
104 logger.debug('Checking abuseUpdateValidator parameters', { parameters: req.body })
106 if (areValidationErrors(req, res)) return
107 if (!await doesAbuseExist(req.params.id, res)) return
113 const abuseListForAdminsValidator = [
116 .custom(isIdValid).withMessage('Should have a valid id'),
119 .custom(isAbuseFilterValid)
120 .withMessage('Should have a valid filter'),
121 query('predefinedReason')
123 .custom(isAbusePredefinedReasonValid)
124 .withMessage('Should have a valid predefinedReason'),
127 .custom(exists).withMessage('Should have a valid search'),
130 .custom(isAbuseStateValid).withMessage('Should have a valid abuse state'),
133 .custom(isAbuseVideoIsValid).withMessage('Should have a valid "video is" attribute'),
134 query('searchReporter')
136 .custom(exists).withMessage('Should have a valid reporter search'),
137 query('searchReportee')
139 .custom(exists).withMessage('Should have a valid reportee search'),
142 .custom(exists).withMessage('Should have a valid video search'),
143 query('searchVideoChannel')
145 .custom(exists).withMessage('Should have a valid video channel search'),
147 (req: express.Request, res: express.Response, next: express.NextFunction) => {
148 logger.debug('Checking abuseListForAdminsValidator parameters', { parameters: req.body })
150 if (areValidationErrors(req, res)) return
156 const abuseListForUserValidator = [
159 .custom(isIdValid).withMessage('Should have a valid id'),
163 .custom(exists).withMessage('Should have a valid search'),
167 .custom(isAbuseStateValid).withMessage('Should have a valid abuse state'),
169 (req: express.Request, res: express.Response, next: express.NextFunction) => {
170 logger.debug('Checking abuseListForUserValidator parameters', { parameters: req.body })
172 if (areValidationErrors(req, res)) return
178 const getAbuseValidator = [
179 param('id').custom(isIdValid).not().isEmpty().withMessage('Should have a valid id'),
181 async (req: express.Request, res: express.Response, next: express.NextFunction) => {
182 logger.debug('Checking getAbuseValidator parameters', { parameters: req.body })
184 if (areValidationErrors(req, res)) return
185 if (!await doesAbuseExist(req.params.id, res)) return
187 const user = res.locals.oauth.token.user
188 const abuse = res.locals.abuse
190 if (user.hasRight(UserRight.MANAGE_ABUSES) !== true && abuse.reporterAccountId !== user.Account.id) {
191 const message = `User ${user.username} does not have right to get abuse ${abuse.id}`
195 status: HttpStatusCode.FORBIDDEN_403,
204 const checkAbuseValidForMessagesValidator = [
205 (req: express.Request, res: express.Response, next: express.NextFunction) => {
206 logger.debug('Checking checkAbuseValidForMessagesValidator parameters', { parameters: req.body })
208 const abuse = res.locals.abuse
209 if (abuse.ReporterAccount.isOwned() === false) {
210 return res.fail({ message: 'This abuse was created by a user of your instance.' })
217 const addAbuseMessageValidator = [
218 body('message').custom(isAbuseMessageValid).not().isEmpty().withMessage('Should have a valid abuse message'),
220 (req: express.Request, res: express.Response, next: express.NextFunction) => {
221 logger.debug('Checking addAbuseMessageValidator parameters', { parameters: req.body })
223 if (areValidationErrors(req, res)) return
229 const deleteAbuseMessageValidator = [
230 param('messageId').custom(isIdValid).not().isEmpty().withMessage('Should have a valid message id'),
232 async (req: express.Request, res: express.Response, next: express.NextFunction) => {
233 logger.debug('Checking deleteAbuseMessageValidator parameters', { parameters: req.body })
235 if (areValidationErrors(req, res)) return
237 const user = res.locals.oauth.token.user
238 const abuse = res.locals.abuse
240 const messageId = parseInt(req.params.messageId + '', 10)
241 const abuseMessage = await AbuseMessageModel.loadByIdAndAbuseId(messageId, abuse.id)
245 status: HttpStatusCode.NOT_FOUND_404,
246 message: 'Abuse message not found'
250 if (user.hasRight(UserRight.MANAGE_ABUSES) !== true && abuseMessage.accountId !== user.Account.id) {
252 status: HttpStatusCode.FORBIDDEN_403,
253 message: 'Cannot delete this abuse message'
257 res.locals.abuseMessage = abuseMessage
263 // ---------------------------------------------------------------------------
266 abuseListForAdminsValidator,
267 abuseReportValidator,
269 addAbuseMessageValidator,
270 checkAbuseValidForMessagesValidator,
271 abuseUpdateValidator,
272 deleteAbuseMessageValidator,
273 abuseListForUserValidator,