]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blame - server/middlewares/validators/videos/video-channels.ts
Give moderators access to edit channels (#4608)
[github/Chocobozzz/PeerTube.git] / server / middlewares / validators / videos / video-channels.ts
CommitLineData
41fb13c3 1import express from 'express'
747c5628 2import { body, param, query } from 'express-validator'
a37e9e74 3import { CONFIG } from '@server/initializers/config'
4import { MChannelAccountDefault } from '@server/types/models'
c0e8b12e 5import { HttpStatusCode } from '../../../../shared/models/http/http-error-codes'
5a61ffbb 6import { isBooleanValid, toBooleanOrNull } from '../../../helpers/custom-validators/misc'
4e50b6a1 7import {
7d8e778a 8 isVideoChannelDescriptionValid,
27db7840
C
9 isVideoChannelDisplayNameValid,
10 isVideoChannelSupportValid,
11 isVideoChannelUsernameValid
6e46de09
C
12} from '../../../helpers/custom-validators/video-channels'
13import { logger } from '../../../helpers/logger'
7d9ba5c0 14import { ActorModel } from '../../../models/actor/actor'
6e46de09 15import { VideoChannelModel } from '../../../models/video/video-channel'
a37e9e74 16import { areValidationErrors, doesVideoChannelNameWithHostExist } from '../shared'
72c7248b 17
72c7248b 18const videoChannelsAddValidator = [
27db7840
C
19 body('name').custom(isVideoChannelUsernameValid).withMessage('Should have a valid channel name'),
20 body('displayName').custom(isVideoChannelDisplayNameValid).withMessage('Should have a valid display name'),
2422c46b
C
21 body('description').optional().custom(isVideoChannelDescriptionValid).withMessage('Should have a valid description'),
22 body('support').optional().custom(isVideoChannelSupportValid).withMessage('Should have a valid support text'),
72c7248b 23
601527d7 24 async (req: express.Request, res: express.Response, next: express.NextFunction) => {
72c7248b
C
25 logger.debug('Checking videoChannelsAdd parameters', { parameters: req.body })
26
a2431b7d
C
27 if (areValidationErrors(req, res)) return
28
601527d7
C
29 const actor = await ActorModel.loadLocalByName(req.body.name)
30 if (actor) {
76148b27
RK
31 res.fail({
32 status: HttpStatusCode.CONFLICT_409,
33 message: 'Another actor (account/channel) with this name on this instance already exists or has already existed.'
34 })
601527d7
C
35 return false
36 }
37
a3ce4ae8 38 const count = await VideoChannelModel.countByAccount(res.locals.oauth.token.User.Account.id)
754b6f5f
FC
39 if (count >= CONFIG.VIDEO_CHANNELS.MAX_PER_USER) {
40 res.fail({ message: `You cannot create more than ${CONFIG.VIDEO_CHANNELS.MAX_PER_USER} channels` })
a3ce4ae8
C
41 return false
42 }
43
a2431b7d 44 return next()
72c7248b
C
45 }
46]
47
48const videoChannelsUpdateValidator = [
8a19bee1 49 param('nameWithHost').exists().withMessage('Should have an video channel name with host'),
7d14d4d2
C
50 body('displayName')
51 .optional()
27db7840 52 .custom(isVideoChannelDisplayNameValid).withMessage('Should have a valid display name'),
7d14d4d2
C
53 body('description')
54 .optional()
55 .custom(isVideoChannelDescriptionValid).withMessage('Should have a valid description'),
56 body('support')
57 .optional()
58 .custom(isVideoChannelSupportValid).withMessage('Should have a valid support text'),
59 body('bulkVideosSupportUpdate')
60 .optional()
61 .custom(isBooleanValid).withMessage('Should have a valid bulkVideosSupportUpdate boolean field'),
72c7248b 62
906f46d0 63 (req: express.Request, res: express.Response, next: express.NextFunction) => {
72c7248b
C
64 logger.debug('Checking videoChannelsUpdate parameters', { parameters: req.body })
65
a2431b7d 66 if (areValidationErrors(req, res)) return
a2431b7d
C
67
68 return next()
72c7248b
C
69 }
70]
71
72const videoChannelsRemoveValidator = [
a2431b7d 73 async (req: express.Request, res: express.Response, next: express.NextFunction) => {
72c7248b
C
74 logger.debug('Checking videoChannelsRemove parameters', { parameters: req.params })
75
a37e9e74 76 if (!await checkVideoChannelIsNotTheLastOne(res.locals.videoChannel, res)) return
a2431b7d
C
77
78 return next()
72c7248b
C
79 }
80]
81
8a19bee1
C
82const videoChannelsNameWithHostValidator = [
83 param('nameWithHost').exists().withMessage('Should have an video channel name with host'),
72c7248b 84
a2431b7d 85 async (req: express.Request, res: express.Response, next: express.NextFunction) => {
8a19bee1 86 logger.debug('Checking videoChannelsNameWithHostValidator parameters', { parameters: req.params })
72c7248b 87
a2431b7d 88 if (areValidationErrors(req, res)) return
6b738c7a 89
0f6acda1 90 if (!await doesVideoChannelNameWithHostExist(req.params.nameWithHost, res)) return
a2431b7d
C
91
92 return next()
72c7248b
C
93 }
94]
95
a37e9e74 96const ensureIsLocalChannel = [
97 (req: express.Request, res: express.Response, next: express.NextFunction) => {
98 if (res.locals.videoChannel.Actor.isOwned() === false) {
99 return res.fail({
100 status: HttpStatusCode.FORBIDDEN_403,
101 message: 'This channel is not owned.'
102 })
103 }
06a05d5f
C
104
105 return next()
106 }
107]
108
747c5628 109const videoChannelStatsValidator = [
5a61ffbb
C
110 query('withStats')
111 .optional()
112 .customSanitizer(toBooleanOrNull)
113 .custom(isBooleanValid).withMessage('Should have a valid stats flag'),
747c5628
RK
114
115 (req: express.Request, res: express.Response, next: express.NextFunction) => {
116 if (areValidationErrors(req, res)) return
117 return next()
118 }
119]
120
37a44fc9
C
121const videoChannelsListValidator = [
122 query('search').optional().not().isEmpty().withMessage('Should have a valid search'),
123
124 (req: express.Request, res: express.Response, next: express.NextFunction) => {
125 logger.debug('Checking video channels search query', { parameters: req.query })
126
127 if (areValidationErrors(req, res)) return
128
129 return next()
130 }
131]
132
72c7248b
C
133// ---------------------------------------------------------------------------
134
135export {
72c7248b
C
136 videoChannelsAddValidator,
137 videoChannelsUpdateValidator,
138 videoChannelsRemoveValidator,
8a19bee1 139 videoChannelsNameWithHostValidator,
a37e9e74 140 ensureIsLocalChannel,
37a44fc9 141 videoChannelsListValidator,
747c5628 142 videoChannelStatsValidator
72c7248b
C
143}
144
145// ---------------------------------------------------------------------------
146
a37e9e74 147async function checkVideoChannelIsNotTheLastOne (videoChannel: MChannelAccountDefault, res: express.Response) {
148 const count = await VideoChannelModel.countByAccount(videoChannel.Account.id)
a2431b7d
C
149
150 if (count <= 1) {
76148b27
RK
151 res.fail({
152 status: HttpStatusCode.CONFLICT_409,
153 message: 'Cannot remove the last channel of this user'
154 })
a2431b7d
C
155 return false
156 }
157
158 return true
72c7248b 159}