]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blob - server/helpers/custom-validators/videos.ts
27635462608e6db2d1927e67b7c713fa38671f14
[github/Chocobozzz/PeerTube.git] / server / helpers / custom-validators / videos.ts
1 import * as Bluebird from 'bluebird'
2 import { Response } from 'express'
3 import 'express-validator'
4 import { values } from 'lodash'
5 import 'multer'
6 import * as validator from 'validator'
7 import { VideoRateType } from '../../../shared'
8 import { CONSTRAINTS_FIELDS, VIDEO_CATEGORIES, VIDEO_LANGUAGES, VIDEO_LICENCES, VIDEO_RATE_TYPES } from '../../initializers'
9 import { database as db } from '../../initializers/database'
10 import { VideoInstance } from '../../models/video/video-interface'
11 import { logger } from '../logger'
12 import { isActivityPubUrlValid } from './activitypub/misc'
13 import { exists, isArray } from './misc'
14 import { VIDEO_PRIVACIES } from '../../initializers/constants'
15
16 const VIDEOS_CONSTRAINTS_FIELDS = CONSTRAINTS_FIELDS.VIDEOS
17 const VIDEO_ABUSES_CONSTRAINTS_FIELDS = CONSTRAINTS_FIELDS.VIDEO_ABUSES
18
19 function isVideoCategoryValid (value: number) {
20 return VIDEO_CATEGORIES[value] !== undefined
21 }
22
23 function isVideoUrlValid (value: string) {
24 return isActivityPubUrlValid(value)
25 }
26
27 function isVideoLicenceValid (value: number) {
28 return VIDEO_LICENCES[value] !== undefined
29 }
30
31 function isVideoLanguageValid (value: number) {
32 return value === null || VIDEO_LANGUAGES[value] !== undefined
33 }
34
35 function isVideoNSFWValid (value: any) {
36 return typeof value === 'boolean' || (typeof value === 'string' && validator.isBoolean(value))
37 }
38
39 function isVideoDurationValid (value: string) {
40 return exists(value) && validator.isInt(value + '', VIDEOS_CONSTRAINTS_FIELDS.DURATION)
41 }
42
43 function isVideoTruncatedDescriptionValid (value: string) {
44 return exists(value) && validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.TRUNCATED_DESCRIPTION)
45 }
46
47 function isVideoDescriptionValid (value: string) {
48 return exists(value) && validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.DESCRIPTION)
49 }
50
51 function isVideoNameValid (value: string) {
52 return exists(value) && validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.NAME)
53 }
54
55 function isVideoTagValid (tag: string) {
56 return exists(tag) && validator.isLength(tag, VIDEOS_CONSTRAINTS_FIELDS.TAG)
57 }
58
59 function isVideoTagsValid (tags: string[]) {
60 return isArray(tags) &&
61 validator.isInt(tags.length.toString(), VIDEOS_CONSTRAINTS_FIELDS.TAGS) &&
62 tags.every(tag => isVideoTagValid(tag))
63 }
64
65 function isVideoAbuseReasonValid (value: string) {
66 return exists(value) && validator.isLength(value, VIDEO_ABUSES_CONSTRAINTS_FIELDS.REASON)
67 }
68
69 function isVideoViewsValid (value: string) {
70 return exists(value) && validator.isInt(value + '', VIDEOS_CONSTRAINTS_FIELDS.VIEWS)
71 }
72
73 function isVideoRatingTypeValid (value: string) {
74 return values(VIDEO_RATE_TYPES).indexOf(value as VideoRateType) !== -1
75 }
76
77 function isVideoFile (files: { [ fieldname: string ]: Express.Multer.File[] } | Express.Multer.File[]) {
78 // Should have files
79 if (!files) return false
80 if (isArray(files)) return false
81
82 // Should have videofile file
83 const videofile = files['videofile']
84 if (!videofile || videofile.length === 0) return false
85
86 // The file should exist
87 const file = videofile[0]
88 if (!file || !file.originalname) return false
89
90 return new RegExp('^video/(webm|mp4|ogg)$', 'i').test(file.mimetype)
91 }
92
93 function isVideoPrivacyValid (value: string) {
94 return VIDEO_PRIVACIES[value] !== undefined
95 }
96
97 function isVideoFileInfoHashValid (value: string) {
98 return exists(value) && validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.INFO_HASH)
99 }
100
101 function isVideoFileResolutionValid (value: string) {
102 return exists(value) && validator.isInt(value + '')
103 }
104
105 function isVideoFileSizeValid (value: string) {
106 return exists(value) && validator.isInt(value + '', VIDEOS_CONSTRAINTS_FIELDS.FILE_SIZE)
107 }
108
109 function checkVideoExists (id: string, res: Response, callback: () => void) {
110 let promise: Bluebird<VideoInstance>
111 if (validator.isInt(id)) {
112 promise = db.Video.loadAndPopulateAccountAndServerAndTags(+id)
113 } else { // UUID
114 promise = db.Video.loadByUUIDAndPopulateAccountAndServerAndTags(id)
115 }
116
117 promise.then(video => {
118 if (!video) {
119 return res.status(404)
120 .json({ error: 'Video not found' })
121 .end()
122 }
123
124 res.locals.video = video
125 callback()
126 })
127 .catch(err => {
128 logger.error('Error in video request validator.', err)
129 return res.sendStatus(500)
130 })
131 }
132
133 async function isVideoExistsPromise (id: string, res: Response) {
134 let video: VideoInstance
135
136 if (validator.isInt(id)) {
137 video = await db.Video.loadAndPopulateAccountAndServerAndTags(+id)
138 } else { // UUID
139 video = await db.Video.loadByUUIDAndPopulateAccountAndServerAndTags(id)
140 }
141
142 if (!video) {
143 res.status(404)
144 .json({ error: 'Video not found' })
145 .end()
146
147 return false
148 }
149
150 res.locals.video = video
151 return true
152 }
153
154 // ---------------------------------------------------------------------------
155
156 export {
157 isVideoCategoryValid,
158 isVideoLicenceValid,
159 isVideoLanguageValid,
160 isVideoNSFWValid,
161 isVideoTruncatedDescriptionValid,
162 isVideoDescriptionValid,
163 isVideoFileInfoHashValid,
164 isVideoNameValid,
165 isVideoTagsValid,
166 isVideoAbuseReasonValid,
167 isVideoFile,
168 isVideoViewsValid,
169 isVideoRatingTypeValid,
170 isVideoDurationValid,
171 isVideoTagValid,
172 isVideoUrlValid,
173 isVideoPrivacyValid,
174 isVideoFileResolutionValid,
175 isVideoFileSizeValid,
176 checkVideoExists,
177 isVideoExistsPromise
178 }