Update the api documentation
[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 isVideoLanguageValid (value: number) {
30   return value === null || VIDEO_LANGUAGES[value] !== undefined
31 }
32
33 function isVideoDurationValid (value: string) {
34   return exists(value) && validator.isInt(value + '', VIDEOS_CONSTRAINTS_FIELDS.DURATION)
35 }
36
37 function isVideoTruncatedDescriptionValid (value: string) {
38   return exists(value) && validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.TRUNCATED_DESCRIPTION)
39 }
40
41 function isVideoDescriptionValid (value: string) {
42   return value === null || (exists(value) && validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.DESCRIPTION))
43 }
44
45 function isVideoSupportValid (value: string) {
46   return value === null || (exists(value) && validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.SUPPORT))
47 }
48
49 function isVideoNameValid (value: string) {
50   return exists(value) && validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.NAME)
51 }
52
53 function isVideoTagValid (tag: string) {
54   return exists(tag) && validator.isLength(tag, VIDEOS_CONSTRAINTS_FIELDS.TAG)
55 }
56
57 function isVideoTagsValid (tags: string[]) {
58   return isArray(tags) &&
59          validator.isInt(tags.length.toString(), VIDEOS_CONSTRAINTS_FIELDS.TAGS) &&
60          tags.every(tag => isVideoTagValid(tag))
61 }
62
63 function isVideoAbuseReasonValid (value: string) {
64   return exists(value) && validator.isLength(value, VIDEO_ABUSES_CONSTRAINTS_FIELDS.REASON)
65 }
66
67 function isVideoViewsValid (value: string) {
68   return exists(value) && validator.isInt(value + '', VIDEOS_CONSTRAINTS_FIELDS.VIEWS)
69 }
70
71 function isVideoRatingTypeValid (value: string) {
72   return value === 'none' || values(VIDEO_RATE_TYPES).indexOf(value as VideoRateType) !== -1
73 }
74
75 const videoFileTypes = Object.keys(VIDEO_MIMETYPE_EXT).map(m => `(${m})`)
76 const videoFileTypesRegex = videoFileTypes.join('|')
77 function isVideoFile (files: { [ fieldname: string ]: Express.Multer.File[] } | Express.Multer.File[]) {
78   return isFileValid(files, videoFileTypesRegex, 'videofile')
79 }
80
81 const videoImageTypes = CONSTRAINTS_FIELDS.VIDEOS.IMAGE.EXTNAME
82   .map(v => v.replace('.', ''))
83   .join('|')
84 const videoImageTypesRegex = `image/(${videoImageTypes})`
85 function isVideoImage (files: { [ fieldname: string ]: Express.Multer.File[] } | Express.Multer.File[], field: string) {
86   return isFileValid(files, videoImageTypesRegex, field, true)
87 }
88
89 function isVideoPrivacyValid (value: string) {
90   return validator.isInt(value + '') && VIDEO_PRIVACIES[value] !== undefined
91 }
92
93 function isVideoFileInfoHashValid (value: string) {
94   return exists(value) && validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.INFO_HASH)
95 }
96
97 function isVideoFileResolutionValid (value: string) {
98   return exists(value) && validator.isInt(value + '')
99 }
100
101 function isVideoFileSizeValid (value: string) {
102   return exists(value) && validator.isInt(value + '', VIDEOS_CONSTRAINTS_FIELDS.FILE_SIZE)
103 }
104
105 async function isVideoExist (id: string, res: Response) {
106   let video: VideoModel
107
108   if (validator.isInt(id)) {
109     video = await VideoModel.loadAndPopulateAccountAndServerAndTags(+id)
110   } else { // UUID
111     video = await VideoModel.loadByUUIDAndPopulateAccountAndServerAndTags(id)
112   }
113
114   if (!video) {
115     res.status(404)
116       .json({ error: 'Video not found' })
117       .end()
118
119     return false
120   }
121
122   res.locals.video = video
123   return true
124 }
125
126 // ---------------------------------------------------------------------------
127
128 export {
129   isVideoCategoryValid,
130   isVideoLicenceValid,
131   isVideoLanguageValid,
132   isVideoTruncatedDescriptionValid,
133   isVideoDescriptionValid,
134   isVideoFileInfoHashValid,
135   isVideoNameValid,
136   isVideoTagsValid,
137   isVideoAbuseReasonValid,
138   isVideoFile,
139   isVideoViewsValid,
140   isVideoRatingTypeValid,
141   isVideoDurationValid,
142   isVideoTagValid,
143   isVideoPrivacyValid,
144   isVideoFileResolutionValid,
145   isVideoFileSizeValid,
146   isVideoExist,
147   isVideoImage,
148   isVideoSupportValid
149 }