]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blame - server/helpers/custom-validators/videos.ts
Fix last commit
[github/Chocobozzz/PeerTube.git] / server / helpers / custom-validators / videos.ts
CommitLineData
8d468a16 1import { Response } from 'express'
fdbda9e3 2import 'express-validator'
79d5caf9 3import { values } from 'lodash'
1840c2f7 4import 'multer'
79d5caf9 5import * as validator from 'validator'
2baea0c7 6import { UserRight, VideoPrivacy, VideoRateType } from '../../../shared'
3fd3ab2d
C
7import {
8 CONSTRAINTS_FIELDS,
9 VIDEO_CATEGORIES,
28be8916
C
10 VIDEO_LICENCES,
11 VIDEO_MIMETYPE_EXT,
3fd3ab2d 12 VIDEO_PRIVACIES,
2186386c
C
13 VIDEO_RATE_TYPES,
14 VIDEO_STATES
3fd3ab2d
C
15} from '../../initializers'
16import { VideoModel } from '../../models/video/video'
ac81d1a0 17import { exists, isArray, isFileValid } from './misc'
0f320037 18import { VideoChannelModel } from '../../models/video/video-channel'
6200d8d9 19import { UserModel } from '../../models/account/user'
65fcc311
C
20
21const VIDEOS_CONSTRAINTS_FIELDS = CONSTRAINTS_FIELDS.VIDEOS
22const VIDEO_ABUSES_CONSTRAINTS_FIELDS = CONSTRAINTS_FIELDS.VIDEO_ABUSES
0b697522 23
9d3ef9fe 24function isVideoCategoryValid (value: any) {
2186386c
C
25 return value === null || VIDEO_CATEGORIES[ value ] !== undefined
26}
27
28function isVideoStateValid (value: any) {
29 return exists(value) && VIDEO_STATES[ value ] !== undefined
6e07c3de
C
30}
31
9d3ef9fe 32function isVideoLicenceValid (value: any) {
2186386c 33 return value === null || VIDEO_LICENCES[ value ] !== undefined
6f0c39e2
C
34}
35
9d3ef9fe
C
36function isVideoLanguageValid (value: any) {
37 return value === null ||
38 (typeof value === 'string' && validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.LANGUAGE))
3092476e
C
39}
40
8e10cf1a
C
41function isVideoDurationValid (value: string) {
42 return exists(value) && validator.isInt(value + '', VIDEOS_CONSTRAINTS_FIELDS.DURATION)
43}
44
9567011b
C
45function isVideoTruncatedDescriptionValid (value: string) {
46 return exists(value) && validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.TRUNCATED_DESCRIPTION)
47}
48
69818c93 49function isVideoDescriptionValid (value: string) {
f595d394 50 return value === null || (exists(value) && validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.DESCRIPTION))
be587647
C
51}
52
2422c46b
C
53function isVideoSupportValid (value: string) {
54 return value === null || (exists(value) && validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.SUPPORT))
55}
56
69818c93
C
57function isVideoNameValid (value: string) {
58 return exists(value) && validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.NAME)
be587647
C
59}
60
0d0e8dd0
C
61function isVideoTagValid (tag: string) {
62 return exists(tag) && validator.isLength(tag, VIDEOS_CONSTRAINTS_FIELDS.TAG)
63}
64
69818c93 65function isVideoTagsValid (tags: string[]) {
2efd32f6
C
66 return tags === null || (
67 isArray(tags) &&
68 validator.isInt(tags.length.toString(), VIDEOS_CONSTRAINTS_FIELDS.TAGS) &&
69 tags.every(tag => isVideoTagValid(tag))
70 )
be587647
C
71}
72
69818c93
C
73function isVideoAbuseReasonValid (value: string) {
74 return exists(value) && validator.isLength(value, VIDEO_ABUSES_CONSTRAINTS_FIELDS.REASON)
e4c55619
C
75}
76
69818c93
C
77function isVideoViewsValid (value: string) {
78 return exists(value) && validator.isInt(value + '', VIDEOS_CONSTRAINTS_FIELDS.VIEWS)
9e167724
C
79}
80
69818c93 81function isVideoRatingTypeValid (value: string) {
57a49263 82 return value === 'none' || values(VIDEO_RATE_TYPES).indexOf(value as VideoRateType) !== -1
d38b8281
C
83}
84
ac81d1a0
C
85const videoFileTypes = Object.keys(VIDEO_MIMETYPE_EXT).map(m => `(${m})`)
86const videoFileTypesRegex = videoFileTypes.join('|')
2186386c 87
b60e5f38 88function isVideoFile (files: { [ fieldname: string ]: Express.Multer.File[] } | Express.Multer.File[]) {
0c237b19 89 return isFileValid(files, videoFileTypesRegex, 'videofile', null)
ac81d1a0 90}
f6f7dfee 91
ac81d1a0 92const videoImageTypes = CONSTRAINTS_FIELDS.VIDEOS.IMAGE.EXTNAME
2186386c
C
93 .map(v => v.replace('.', ''))
94 .join('|')
ac81d1a0 95const videoImageTypesRegex = `image/(${videoImageTypes})`
2186386c 96
ac81d1a0 97function isVideoImage (files: { [ fieldname: string ]: Express.Multer.File[] } | Express.Multer.File[], field: string) {
0c237b19 98 return isFileValid(files, videoImageTypesRegex, field, CONSTRAINTS_FIELDS.VIDEOS.IMAGE.FILE_SIZE.max, true)
f6f7dfee
C
99}
100
2baea0c7 101function isVideoPrivacyValid (value: number) {
2186386c 102 return validator.isInt(value + '') && VIDEO_PRIVACIES[ value ] !== undefined
d4f1e94c
C
103}
104
2baea0c7
C
105function isScheduleVideoUpdatePrivacyValid (value: number) {
106 return validator.isInt(value + '') &&
107 (
108 value === VideoPrivacy.UNLISTED ||
109 value === VideoPrivacy.PUBLIC
110 )
111}
112
2cebd797 113function isVideoFileInfoHashValid (value: string | null | undefined) {
93e1258c
C
114 return exists(value) && validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.INFO_HASH)
115}
116
d4f1e94c
C
117function isVideoFileResolutionValid (value: string) {
118 return exists(value) && validator.isInt(value + '')
119}
120
3a6f351b
C
121function isVideoFPSResolutionValid (value: string) {
122 return value === null || validator.isInt(value + '')
123}
124
d4f1e94c
C
125function isVideoFileSizeValid (value: string) {
126 return exists(value) && validator.isInt(value + '', VIDEOS_CONSTRAINTS_FIELDS.FILE_SIZE)
8d468a16
C
127}
128
40e87e9e
C
129function checkUserCanManageVideo (user: UserModel, video: VideoModel, right: UserRight, res: Response) {
130 // Retrieve the user who did the request
131 if (video.isOwned() === false) {
132 res.status(403)
133 .json({ error: 'Cannot manage a video of another server.' })
134 .end()
135 return false
136 }
137
138 // Check if the user can delete the video
139 // The user can delete it if he has the right
140 // Or if s/he is the video's account
141 const account = video.VideoChannel.Account
142 if (user.hasRight(right) === false && account.userId !== user.id) {
143 res.status(403)
144 .json({ error: 'Cannot manage a video of another user.' })
145 .end()
146 return false
147 }
148
149 return true
150}
151
a2431b7d 152async function isVideoExist (id: string, res: Response) {
c1e791ba 153 let video: VideoModel | null
4e50b6a1
C
154
155 if (validator.isInt(id)) {
3fd3ab2d 156 video = await VideoModel.loadAndPopulateAccountAndServerAndTags(+id)
4e50b6a1 157 } else { // UUID
3fd3ab2d 158 video = await VideoModel.loadByUUIDAndPopulateAccountAndServerAndTags(id)
4e50b6a1
C
159 }
160
2cebd797 161 if (video === null) {
4e50b6a1 162 res.status(404)
2186386c
C
163 .json({ error: 'Video not found' })
164 .end()
4e50b6a1
C
165
166 return false
167 }
168
169 res.locals.video = video
170 return true
171}
172
6200d8d9
C
173async function isVideoChannelOfAccountExist (channelId: number, user: UserModel, res: Response) {
174 if (user.hasRight(UserRight.UPDATE_ANY_VIDEO) === true) {
175 const videoChannel = await VideoChannelModel.loadAndPopulateAccount(channelId)
2cebd797 176 if (videoChannel === null) {
6200d8d9
C
177 res.status(400)
178 .json({ error: 'Unknown video video channel on this instance.' })
179 .end()
180
181 return false
182 }
183
184 res.locals.videoChannel = videoChannel
185 return true
186 }
187
188 const videoChannel = await VideoChannelModel.loadByIdAndAccount(channelId, user.Account.id)
2cebd797 189 if (videoChannel === null) {
0f320037
C
190 res.status(400)
191 .json({ error: 'Unknown video video channel for this account.' })
192 .end()
193
194 return false
195 }
196
197 res.locals.videoChannel = videoChannel
198 return true
199}
200
55fa55a9
C
201// ---------------------------------------------------------------------------
202
65fcc311 203export {
65fcc311 204 isVideoCategoryValid,
40e87e9e 205 checkUserCanManageVideo,
65fcc311
C
206 isVideoLicenceValid,
207 isVideoLanguageValid,
9567011b 208 isVideoTruncatedDescriptionValid,
65fcc311 209 isVideoDescriptionValid,
93e1258c 210 isVideoFileInfoHashValid,
65fcc311
C
211 isVideoNameValid,
212 isVideoTagsValid,
3a6f351b 213 isVideoFPSResolutionValid,
2baea0c7 214 isScheduleVideoUpdatePrivacyValid,
65fcc311 215 isVideoAbuseReasonValid,
65fcc311 216 isVideoFile,
2186386c 217 isVideoStateValid,
65fcc311 218 isVideoViewsValid,
65fcc311 219 isVideoRatingTypeValid,
8e10cf1a 220 isVideoDurationValid,
0d0e8dd0 221 isVideoTagValid,
8d468a16 222 isVideoPrivacyValid,
d4f1e94c
C
223 isVideoFileResolutionValid,
224 isVideoFileSizeValid,
ac81d1a0 225 isVideoExist,
2422c46b 226 isVideoImage,
0f320037 227 isVideoChannelOfAccountExist,
2422c46b 228 isVideoSupportValid
65fcc311 229}