]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blame - server/middlewares/validators/videos/video-channels.ts
Merge branch 'release/1.4.0' into develop
[github/Chocobozzz/PeerTube.git] / server / middlewares / validators / videos / video-channels.ts
CommitLineData
72c7248b 1import * as express from 'express'
c8861d5d 2import { body, param } from 'express-validator'
6e46de09 3import { UserRight } from '../../../../shared'
4e50b6a1 4import {
7d8e778a 5 isVideoChannelDescriptionValid,
7d8e778a
C
6 isVideoChannelNameValid,
7 isVideoChannelSupportValid
6e46de09
C
8} from '../../../helpers/custom-validators/video-channels'
9import { logger } from '../../../helpers/logger'
6e46de09
C
10import { VideoChannelModel } from '../../../models/video/video-channel'
11import { areValidationErrors } from '../utils'
12import { isActorPreferredUsernameValid } from '../../../helpers/custom-validators/activitypub/actor'
13import { ActorModel } from '../../../models/activitypub/actor'
7d14d4d2 14import { isBooleanValid } from '../../../helpers/custom-validators/misc'
3e753302 15import { doesLocalVideoChannelNameExist, doesVideoChannelNameWithHostExist } from '../../../helpers/middlewares'
0283eaac 16import { MChannelAccountDefault, MUser } from '@server/typings/models'
72c7248b 17
72c7248b 18const videoChannelsAddValidator = [
8a19bee1 19 body('name').custom(isActorPreferredUsernameValid).withMessage('Should have a valid channel name'),
08c1efbe 20 body('displayName').custom(isVideoChannelNameValid).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) {
31 res.status(409)
32 .send({ error: 'Another actor (account/channel) with this name on this instance already exists or has already existed.' })
33 .end()
34 return false
35 }
36
a2431b7d 37 return next()
72c7248b
C
38 }
39]
40
41const videoChannelsUpdateValidator = [
8a19bee1 42 param('nameWithHost').exists().withMessage('Should have an video channel name with host'),
7d14d4d2
C
43 body('displayName')
44 .optional()
45 .custom(isVideoChannelNameValid).withMessage('Should have a valid display name'),
46 body('description')
47 .optional()
48 .custom(isVideoChannelDescriptionValid).withMessage('Should have a valid description'),
49 body('support')
50 .optional()
51 .custom(isVideoChannelSupportValid).withMessage('Should have a valid support text'),
52 body('bulkVideosSupportUpdate')
53 .optional()
54 .custom(isBooleanValid).withMessage('Should have a valid bulkVideosSupportUpdate boolean field'),
72c7248b 55
a2431b7d 56 async (req: express.Request, res: express.Response, next: express.NextFunction) => {
72c7248b
C
57 logger.debug('Checking videoChannelsUpdate parameters', { parameters: req.body })
58
a2431b7d 59 if (areValidationErrors(req, res)) return
0f6acda1 60 if (!await doesVideoChannelNameWithHostExist(req.params.nameWithHost, res)) return
a2431b7d
C
61
62 // We need to make additional checks
d50acfab 63 if (res.locals.videoChannel.Actor.isOwned() === false) {
a2431b7d
C
64 return res.status(403)
65 .json({ error: 'Cannot update video channel of another server' })
66 .end()
67 }
68
69 if (res.locals.videoChannel.Account.userId !== res.locals.oauth.token.User.id) {
70 return res.status(403)
71 .json({ error: 'Cannot update video channel of another user' })
72 .end()
73 }
74
75 return next()
72c7248b
C
76 }
77]
78
79const videoChannelsRemoveValidator = [
8a19bee1 80 param('nameWithHost').exists().withMessage('Should have an video channel name with host'),
72c7248b 81
a2431b7d 82 async (req: express.Request, res: express.Response, next: express.NextFunction) => {
72c7248b
C
83 logger.debug('Checking videoChannelsRemove parameters', { parameters: req.params })
84
a2431b7d 85 if (areValidationErrors(req, res)) return
0f6acda1 86 if (!await doesVideoChannelNameWithHostExist(req.params.nameWithHost, res)) return
a2431b7d 87
d48ff09d 88 if (!checkUserCanDeleteVideoChannel(res.locals.oauth.token.User, res.locals.videoChannel, res)) return
a2431b7d
C
89 if (!await checkVideoChannelIsNotTheLastOne(res)) return
90
91 return next()
72c7248b
C
92 }
93]
94
8a19bee1
C
95const videoChannelsNameWithHostValidator = [
96 param('nameWithHost').exists().withMessage('Should have an video channel name with host'),
72c7248b 97
a2431b7d 98 async (req: express.Request, res: express.Response, next: express.NextFunction) => {
8a19bee1 99 logger.debug('Checking videoChannelsNameWithHostValidator parameters', { parameters: req.params })
72c7248b 100
a2431b7d 101 if (areValidationErrors(req, res)) return
6b738c7a 102
0f6acda1 103 if (!await doesVideoChannelNameWithHostExist(req.params.nameWithHost, res)) return
a2431b7d
C
104
105 return next()
72c7248b
C
106 }
107]
108
06a05d5f
C
109const localVideoChannelValidator = [
110 param('name').custom(isVideoChannelNameValid).withMessage('Should have a valid video channel name'),
111
112 async (req: express.Request, res: express.Response, next: express.NextFunction) => {
113 logger.debug('Checking localVideoChannelValidator parameters', { parameters: req.params })
114
115 if (areValidationErrors(req, res)) return
0f6acda1 116 if (!await doesLocalVideoChannelNameExist(req.params.name, res)) return
06a05d5f
C
117
118 return next()
119 }
120]
121
72c7248b
C
122// ---------------------------------------------------------------------------
123
124export {
72c7248b
C
125 videoChannelsAddValidator,
126 videoChannelsUpdateValidator,
127 videoChannelsRemoveValidator,
8a19bee1 128 videoChannelsNameWithHostValidator,
06a05d5f 129 localVideoChannelValidator
72c7248b
C
130}
131
132// ---------------------------------------------------------------------------
133
0283eaac 134function checkUserCanDeleteVideoChannel (user: MUser, videoChannel: MChannelAccountDefault, res: express.Response) {
50d6de9c 135 if (videoChannel.Actor.isOwned() === false) {
a2431b7d 136 res.status(403)
60862425 137 .json({ error: 'Cannot remove video channel of another server.' })
72c7248b 138 .end()
a2431b7d
C
139
140 return false
72c7248b
C
141 }
142
143 // Check if the user can delete the video channel
144 // The user can delete it if s/he is an admin
38fa2065 145 // Or if s/he is the video channel's account
a2431b7d
C
146 if (user.hasRight(UserRight.REMOVE_ANY_VIDEO_CHANNEL) === false && videoChannel.Account.userId !== user.id) {
147 res.status(403)
72c7248b
C
148 .json({ error: 'Cannot remove video channel of another user' })
149 .end()
a2431b7d
C
150
151 return false
72c7248b
C
152 }
153
a2431b7d 154 return true
72c7248b
C
155}
156
a2431b7d 157async function checkVideoChannelIsNotTheLastOne (res: express.Response) {
3fd3ab2d 158 const count = await VideoChannelModel.countByAccount(res.locals.oauth.token.User.Account.id)
a2431b7d
C
159
160 if (count <= 1) {
161 res.status(409)
162 .json({ error: 'Cannot remove the last channel of this user' })
163 .end()
164
165 return false
166 }
167
168 return true
72c7248b 169}