aboutsummaryrefslogblamecommitdiffhomepage
path: root/server/middlewares/validators/abuse.ts
blob: 70bae17758d48a8308529d862e5f9a22e7971036 (plain) (tree)
1
2
3
4
5
6
7
                             

                                                      
                                 
                     
                      
                                






                                                 
                                                                                                                        
                                               

                                                                      
                                                                             
                                                                                                                      
                                                

                              

                    
                       


                  
                                    
                             
                       

                                 
                                   
                     


                                  



                                                                           

                    
                       

                
                                


                           
                                            
 
                                                                                      
                                             
 






                                                                                   
                                                                                

            





                           

                       

                                                                                      
                                             
                                                         





                              

                       
 

               
                               

                           
                                           

                                                                                      
                                             
                                                         




                 
                                     

               
                       

                 
                                

                           
                                          

                 
                    

                
                               

                  
                                 

                         
                    

                         
                    

                      
                    

                             
                    

                                                                                





                                             


                                   
                       


                 
                    


                
                               

                                                                                






                                             

                       

                                                                                      









                                                                                                         



                                             





                 

                                                                                

                                                    
                                                                                        





                 
                                  

                                 

                                                                                






                                             

                       

                                                                                      




                                             
                                                       


                                                                                        



                                             


                                                                                                        



                                                   







                                          


                                                                              
                              

                       
                           
                                      
                       

                              
                   
 
import express from 'express'
import { body, param, query } from 'express-validator'
import {
  areAbusePredefinedReasonsValid,
  isAbuseFilterValid,
  isAbuseMessageValid,
  isAbuseModerationCommentValid,
  isAbusePredefinedReasonValid,
  isAbuseReasonValid,
  isAbuseStateValid,
  isAbuseTimestampCoherent,
  isAbuseTimestampValid,
  isAbuseVideoIsValid
} from '@server/helpers/custom-validators/abuses'
import { exists, isIdOrUUIDValid, isIdValid, toCompleteUUID, toIntOrNull } from '@server/helpers/custom-validators/misc'
import { logger } from '@server/helpers/logger'
import { AbuseMessageModel } from '@server/models/abuse/abuse-message'
import { AbuseCreate, UserRight } from '@shared/models'
import { HttpStatusCode } from '../../../shared/models/http/http-error-codes'
import { areValidationErrors, doesAbuseExist, doesAccountIdExist, doesCommentIdExist, doesVideoExist } from './shared'
import { forceNumber } from '@shared/core-utils'

const abuseReportValidator = [
  body('account.id')
    .optional()
    .custom(isIdValid),

  body('video.id')
    .optional()
    .customSanitizer(toCompleteUUID)
    .custom(isIdOrUUIDValid),
  body('video.startAt')
    .optional()
    .customSanitizer(toIntOrNull)
    .custom(isAbuseTimestampValid),
  body('video.endAt')
    .optional()
    .customSanitizer(toIntOrNull)
    .custom(isAbuseTimestampValid)
    .bail()
    .custom(isAbuseTimestampCoherent)
    .withMessage('Should have a startAt timestamp beginning before endAt'),

  body('comment.id')
    .optional()
    .custom(isIdValid),

  body('reason')
    .custom(isAbuseReasonValid),

  body('predefinedReasons')
    .optional()
    .custom(areAbusePredefinedReasonsValid),

  async (req: express.Request, res: express.Response, next: express.NextFunction) => {
    if (areValidationErrors(req, res)) return

    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) {
      res.fail({ message: 'video id or account id or comment id is required.' })
      return
    }

    return next()
  }
]

const abuseGetValidator = [
  param('id')
    .custom(isIdValid),

  async (req: express.Request, res: express.Response, next: express.NextFunction) => {
    if (areValidationErrors(req, res)) return
    if (!await doesAbuseExist(req.params.id, res)) return

    return next()
  }
]

const abuseUpdateValidator = [
  param('id')
    .custom(isIdValid),

  body('state')
    .optional()
    .custom(isAbuseStateValid),
  body('moderationComment')
    .optional()
    .custom(isAbuseModerationCommentValid),

  async (req: express.Request, res: express.Response, next: express.NextFunction) => {
    if (areValidationErrors(req, res)) return
    if (!await doesAbuseExist(req.params.id, res)) return

    return next()
  }
]

const abuseListForAdminsValidator = [
  query('id')
    .optional()
    .custom(isIdValid),
  query('filter')
    .optional()
    .custom(isAbuseFilterValid),
  query('predefinedReason')
    .optional()
    .custom(isAbusePredefinedReasonValid),
  query('search')
    .optional()
    .custom(exists),
  query('state')
    .optional()
    .custom(isAbuseStateValid),
  query('videoIs')
    .optional()
    .custom(isAbuseVideoIsValid),
  query('searchReporter')
    .optional()
    .custom(exists),
  query('searchReportee')
    .optional()
    .custom(exists),
  query('searchVideo')
    .optional()
    .custom(exists),
  query('searchVideoChannel')
    .optional()
    .custom(exists),

  (req: express.Request, res: express.Response, next: express.NextFunction) => {
    if (areValidationErrors(req, res)) return

    return next()
  }
]

const abuseListForUserValidator = [
  query('id')
    .optional()
    .custom(isIdValid),

  query('search')
    .optional()
    .custom(exists),

  query('state')
    .optional()
    .custom(isAbuseStateValid),

  (req: express.Request, res: express.Response, next: express.NextFunction) => {
    if (areValidationErrors(req, res)) return

    return next()
  }
]

const getAbuseValidator = [
  param('id')
    .custom(isIdValid),

  async (req: express.Request, res: express.Response, next: express.NextFunction) => {
    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)

      return res.fail({
        status: HttpStatusCode.FORBIDDEN_403,
        message
      })
    }

    return next()
  }
]

const checkAbuseValidForMessagesValidator = [
  (req: express.Request, res: express.Response, next: express.NextFunction) => {
    const abuse = res.locals.abuse
    if (abuse.ReporterAccount.isOwned() === false) {
      return res.fail({ message: 'This abuse was created by a user of your instance.' })
    }

    return next()
  }
]

const addAbuseMessageValidator = [
  body('message')
    .custom(isAbuseMessageValid),

  (req: express.Request, res: express.Response, next: express.NextFunction) => {
    if (areValidationErrors(req, res)) return

    return next()
  }
]

const deleteAbuseMessageValidator = [
  param('messageId')
    .custom(isIdValid),

  async (req: express.Request, res: express.Response, next: express.NextFunction) => {
    if (areValidationErrors(req, res)) return

    const user = res.locals.oauth.token.user
    const abuse = res.locals.abuse

    const messageId = forceNumber(req.params.messageId)
    const abuseMessage = await AbuseMessageModel.loadByIdAndAbuseId(messageId, abuse.id)

    if (!abuseMessage) {
      return res.fail({
        status: HttpStatusCode.NOT_FOUND_404,
        message: 'Abuse message not found'
      })
    }

    if (user.hasRight(UserRight.MANAGE_ABUSES) !== true && abuseMessage.accountId !== user.Account.id) {
      return res.fail({
        status: HttpStatusCode.FORBIDDEN_403,
        message: 'Cannot delete this abuse message'
      })
    }

    res.locals.abuseMessage = abuseMessage

    return next()
  }
]

// ---------------------------------------------------------------------------

export {
  abuseListForAdminsValidator,
  abuseReportValidator,
  abuseGetValidator,
  addAbuseMessageValidator,
  checkAbuseValidForMessagesValidator,
  abuseUpdateValidator,
  deleteAbuseMessageValidator,
  abuseListForUserValidator,
  getAbuseValidator
}