]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blame - server/helpers/custom-validators/videos.ts
Fix video upload and videos list
[github/Chocobozzz/PeerTube.git] / server / helpers / custom-validators / videos.ts
CommitLineData
65fcc311 1import { values } from 'lodash'
4d4e5cd4 2import * as validator from 'validator'
35bf0c83
C
3import * as Promise from 'bluebird'
4import * as express from 'express'
fdbda9e3 5import 'express-validator'
1840c2f7 6import 'multer'
65fcc311
C
7
8import {
9 CONSTRAINTS_FIELDS,
10 VIDEO_CATEGORIES,
11 VIDEO_LICENCES,
12 VIDEO_LANGUAGES,
35bf0c83 13 VIDEO_RATE_TYPES,
fd45e8f4 14 VIDEO_PRIVACIES,
35bf0c83 15 database as db
65fcc311
C
16} from '../../initializers'
17import { isUserUsernameValid } from './users'
69818c93 18import { isArray, exists } from './misc'
35bf0c83
C
19import { VideoInstance } from '../../models'
20import { logger } from '../../helpers'
ee9e7b61 21import { VideoRateType } from '../../../shared'
e34c85e5 22import { isActivityPubUrlValid } from './activitypub/misc'
65fcc311
C
23
24const VIDEOS_CONSTRAINTS_FIELDS = CONSTRAINTS_FIELDS.VIDEOS
25const VIDEO_ABUSES_CONSTRAINTS_FIELDS = CONSTRAINTS_FIELDS.VIDEO_ABUSES
26const VIDEO_EVENTS_CONSTRAINTS_FIELDS = CONSTRAINTS_FIELDS.VIDEO_EVENTS
0b697522 27
69818c93 28function isVideoCategoryValid (value: number) {
65fcc311 29 return VIDEO_CATEGORIES[value] !== undefined
6e07c3de
C
30}
31
51c443db
C
32// Maybe we don't know the remote category, but that doesn't matter
33function isRemoteVideoCategoryValid (value: string) {
34 return validator.isInt('' + value)
35}
36
e34c85e5
C
37function isVideoUrlValid (value: string) {
38 return isActivityPubUrlValid(value)
39}
40
69818c93 41function isVideoLicenceValid (value: number) {
65fcc311 42 return VIDEO_LICENCES[value] !== undefined
6f0c39e2
C
43}
44
fd45e8f4
C
45function isVideoPrivacyValid (value: string) {
46 return VIDEO_PRIVACIES[value] !== undefined
47}
48
49// Maybe we don't know the remote privacy setting, but that doesn't matter
50function isRemoteVideoPrivacyValid (value: string) {
51 return validator.isInt('' + value)
52}
53
51c443db
C
54// Maybe we don't know the remote licence, but that doesn't matter
55function isRemoteVideoLicenceValid (value: string) {
56 return validator.isInt('' + value)
57}
58
69818c93 59function isVideoLanguageValid (value: number) {
65fcc311 60 return value === null || VIDEO_LANGUAGES[value] !== undefined
3092476e
C
61}
62
51c443db
C
63// Maybe we don't know the remote language, but that doesn't matter
64function isRemoteVideoLanguageValid (value: string) {
65 return validator.isInt('' + value)
66}
67
69818c93
C
68function isVideoNSFWValid (value: any) {
69 return typeof value === 'boolean' || (typeof value === 'string' && validator.isBoolean(value))
31b59b47
C
70}
71
8e10cf1a
C
72function isVideoDurationValid (value: string) {
73 return exists(value) && validator.isInt(value + '', VIDEOS_CONSTRAINTS_FIELDS.DURATION)
74}
75
9567011b
C
76function isVideoTruncatedDescriptionValid (value: string) {
77 return exists(value) && validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.TRUNCATED_DESCRIPTION)
78}
79
69818c93
C
80function isVideoDescriptionValid (value: string) {
81 return exists(value) && validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.DESCRIPTION)
be587647
C
82}
83
69818c93
C
84function isVideoNameValid (value: string) {
85 return exists(value) && validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.NAME)
be587647
C
86}
87
0d0e8dd0
C
88function isVideoTagValid (tag: string) {
89 return exists(tag) && validator.isLength(tag, VIDEOS_CONSTRAINTS_FIELDS.TAG)
90}
91
69818c93 92function isVideoTagsValid (tags: string[]) {
65fcc311 93 return isArray(tags) &&
69818c93 94 validator.isInt(tags.length.toString(), VIDEOS_CONSTRAINTS_FIELDS.TAGS) &&
0d0e8dd0 95 tags.every(tag => isVideoTagValid(tag))
be587647
C
96}
97
69818c93
C
98function isVideoThumbnailValid (value: string) {
99 return exists(value) && validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.THUMBNAIL)
aaf61f38
C
100}
101
69818c93
C
102function isVideoThumbnailDataValid (value: string) {
103 return exists(value) && validator.isByteLength(value, VIDEOS_CONSTRAINTS_FIELDS.THUMBNAIL_DATA)
be587647
C
104}
105
69818c93
C
106function isVideoAbuseReasonValid (value: string) {
107 return exists(value) && validator.isLength(value, VIDEO_ABUSES_CONSTRAINTS_FIELDS.REASON)
e4c55619
C
108}
109
69818c93
C
110function isVideoViewsValid (value: string) {
111 return exists(value) && validator.isInt(value + '', VIDEOS_CONSTRAINTS_FIELDS.VIEWS)
9e167724
C
112}
113
69818c93
C
114function isVideoLikesValid (value: string) {
115 return exists(value) && validator.isInt(value + '', VIDEOS_CONSTRAINTS_FIELDS.LIKES)
9e167724
C
116}
117
69818c93
C
118function isVideoDislikesValid (value: string) {
119 return exists(value) && validator.isInt(value + '', VIDEOS_CONSTRAINTS_FIELDS.DISLIKES)
e4c87ec2
C
120}
121
69818c93
C
122function isVideoEventCountValid (value: string) {
123 return exists(value) && validator.isInt(value + '', VIDEO_EVENTS_CONSTRAINTS_FIELDS.COUNT)
9e167724
C
124}
125
69818c93 126function isVideoRatingTypeValid (value: string) {
ee9e7b61 127 return values(VIDEO_RATE_TYPES).indexOf(value as VideoRateType) !== -1
d38b8281
C
128}
129
b60e5f38 130function isVideoFile (files: { [ fieldname: string ]: Express.Multer.File[] } | Express.Multer.File[]) {
f6f7dfee
C
131 // Should have files
132 if (!files) return false
b60e5f38 133 if (isArray(files)) return false
f6f7dfee
C
134
135 // Should have videofile file
b60e5f38 136 const videofile = files['videofile']
f6f7dfee
C
137 if (!videofile || videofile.length === 0) return false
138
139 // The file should exist
140 const file = videofile[0]
141 if (!file || !file.originalname) return false
142
143 return new RegExp('^video/(webm|mp4|ogg)$', 'i').test(file.mimetype)
144}
145
93e1258c
C
146function isVideoFileSizeValid (value: string) {
147 return exists(value) && validator.isInt(value + '', VIDEOS_CONSTRAINTS_FIELDS.FILE_SIZE)
148}
149
150function isVideoFileResolutionValid (value: string) {
14d3270f 151 return exists(value) && validator.isInt(value + '')
93e1258c
C
152}
153
154function isVideoFileExtnameValid (value: string) {
155 return VIDEOS_CONSTRAINTS_FIELDS.EXTNAME.indexOf(value) !== -1
156}
157
158function isVideoFileInfoHashValid (value: string) {
159 return exists(value) && validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.INFO_HASH)
160}
161
35bf0c83
C
162function checkVideoExists (id: string, res: express.Response, callback: () => void) {
163 let promise: Promise<VideoInstance>
164 if (validator.isInt(id)) {
60862425 165 promise = db.Video.loadAndPopulateAccountAndServerAndTags(+id)
35bf0c83 166 } else { // UUID
60862425 167 promise = db.Video.loadByUUIDAndPopulateAccountAndServerAndTags(id)
35bf0c83
C
168 }
169
170 promise.then(video => {
171 if (!video) {
172 return res.status(404)
173 .json({ error: 'Video not found' })
174 .end()
175 }
176
177 res.locals.video = video
178 callback()
179 })
180 .catch(err => {
181 logger.error('Error in video request validator.', err)
182 return res.sendStatus(500)
183 })
184}
185
55fa55a9
C
186// ---------------------------------------------------------------------------
187
65fcc311 188export {
65fcc311
C
189 isVideoCategoryValid,
190 isVideoLicenceValid,
191 isVideoLanguageValid,
192 isVideoNSFWValid,
9567011b 193 isVideoTruncatedDescriptionValid,
65fcc311 194 isVideoDescriptionValid,
93e1258c 195 isVideoFileInfoHashValid,
65fcc311
C
196 isVideoNameValid,
197 isVideoTagsValid,
198 isVideoThumbnailValid,
199 isVideoThumbnailDataValid,
93e1258c 200 isVideoFileExtnameValid,
65fcc311 201 isVideoAbuseReasonValid,
65fcc311
C
202 isVideoFile,
203 isVideoViewsValid,
204 isVideoLikesValid,
205 isVideoRatingTypeValid,
206 isVideoDislikesValid,
93e1258c
C
207 isVideoEventCountValid,
208 isVideoFileSizeValid,
fd45e8f4
C
209 isVideoPrivacyValid,
210 isRemoteVideoPrivacyValid,
8e10cf1a 211 isVideoDurationValid,
35bf0c83 212 isVideoFileResolutionValid,
51c443db 213 checkVideoExists,
0d0e8dd0 214 isVideoTagValid,
51c443db
C
215 isRemoteVideoCategoryValid,
216 isRemoteVideoLicenceValid,
e34c85e5 217 isVideoUrlValid,
51c443db 218 isRemoteVideoLanguageValid
65fcc311 219}