]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blame - server/helpers/custom-validators/videos.ts
Continue activitypub
[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'
65fcc311
C
22
23const VIDEOS_CONSTRAINTS_FIELDS = CONSTRAINTS_FIELDS.VIDEOS
24const VIDEO_ABUSES_CONSTRAINTS_FIELDS = CONSTRAINTS_FIELDS.VIDEO_ABUSES
25const VIDEO_EVENTS_CONSTRAINTS_FIELDS = CONSTRAINTS_FIELDS.VIDEO_EVENTS
0b697522 26
69818c93 27function isVideoCategoryValid (value: number) {
65fcc311 28 return VIDEO_CATEGORIES[value] !== undefined
6e07c3de
C
29}
30
51c443db
C
31// Maybe we don't know the remote category, but that doesn't matter
32function isRemoteVideoCategoryValid (value: string) {
33 return validator.isInt('' + value)
34}
35
69818c93 36function isVideoLicenceValid (value: number) {
65fcc311 37 return VIDEO_LICENCES[value] !== undefined
6f0c39e2
C
38}
39
fd45e8f4
C
40function isVideoPrivacyValid (value: string) {
41 return VIDEO_PRIVACIES[value] !== undefined
42}
43
44// Maybe we don't know the remote privacy setting, but that doesn't matter
45function isRemoteVideoPrivacyValid (value: string) {
46 return validator.isInt('' + value)
47}
48
51c443db
C
49// Maybe we don't know the remote licence, but that doesn't matter
50function isRemoteVideoLicenceValid (value: string) {
51 return validator.isInt('' + value)
52}
53
69818c93 54function isVideoLanguageValid (value: number) {
65fcc311 55 return value === null || VIDEO_LANGUAGES[value] !== undefined
3092476e
C
56}
57
51c443db
C
58// Maybe we don't know the remote language, but that doesn't matter
59function isRemoteVideoLanguageValid (value: string) {
60 return validator.isInt('' + value)
61}
62
69818c93
C
63function isVideoNSFWValid (value: any) {
64 return typeof value === 'boolean' || (typeof value === 'string' && validator.isBoolean(value))
31b59b47
C
65}
66
9567011b
C
67function isVideoTruncatedDescriptionValid (value: string) {
68 return exists(value) && validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.TRUNCATED_DESCRIPTION)
69}
70
69818c93
C
71function isVideoDescriptionValid (value: string) {
72 return exists(value) && validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.DESCRIPTION)
be587647
C
73}
74
69818c93 75function isVideoDurationValid (value: string) {
0d0e8dd0
C
76 // https://www.w3.org/TR/activitystreams-vocabulary/#dfn-duration
77 return exists(value) &&
78 typeof value === 'string' &&
79 value.startsWith('PT') &&
80 value.endsWith('S') &&
81 validator.isInt(value.replace(/[^0-9]+/, ''), VIDEOS_CONSTRAINTS_FIELDS.DURATION)
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 110function isVideoAbuseReporterUsernameValid (value: string) {
65fcc311 111 return isUserUsernameValid(value)
3d118fb5
C
112}
113
69818c93
C
114function isVideoViewsValid (value: string) {
115 return exists(value) && validator.isInt(value + '', VIDEOS_CONSTRAINTS_FIELDS.VIEWS)
9e167724
C
116}
117
69818c93
C
118function isVideoLikesValid (value: string) {
119 return exists(value) && validator.isInt(value + '', VIDEOS_CONSTRAINTS_FIELDS.LIKES)
9e167724
C
120}
121
69818c93
C
122function isVideoDislikesValid (value: string) {
123 return exists(value) && validator.isInt(value + '', VIDEOS_CONSTRAINTS_FIELDS.DISLIKES)
e4c87ec2
C
124}
125
69818c93
C
126function isVideoEventCountValid (value: string) {
127 return exists(value) && validator.isInt(value + '', VIDEO_EVENTS_CONSTRAINTS_FIELDS.COUNT)
9e167724
C
128}
129
69818c93 130function isVideoRatingTypeValid (value: string) {
ee9e7b61 131 return values(VIDEO_RATE_TYPES).indexOf(value as VideoRateType) !== -1
d38b8281
C
132}
133
b60e5f38 134function isVideoFile (files: { [ fieldname: string ]: Express.Multer.File[] } | Express.Multer.File[]) {
f6f7dfee
C
135 // Should have files
136 if (!files) return false
b60e5f38 137 if (isArray(files)) return false
f6f7dfee
C
138
139 // Should have videofile file
b60e5f38 140 const videofile = files['videofile']
f6f7dfee
C
141 if (!videofile || videofile.length === 0) return false
142
143 // The file should exist
144 const file = videofile[0]
145 if (!file || !file.originalname) return false
146
147 return new RegExp('^video/(webm|mp4|ogg)$', 'i').test(file.mimetype)
148}
149
93e1258c
C
150function isVideoFileSizeValid (value: string) {
151 return exists(value) && validator.isInt(value + '', VIDEOS_CONSTRAINTS_FIELDS.FILE_SIZE)
152}
153
154function isVideoFileResolutionValid (value: string) {
14d3270f 155 return exists(value) && validator.isInt(value + '')
93e1258c
C
156}
157
158function isVideoFileExtnameValid (value: string) {
159 return VIDEOS_CONSTRAINTS_FIELDS.EXTNAME.indexOf(value) !== -1
160}
161
162function isVideoFileInfoHashValid (value: string) {
163 return exists(value) && validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.INFO_HASH)
164}
165
35bf0c83
C
166function checkVideoExists (id: string, res: express.Response, callback: () => void) {
167 let promise: Promise<VideoInstance>
168 if (validator.isInt(id)) {
169 promise = db.Video.loadAndPopulateAuthorAndPodAndTags(+id)
170 } else { // UUID
171 promise = db.Video.loadByUUIDAndPopulateAuthorAndPodAndTags(id)
172 }
173
174 promise.then(video => {
175 if (!video) {
176 return res.status(404)
177 .json({ error: 'Video not found' })
178 .end()
179 }
180
181 res.locals.video = video
182 callback()
183 })
184 .catch(err => {
185 logger.error('Error in video request validator.', err)
186 return res.sendStatus(500)
187 })
188}
189
55fa55a9
C
190// ---------------------------------------------------------------------------
191
65fcc311 192export {
65fcc311
C
193 isVideoCategoryValid,
194 isVideoLicenceValid,
195 isVideoLanguageValid,
196 isVideoNSFWValid,
9567011b 197 isVideoTruncatedDescriptionValid,
65fcc311
C
198 isVideoDescriptionValid,
199 isVideoDurationValid,
93e1258c 200 isVideoFileInfoHashValid,
65fcc311
C
201 isVideoNameValid,
202 isVideoTagsValid,
203 isVideoThumbnailValid,
204 isVideoThumbnailDataValid,
93e1258c 205 isVideoFileExtnameValid,
65fcc311
C
206 isVideoAbuseReasonValid,
207 isVideoAbuseReporterUsernameValid,
208 isVideoFile,
209 isVideoViewsValid,
210 isVideoLikesValid,
211 isVideoRatingTypeValid,
212 isVideoDislikesValid,
93e1258c
C
213 isVideoEventCountValid,
214 isVideoFileSizeValid,
fd45e8f4
C
215 isVideoPrivacyValid,
216 isRemoteVideoPrivacyValid,
35bf0c83 217 isVideoFileResolutionValid,
51c443db 218 checkVideoExists,
0d0e8dd0 219 isVideoTagValid,
51c443db
C
220 isRemoteVideoCategoryValid,
221 isRemoteVideoLicenceValid,
222 isRemoteVideoLanguageValid
65fcc311 223}