]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blob - server/helpers/custom-validators/videos.ts
a227136acc5fde6644f97584932cd7b312f05a7e
[github/Chocobozzz/PeerTube.git] / server / helpers / custom-validators / videos.ts
1 import { Response } from 'express'
2 import 'express-validator'
3 import { values } from 'lodash'
4 import 'multer'
5 import * as validator from 'validator'
6 import { UserRight, VideoPrivacy, VideoRateType } from '../../../shared'
7 import {
8 CONSTRAINTS_FIELDS,
9 VIDEO_CATEGORIES,
10 VIDEO_LICENCES,
11 VIDEO_MIMETYPE_EXT,
12 VIDEO_PRIVACIES,
13 VIDEO_RATE_TYPES,
14 VIDEO_STATES
15 } from '../../initializers'
16 import { VideoModel } from '../../models/video/video'
17 import { exists, isArray, isFileValid } from './misc'
18 import { VideoChannelModel } from '../../models/video/video-channel'
19 import { UserModel } from '../../models/account/user'
20
21 const VIDEOS_CONSTRAINTS_FIELDS = CONSTRAINTS_FIELDS.VIDEOS
22 const VIDEO_ABUSES_CONSTRAINTS_FIELDS = CONSTRAINTS_FIELDS.VIDEO_ABUSES
23
24 function isVideoCategoryValid (value: any) {
25 return value === null || VIDEO_CATEGORIES[ value ] !== undefined
26 }
27
28 function isVideoStateValid (value: any) {
29 return exists(value) && VIDEO_STATES[ value ] !== undefined
30 }
31
32 function isVideoLicenceValid (value: any) {
33 return value === null || VIDEO_LICENCES[ value ] !== undefined
34 }
35
36 function isVideoLanguageValid (value: any) {
37 return value === null ||
38 (typeof value === 'string' && validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.LANGUAGE))
39 }
40
41 function isVideoDurationValid (value: string) {
42 return exists(value) && validator.isInt(value + '', VIDEOS_CONSTRAINTS_FIELDS.DURATION)
43 }
44
45 function isVideoTruncatedDescriptionValid (value: string) {
46 return exists(value) && validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.TRUNCATED_DESCRIPTION)
47 }
48
49 function isVideoDescriptionValid (value: string) {
50 return value === null || (exists(value) && validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.DESCRIPTION))
51 }
52
53 function isVideoSupportValid (value: string) {
54 return value === null || (exists(value) && validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.SUPPORT))
55 }
56
57 function isVideoNameValid (value: string) {
58 return exists(value) && validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.NAME)
59 }
60
61 function isVideoTagValid (tag: string) {
62 return exists(tag) && validator.isLength(tag, VIDEOS_CONSTRAINTS_FIELDS.TAG)
63 }
64
65 function isVideoTagsValid (tags: string[]) {
66 return tags === null || (
67 isArray(tags) &&
68 validator.isInt(tags.length.toString(), VIDEOS_CONSTRAINTS_FIELDS.TAGS) &&
69 tags.every(tag => isVideoTagValid(tag))
70 )
71 }
72
73 function isVideoAbuseReasonValid (value: string) {
74 return exists(value) && validator.isLength(value, VIDEO_ABUSES_CONSTRAINTS_FIELDS.REASON)
75 }
76
77 function isVideoViewsValid (value: string) {
78 return exists(value) && validator.isInt(value + '', VIDEOS_CONSTRAINTS_FIELDS.VIEWS)
79 }
80
81 function isVideoRatingTypeValid (value: string) {
82 return value === 'none' || values(VIDEO_RATE_TYPES).indexOf(value as VideoRateType) !== -1
83 }
84
85 const videoFileTypes = Object.keys(VIDEO_MIMETYPE_EXT).map(m => `(${m})`)
86 const videoFileTypesRegex = videoFileTypes.join('|')
87
88 function isVideoFile (files: { [ fieldname: string ]: Express.Multer.File[] } | Express.Multer.File[]) {
89 return isFileValid(files, videoFileTypesRegex, 'videofile')
90 }
91
92 const videoImageTypes = CONSTRAINTS_FIELDS.VIDEOS.IMAGE.EXTNAME
93 .map(v => v.replace('.', ''))
94 .join('|')
95 const videoImageTypesRegex = `image/(${videoImageTypes})`
96
97 function isVideoImage (files: { [ fieldname: string ]: Express.Multer.File[] } | Express.Multer.File[], field: string) {
98 return isFileValid(files, videoImageTypesRegex, field, true)
99 }
100
101 function isVideoPrivacyValid (value: number) {
102 return validator.isInt(value + '') && VIDEO_PRIVACIES[ value ] !== undefined
103 }
104
105 function isScheduleVideoUpdatePrivacyValid (value: number) {
106 return validator.isInt(value + '') &&
107 (
108 value === VideoPrivacy.UNLISTED ||
109 value === VideoPrivacy.PUBLIC
110 )
111 }
112
113 function isVideoFileInfoHashValid (value: string) {
114 return exists(value) && validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.INFO_HASH)
115 }
116
117 function isVideoFileResolutionValid (value: string) {
118 return exists(value) && validator.isInt(value + '')
119 }
120
121 function isVideoFileSizeValid (value: string) {
122 return exists(value) && validator.isInt(value + '', VIDEOS_CONSTRAINTS_FIELDS.FILE_SIZE)
123 }
124
125 async function isVideoExist (id: string, res: Response) {
126 let video: VideoModel
127
128 if (validator.isInt(id)) {
129 video = await VideoModel.loadAndPopulateAccountAndServerAndTags(+id)
130 } else { // UUID
131 video = await VideoModel.loadByUUIDAndPopulateAccountAndServerAndTags(id)
132 }
133
134 if (!video) {
135 res.status(404)
136 .json({ error: 'Video not found' })
137 .end()
138
139 return false
140 }
141
142 res.locals.video = video
143 return true
144 }
145
146 async function isVideoChannelOfAccountExist (channelId: number, user: UserModel, res: Response) {
147 if (user.hasRight(UserRight.UPDATE_ANY_VIDEO) === true) {
148 const videoChannel = await VideoChannelModel.loadAndPopulateAccount(channelId)
149 if (!videoChannel) {
150 res.status(400)
151 .json({ error: 'Unknown video video channel on this instance.' })
152 .end()
153
154 return false
155 }
156
157 res.locals.videoChannel = videoChannel
158 return true
159 }
160
161 const videoChannel = await VideoChannelModel.loadByIdAndAccount(channelId, user.Account.id)
162 if (!videoChannel) {
163 res.status(400)
164 .json({ error: 'Unknown video video channel for this account.' })
165 .end()
166
167 return false
168 }
169
170 res.locals.videoChannel = videoChannel
171 return true
172 }
173
174 // ---------------------------------------------------------------------------
175
176 export {
177 isVideoCategoryValid,
178 isVideoLicenceValid,
179 isVideoLanguageValid,
180 isVideoTruncatedDescriptionValid,
181 isVideoDescriptionValid,
182 isVideoFileInfoHashValid,
183 isVideoNameValid,
184 isVideoTagsValid,
185 isScheduleVideoUpdatePrivacyValid,
186 isVideoAbuseReasonValid,
187 isVideoFile,
188 isVideoStateValid,
189 isVideoViewsValid,
190 isVideoRatingTypeValid,
191 isVideoDurationValid,
192 isVideoTagValid,
193 isVideoPrivacyValid,
194 isVideoFileResolutionValid,
195 isVideoFileSizeValid,
196 isVideoExist,
197 isVideoImage,
198 isVideoChannelOfAccountExist,
199 isVideoSupportValid
200 }