2020-07-01 16:05:30 +02:00
|
|
|
import * as express from 'express'
|
|
|
|
import { body, param, query } from 'express-validator'
|
|
|
|
import {
|
2020-11-10 14:41:20 +01:00
|
|
|
areAbusePredefinedReasonsValid,
|
2020-07-07 10:57:04 +02:00
|
|
|
isAbuseFilterValid,
|
2020-07-24 15:05:51 +02:00
|
|
|
isAbuseMessageValid,
|
2020-07-01 16:05:30 +02:00
|
|
|
isAbuseModerationCommentValid,
|
|
|
|
isAbusePredefinedReasonValid,
|
|
|
|
isAbuseReasonValid,
|
|
|
|
isAbuseStateValid,
|
|
|
|
isAbuseTimestampCoherent,
|
|
|
|
isAbuseTimestampValid,
|
|
|
|
isAbuseVideoIsValid
|
|
|
|
} from '@server/helpers/custom-validators/abuses'
|
2021-06-28 17:30:59 +02:00
|
|
|
import { exists, isIdOrUUIDValid, isIdValid, toCompleteUUID, toIntOrNull } from '@server/helpers/custom-validators/misc'
|
2020-07-01 16:05:30 +02:00
|
|
|
import { logger } from '@server/helpers/logger'
|
2020-07-24 15:05:51 +02:00
|
|
|
import { AbuseMessageModel } from '@server/models/abuse/abuse-message'
|
|
|
|
import { AbuseCreate, UserRight } from '@shared/models'
|
2021-07-16 10:42:24 +02:00
|
|
|
import { HttpStatusCode } from '../../../shared/models/http/http-error-codes'
|
2021-06-03 17:33:44 +02:00
|
|
|
import { areValidationErrors, doesAbuseExist, doesAccountIdExist, doesCommentIdExist, doesVideoExist } from './shared'
|
2020-07-01 16:05:30 +02:00
|
|
|
|
|
|
|
const abuseReportValidator = [
|
2020-07-07 10:57:04 +02:00
|
|
|
body('account.id')
|
|
|
|
.optional()
|
|
|
|
.custom(isIdValid)
|
|
|
|
.withMessage('Should have a valid accountId'),
|
|
|
|
|
|
|
|
body('video.id')
|
|
|
|
.optional()
|
2021-06-28 17:30:59 +02:00
|
|
|
.customSanitizer(toCompleteUUID)
|
2020-07-01 16:05:30 +02:00
|
|
|
.custom(isIdOrUUIDValid)
|
|
|
|
.withMessage('Should have a valid videoId'),
|
2020-07-07 10:57:04 +02:00
|
|
|
body('video.startAt')
|
2020-07-01 16:05:30 +02:00
|
|
|
.optional()
|
|
|
|
.customSanitizer(toIntOrNull)
|
|
|
|
.custom(isAbuseTimestampValid)
|
|
|
|
.withMessage('Should have valid starting time value'),
|
2020-07-07 10:57:04 +02:00
|
|
|
body('video.endAt')
|
2020-07-01 16:05:30 +02:00
|
|
|
.optional()
|
|
|
|
.customSanitizer(toIntOrNull)
|
|
|
|
.custom(isAbuseTimestampValid)
|
|
|
|
.withMessage('Should have valid ending time value')
|
|
|
|
.bail()
|
|
|
|
.custom(isAbuseTimestampCoherent)
|
|
|
|
.withMessage('Should have a startAt timestamp beginning before endAt'),
|
|
|
|
|
2020-07-07 10:57:04 +02:00
|
|
|
body('comment.id')
|
|
|
|
.optional()
|
|
|
|
.custom(isIdValid)
|
|
|
|
.withMessage('Should have a valid commentId'),
|
|
|
|
|
|
|
|
body('reason')
|
|
|
|
.custom(isAbuseReasonValid)
|
|
|
|
.withMessage('Should have a valid reason'),
|
|
|
|
|
|
|
|
body('predefinedReasons')
|
|
|
|
.optional()
|
2020-07-24 15:05:51 +02:00
|
|
|
.custom(areAbusePredefinedReasonsValid)
|
2020-07-07 10:57:04 +02:00
|
|
|
.withMessage('Should have a valid list of predefined reasons'),
|
|
|
|
|
2020-07-01 16:05:30 +02:00
|
|
|
async (req: express.Request, res: express.Response, next: express.NextFunction) => {
|
|
|
|
logger.debug('Checking abuseReport parameters', { parameters: req.body })
|
|
|
|
|
|
|
|
if (areValidationErrors(req, res)) return
|
|
|
|
|
2020-07-07 10:57:04 +02:00
|
|
|
const body: AbuseCreate = req.body
|
|
|
|
|
|
|
|
if (body.video?.id && !await doesVideoExist(body.video.id, res)) return
|
|
|
|
if (body.account?.id && !await doesAccountIdExist(body.account.id, res)) return
|
|
|
|
if (body.comment?.id && !await doesCommentIdExist(body.comment.id, res)) return
|
|
|
|
|
|
|
|
if (!body.video?.id && !body.account?.id && !body.comment?.id) {
|
2021-06-01 01:36:53 +02:00
|
|
|
res.fail({ message: 'video id or account id or comment id is required.' })
|
2020-07-07 10:57:04 +02:00
|
|
|
return
|
|
|
|
}
|
2020-07-01 16:05:30 +02:00
|
|
|
|
|
|
|
return next()
|
|
|
|
}
|
|
|
|
]
|
|
|
|
|
|
|
|
const abuseGetValidator = [
|
|
|
|
param('id').custom(isIdValid).not().isEmpty().withMessage('Should have a valid id'),
|
|
|
|
|
|
|
|
async (req: express.Request, res: express.Response, next: express.NextFunction) => {
|
|
|
|
logger.debug('Checking abuseGetValidator parameters', { parameters: req.body })
|
|
|
|
|
|
|
|
if (areValidationErrors(req, res)) return
|
2020-07-07 10:57:04 +02:00
|
|
|
if (!await doesAbuseExist(req.params.id, res)) return
|
2020-07-01 16:05:30 +02:00
|
|
|
|
|
|
|
return next()
|
|
|
|
}
|
|
|
|
]
|
|
|
|
|
|
|
|
const abuseUpdateValidator = [
|
|
|
|
param('id').custom(isIdValid).not().isEmpty().withMessage('Should have a valid id'),
|
2020-07-07 10:57:04 +02:00
|
|
|
|
2020-07-01 16:05:30 +02:00
|
|
|
body('state')
|
|
|
|
.optional()
|
2020-07-07 10:57:04 +02:00
|
|
|
.custom(isAbuseStateValid).withMessage('Should have a valid abuse state'),
|
2020-07-01 16:05:30 +02:00
|
|
|
body('moderationComment')
|
|
|
|
.optional()
|
2020-07-07 10:57:04 +02:00
|
|
|
.custom(isAbuseModerationCommentValid).withMessage('Should have a valid moderation comment'),
|
2020-07-01 16:05:30 +02:00
|
|
|
|
|
|
|
async (req: express.Request, res: express.Response, next: express.NextFunction) => {
|
|
|
|
logger.debug('Checking abuseUpdateValidator parameters', { parameters: req.body })
|
|
|
|
|
|
|
|
if (areValidationErrors(req, res)) return
|
2020-07-07 10:57:04 +02:00
|
|
|
if (!await doesAbuseExist(req.params.id, res)) return
|
2020-07-01 16:05:30 +02:00
|
|
|
|
|
|
|
return next()
|
|
|
|
}
|
|
|
|
]
|
|
|
|
|
2020-07-24 15:05:51 +02:00
|
|
|
const abuseListForAdminsValidator = [
|
2020-07-01 16:05:30 +02:00
|
|
|
query('id')
|
|
|
|
.optional()
|
|
|
|
.custom(isIdValid).withMessage('Should have a valid id'),
|
2020-07-07 10:57:04 +02:00
|
|
|
query('filter')
|
|
|
|
.optional()
|
|
|
|
.custom(isAbuseFilterValid)
|
|
|
|
.withMessage('Should have a valid filter'),
|
2020-07-01 16:05:30 +02:00
|
|
|
query('predefinedReason')
|
|
|
|
.optional()
|
|
|
|
.custom(isAbusePredefinedReasonValid)
|
|
|
|
.withMessage('Should have a valid predefinedReason'),
|
|
|
|
query('search')
|
|
|
|
.optional()
|
|
|
|
.custom(exists).withMessage('Should have a valid search'),
|
|
|
|
query('state')
|
|
|
|
.optional()
|
2020-07-08 15:51:46 +02:00
|
|
|
.custom(isAbuseStateValid).withMessage('Should have a valid abuse state'),
|
2020-07-01 16:05:30 +02:00
|
|
|
query('videoIs')
|
|
|
|
.optional()
|
|
|
|
.custom(isAbuseVideoIsValid).withMessage('Should have a valid "video is" attribute'),
|
|
|
|
query('searchReporter')
|
|
|
|
.optional()
|
|
|
|
.custom(exists).withMessage('Should have a valid reporter search'),
|
|
|
|
query('searchReportee')
|
|
|
|
.optional()
|
|
|
|
.custom(exists).withMessage('Should have a valid reportee search'),
|
|
|
|
query('searchVideo')
|
|
|
|
.optional()
|
|
|
|
.custom(exists).withMessage('Should have a valid video search'),
|
|
|
|
query('searchVideoChannel')
|
|
|
|
.optional()
|
|
|
|
.custom(exists).withMessage('Should have a valid video channel search'),
|
|
|
|
|
|
|
|
(req: express.Request, res: express.Response, next: express.NextFunction) => {
|
2020-07-24 15:05:51 +02:00
|
|
|
logger.debug('Checking abuseListForAdminsValidator parameters', { parameters: req.body })
|
2020-07-01 16:05:30 +02:00
|
|
|
|
|
|
|
if (areValidationErrors(req, res)) return
|
|
|
|
|
|
|
|
return next()
|
|
|
|
}
|
|
|
|
]
|
|
|
|
|
2020-07-24 15:05:51 +02:00
|
|
|
const abuseListForUserValidator = [
|
|
|
|
query('id')
|
|
|
|
.optional()
|
|
|
|
.custom(isIdValid).withMessage('Should have a valid id'),
|
|
|
|
|
|
|
|
query('search')
|
|
|
|
.optional()
|
|
|
|
.custom(exists).withMessage('Should have a valid search'),
|
|
|
|
|
|
|
|
query('state')
|
|
|
|
.optional()
|
|
|
|
.custom(isAbuseStateValid).withMessage('Should have a valid abuse state'),
|
|
|
|
|
|
|
|
(req: express.Request, res: express.Response, next: express.NextFunction) => {
|
|
|
|
logger.debug('Checking abuseListForUserValidator parameters', { parameters: req.body })
|
|
|
|
|
|
|
|
if (areValidationErrors(req, res)) return
|
|
|
|
|
|
|
|
return next()
|
|
|
|
}
|
|
|
|
]
|
|
|
|
|
|
|
|
const getAbuseValidator = [
|
|
|
|
param('id').custom(isIdValid).not().isEmpty().withMessage('Should have a valid id'),
|
|
|
|
|
|
|
|
async (req: express.Request, res: express.Response, next: express.NextFunction) => {
|
|
|
|
logger.debug('Checking getAbuseValidator parameters', { parameters: req.body })
|
|
|
|
|
|
|
|
if (areValidationErrors(req, res)) return
|
|
|
|
if (!await doesAbuseExist(req.params.id, res)) return
|
|
|
|
|
|
|
|
const user = res.locals.oauth.token.user
|
|
|
|
const abuse = res.locals.abuse
|
|
|
|
|
|
|
|
if (user.hasRight(UserRight.MANAGE_ABUSES) !== true && abuse.reporterAccountId !== user.Account.id) {
|
|
|
|
const message = `User ${user.username} does not have right to get abuse ${abuse.id}`
|
|
|
|
logger.warn(message)
|
|
|
|
|
2021-06-01 01:36:53 +02:00
|
|
|
return res.fail({
|
|
|
|
status: HttpStatusCode.FORBIDDEN_403,
|
|
|
|
message
|
|
|
|
})
|
2020-07-24 15:05:51 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return next()
|
|
|
|
}
|
|
|
|
]
|
|
|
|
|
2020-07-27 11:40:30 +02:00
|
|
|
const checkAbuseValidForMessagesValidator = [
|
|
|
|
(req: express.Request, res: express.Response, next: express.NextFunction) => {
|
|
|
|
logger.debug('Checking checkAbuseValidForMessagesValidator parameters', { parameters: req.body })
|
|
|
|
|
|
|
|
const abuse = res.locals.abuse
|
|
|
|
if (abuse.ReporterAccount.isOwned() === false) {
|
2021-06-01 01:36:53 +02:00
|
|
|
return res.fail({ message: 'This abuse was created by a user of your instance.' })
|
2020-07-27 11:40:30 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return next()
|
|
|
|
}
|
|
|
|
]
|
|
|
|
|
2020-07-24 15:05:51 +02:00
|
|
|
const addAbuseMessageValidator = [
|
|
|
|
body('message').custom(isAbuseMessageValid).not().isEmpty().withMessage('Should have a valid abuse message'),
|
|
|
|
|
|
|
|
(req: express.Request, res: express.Response, next: express.NextFunction) => {
|
|
|
|
logger.debug('Checking addAbuseMessageValidator parameters', { parameters: req.body })
|
|
|
|
|
|
|
|
if (areValidationErrors(req, res)) return
|
|
|
|
|
|
|
|
return next()
|
|
|
|
}
|
|
|
|
]
|
|
|
|
|
|
|
|
const deleteAbuseMessageValidator = [
|
|
|
|
param('messageId').custom(isIdValid).not().isEmpty().withMessage('Should have a valid message id'),
|
|
|
|
|
|
|
|
async (req: express.Request, res: express.Response, next: express.NextFunction) => {
|
|
|
|
logger.debug('Checking deleteAbuseMessageValidator parameters', { parameters: req.body })
|
|
|
|
|
|
|
|
if (areValidationErrors(req, res)) return
|
|
|
|
|
|
|
|
const user = res.locals.oauth.token.user
|
|
|
|
const abuse = res.locals.abuse
|
|
|
|
|
|
|
|
const messageId = parseInt(req.params.messageId + '', 10)
|
|
|
|
const abuseMessage = await AbuseMessageModel.loadByIdAndAbuseId(messageId, abuse.id)
|
|
|
|
|
|
|
|
if (!abuseMessage) {
|
2021-06-01 01:36:53 +02:00
|
|
|
return res.fail({
|
|
|
|
status: HttpStatusCode.NOT_FOUND_404,
|
|
|
|
message: 'Abuse message not found'
|
|
|
|
})
|
2020-07-24 15:05:51 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (user.hasRight(UserRight.MANAGE_ABUSES) !== true && abuseMessage.accountId !== user.Account.id) {
|
2021-06-01 01:36:53 +02:00
|
|
|
return res.fail({
|
|
|
|
status: HttpStatusCode.FORBIDDEN_403,
|
|
|
|
message: 'Cannot delete this abuse message'
|
|
|
|
})
|
2020-07-24 15:05:51 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
res.locals.abuseMessage = abuseMessage
|
|
|
|
|
|
|
|
return next()
|
|
|
|
}
|
|
|
|
]
|
|
|
|
|
2020-07-01 16:05:30 +02:00
|
|
|
// ---------------------------------------------------------------------------
|
|
|
|
|
|
|
|
export {
|
2020-07-24 15:05:51 +02:00
|
|
|
abuseListForAdminsValidator,
|
2020-07-01 16:05:30 +02:00
|
|
|
abuseReportValidator,
|
|
|
|
abuseGetValidator,
|
2020-07-24 15:05:51 +02:00
|
|
|
addAbuseMessageValidator,
|
2020-07-27 11:40:30 +02:00
|
|
|
checkAbuseValidForMessagesValidator,
|
2020-07-01 16:05:30 +02:00
|
|
|
abuseUpdateValidator,
|
2020-07-24 15:05:51 +02:00
|
|
|
deleteAbuseMessageValidator,
|
|
|
|
abuseListForUserValidator,
|
2020-11-10 14:41:20 +01:00
|
|
|
getAbuseValidator
|
2020-07-01 16:05:30 +02:00
|
|
|
}
|