c08ddd24ea4e9e8187007a08a7276b170ddf9ed9
[oweals/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 { VideoRateType } from '../../../shared'
7 import {
8   CONSTRAINTS_FIELDS,
9   VIDEO_CATEGORIES,
10   VIDEO_LANGUAGES,
11   VIDEO_LICENCES, VIDEO_MIMETYPE_EXT,
12   VIDEO_PRIVACIES,
13   VIDEO_RATE_TYPES
14 } from '../../initializers'
15 import { VideoModel } from '../../models/video/video'
16 import { exists, isArray, isFileValid } from './misc'
17
18 const VIDEOS_CONSTRAINTS_FIELDS = CONSTRAINTS_FIELDS.VIDEOS
19 const VIDEO_ABUSES_CONSTRAINTS_FIELDS = CONSTRAINTS_FIELDS.VIDEO_ABUSES
20
21 function isVideoCategoryValid (value: number) {
22   return value === null || VIDEO_CATEGORIES[value] !== undefined
23 }
24
25 function isVideoLicenceValid (value: number) {
26   return value === null || VIDEO_LICENCES[value] !== undefined
27 }
28
29 function areVideoLanguagesValid (value: number[]) {
30   return value === null || (isArray(value) && value.every(v => isVideoLanguageValid(v)))
31 }
32
33 function isVideoLanguageValid (value: number) {
34   return VIDEO_LANGUAGES[value] !== undefined
35 }
36
37 function isVideoDurationValid (value: string) {
38   return exists(value) && validator.isInt(value + '', VIDEOS_CONSTRAINTS_FIELDS.DURATION)
39 }
40
41 function isVideoTruncatedDescriptionValid (value: string) {
42   return exists(value) && validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.TRUNCATED_DESCRIPTION)
43 }
44
45 function isVideoDescriptionValid (value: string) {
46   return value === null || (exists(value) && validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.DESCRIPTION))
47 }
48
49 function isVideoSupportValid (value: string) {
50   return value === null || (exists(value) && validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.SUPPORT))
51 }
52
53 function isVideoNameValid (value: string) {
54   return exists(value) && validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.NAME)
55 }
56
57 function isVideoTagValid (tag: string) {
58   return exists(tag) && validator.isLength(tag, VIDEOS_CONSTRAINTS_FIELDS.TAG)
59 }
60
61 function isVideoTagsValid (tags: string[]) {
62   return isArray(tags) &&
63          validator.isInt(tags.length.toString(), VIDEOS_CONSTRAINTS_FIELDS.TAGS) &&
64          tags.every(tag => isVideoTagValid(tag))
65 }
66
67 function isVideoAbuseReasonValid (value: string) {
68   return exists(value) && validator.isLength(value, VIDEO_ABUSES_CONSTRAINTS_FIELDS.REASON)
69 }
70
71 function isVideoViewsValid (value: string) {
72   return exists(value) && validator.isInt(value + '', VIDEOS_CONSTRAINTS_FIELDS.VIEWS)
73 }
74
75 function isVideoRatingTypeValid (value: string) {
76   return value === 'none' || values(VIDEO_RATE_TYPES).indexOf(value as VideoRateType) !== -1
77 }
78
79 const videoFileTypes = Object.keys(VIDEO_MIMETYPE_EXT).map(m => `(${m})`)
80 const videoFileTypesRegex = videoFileTypes.join('|')
81 function isVideoFile (files: { [ fieldname: string ]: Express.Multer.File[] } | Express.Multer.File[]) {
82   return isFileValid(files, videoFileTypesRegex, 'videofile')
83 }
84
85 const videoImageTypes = CONSTRAINTS_FIELDS.VIDEOS.IMAGE.EXTNAME
86   .map(v => v.replace('.', ''))
87   .join('|')
88 const videoImageTypesRegex = `image/(${videoImageTypes})`
89 function isVideoImage (files: { [ fieldname: string ]: Express.Multer.File[] } | Express.Multer.File[], field: string) {
90   return isFileValid(files, videoImageTypesRegex, field, true)
91 }
92
93 function isVideoPrivacyValid (value: string) {
94   return validator.isInt(value + '') && 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 async function isVideoExist (id: string, res: Response) {
110   let video: VideoModel
111
112   if (validator.isInt(id)) {
113     video = await VideoModel.loadAndPopulateAccountAndServerAndTags(+id)
114   } else { // UUID
115     video = await VideoModel.loadByUUIDAndPopulateAccountAndServerAndTags(id)
116   }
117
118   if (!video) {
119     res.status(404)
120       .json({ error: 'Video not found' })
121       .end()
122
123     return false
124   }
125
126   res.locals.video = video
127   return true
128 }
129
130 // ---------------------------------------------------------------------------
131
132 export {
133   isVideoCategoryValid,
134   isVideoLicenceValid,
135   isVideoLanguageValid,
136   isVideoTruncatedDescriptionValid,
137   isVideoDescriptionValid,
138   isVideoFileInfoHashValid,
139   isVideoNameValid,
140   areVideoLanguagesValid,
141   isVideoTagsValid,
142   isVideoAbuseReasonValid,
143   isVideoFile,
144   isVideoViewsValid,
145   isVideoRatingTypeValid,
146   isVideoDurationValid,
147   isVideoTagValid,
148   isVideoPrivacyValid,
149   isVideoFileResolutionValid,
150   isVideoFileSizeValid,
151   isVideoExist,
152   isVideoImage,
153   isVideoSupportValid
154 }