]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blame - server/helpers/custom-validators/videos.ts
Rename Pod -> Server
[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
9567011b
C
72function isVideoTruncatedDescriptionValid (value: string) {
73 return exists(value) && validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.TRUNCATED_DESCRIPTION)
74}
75
69818c93
C
76function isVideoDescriptionValid (value: string) {
77 return exists(value) && validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.DESCRIPTION)
be587647
C
78}
79
69818c93 80function isVideoDurationValid (value: string) {
0d0e8dd0
C
81 // https://www.w3.org/TR/activitystreams-vocabulary/#dfn-duration
82 return exists(value) &&
83 typeof value === 'string' &&
84 value.startsWith('PT') &&
85 value.endsWith('S') &&
86 validator.isInt(value.replace(/[^0-9]+/, ''), VIDEOS_CONSTRAINTS_FIELDS.DURATION)
be587647
C
87}
88
69818c93
C
89function isVideoNameValid (value: string) {
90 return exists(value) && validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.NAME)
be587647
C
91}
92
0d0e8dd0
C
93function isVideoTagValid (tag: string) {
94 return exists(tag) && validator.isLength(tag, VIDEOS_CONSTRAINTS_FIELDS.TAG)
95}
96
69818c93 97function isVideoTagsValid (tags: string[]) {
65fcc311 98 return isArray(tags) &&
69818c93 99 validator.isInt(tags.length.toString(), VIDEOS_CONSTRAINTS_FIELDS.TAGS) &&
0d0e8dd0 100 tags.every(tag => isVideoTagValid(tag))
be587647
C
101}
102
69818c93
C
103function isVideoThumbnailValid (value: string) {
104 return exists(value) && validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.THUMBNAIL)
aaf61f38
C
105}
106
69818c93
C
107function isVideoThumbnailDataValid (value: string) {
108 return exists(value) && validator.isByteLength(value, VIDEOS_CONSTRAINTS_FIELDS.THUMBNAIL_DATA)
be587647
C
109}
110
69818c93
C
111function isVideoAbuseReasonValid (value: string) {
112 return exists(value) && validator.isLength(value, VIDEO_ABUSES_CONSTRAINTS_FIELDS.REASON)
e4c55619
C
113}
114
69818c93 115function isVideoAbuseReporterUsernameValid (value: string) {
65fcc311 116 return isUserUsernameValid(value)
3d118fb5
C
117}
118
69818c93
C
119function isVideoViewsValid (value: string) {
120 return exists(value) && validator.isInt(value + '', VIDEOS_CONSTRAINTS_FIELDS.VIEWS)
9e167724
C
121}
122
69818c93
C
123function isVideoLikesValid (value: string) {
124 return exists(value) && validator.isInt(value + '', VIDEOS_CONSTRAINTS_FIELDS.LIKES)
9e167724
C
125}
126
69818c93
C
127function isVideoDislikesValid (value: string) {
128 return exists(value) && validator.isInt(value + '', VIDEOS_CONSTRAINTS_FIELDS.DISLIKES)
e4c87ec2
C
129}
130
69818c93
C
131function isVideoEventCountValid (value: string) {
132 return exists(value) && validator.isInt(value + '', VIDEO_EVENTS_CONSTRAINTS_FIELDS.COUNT)
9e167724
C
133}
134
69818c93 135function isVideoRatingTypeValid (value: string) {
ee9e7b61 136 return values(VIDEO_RATE_TYPES).indexOf(value as VideoRateType) !== -1
d38b8281
C
137}
138
b60e5f38 139function isVideoFile (files: { [ fieldname: string ]: Express.Multer.File[] } | Express.Multer.File[]) {
f6f7dfee
C
140 // Should have files
141 if (!files) return false
b60e5f38 142 if (isArray(files)) return false
f6f7dfee
C
143
144 // Should have videofile file
b60e5f38 145 const videofile = files['videofile']
f6f7dfee
C
146 if (!videofile || videofile.length === 0) return false
147
148 // The file should exist
149 const file = videofile[0]
150 if (!file || !file.originalname) return false
151
152 return new RegExp('^video/(webm|mp4|ogg)$', 'i').test(file.mimetype)
153}
154
93e1258c
C
155function isVideoFileSizeValid (value: string) {
156 return exists(value) && validator.isInt(value + '', VIDEOS_CONSTRAINTS_FIELDS.FILE_SIZE)
157}
158
159function isVideoFileResolutionValid (value: string) {
14d3270f 160 return exists(value) && validator.isInt(value + '')
93e1258c
C
161}
162
163function isVideoFileExtnameValid (value: string) {
164 return VIDEOS_CONSTRAINTS_FIELDS.EXTNAME.indexOf(value) !== -1
165}
166
167function isVideoFileInfoHashValid (value: string) {
168 return exists(value) && validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.INFO_HASH)
169}
170
35bf0c83
C
171function checkVideoExists (id: string, res: express.Response, callback: () => void) {
172 let promise: Promise<VideoInstance>
173 if (validator.isInt(id)) {
60862425 174 promise = db.Video.loadAndPopulateAccountAndServerAndTags(+id)
35bf0c83 175 } else { // UUID
60862425 176 promise = db.Video.loadByUUIDAndPopulateAccountAndServerAndTags(id)
35bf0c83
C
177 }
178
179 promise.then(video => {
180 if (!video) {
181 return res.status(404)
182 .json({ error: 'Video not found' })
183 .end()
184 }
185
186 res.locals.video = video
187 callback()
188 })
189 .catch(err => {
190 logger.error('Error in video request validator.', err)
191 return res.sendStatus(500)
192 })
193}
194
55fa55a9
C
195// ---------------------------------------------------------------------------
196
65fcc311 197export {
65fcc311
C
198 isVideoCategoryValid,
199 isVideoLicenceValid,
200 isVideoLanguageValid,
201 isVideoNSFWValid,
9567011b 202 isVideoTruncatedDescriptionValid,
65fcc311
C
203 isVideoDescriptionValid,
204 isVideoDurationValid,
93e1258c 205 isVideoFileInfoHashValid,
65fcc311
C
206 isVideoNameValid,
207 isVideoTagsValid,
208 isVideoThumbnailValid,
209 isVideoThumbnailDataValid,
93e1258c 210 isVideoFileExtnameValid,
65fcc311
C
211 isVideoAbuseReasonValid,
212 isVideoAbuseReporterUsernameValid,
213 isVideoFile,
214 isVideoViewsValid,
215 isVideoLikesValid,
216 isVideoRatingTypeValid,
217 isVideoDislikesValid,
93e1258c
C
218 isVideoEventCountValid,
219 isVideoFileSizeValid,
fd45e8f4
C
220 isVideoPrivacyValid,
221 isRemoteVideoPrivacyValid,
35bf0c83 222 isVideoFileResolutionValid,
51c443db 223 checkVideoExists,
0d0e8dd0 224 isVideoTagValid,
51c443db
C
225 isRemoteVideoCategoryValid,
226 isRemoteVideoLicenceValid,
e34c85e5 227 isVideoUrlValid,
51c443db 228 isRemoteVideoLanguageValid
65fcc311 229}