Finish admin design
[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 { CONSTRAINTS_FIELDS, VIDEO_CATEGORIES, VIDEO_LANGUAGES, VIDEO_LICENCES, VIDEO_RATE_TYPES } from '../../initializers'
8 import { VIDEO_PRIVACIES } from '../../initializers/constants'
9 import { database as db } from '../../initializers/database'
10 import { VideoInstance } from '../../models/video/video-interface'
11 import { exists, isArray } from './misc'
12 import isInt = require('validator/lib/isInt')
13
14 const VIDEOS_CONSTRAINTS_FIELDS = CONSTRAINTS_FIELDS.VIDEOS
15 const VIDEO_ABUSES_CONSTRAINTS_FIELDS = CONSTRAINTS_FIELDS.VIDEO_ABUSES
16
17 function isVideoCategoryValid (value: number) {
18   return value === null || VIDEO_CATEGORIES[value] !== undefined
19 }
20
21 function isVideoLicenceValid (value: number) {
22   return value === null || VIDEO_LICENCES[value] !== undefined
23 }
24
25 function isVideoLanguageValid (value: number) {
26   return value === null || VIDEO_LANGUAGES[value] !== undefined
27 }
28
29 function isVideoNSFWValid (value: any) {
30   return typeof value === 'boolean' || (typeof value === 'string' && validator.isBoolean(value))
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 isVideoNameValid (value: string) {
46   return exists(value) && validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.NAME)
47 }
48
49 function isVideoTagValid (tag: string) {
50   return exists(tag) && validator.isLength(tag, VIDEOS_CONSTRAINTS_FIELDS.TAG)
51 }
52
53 function isVideoTagsValid (tags: string[]) {
54   return isArray(tags) &&
55          validator.isInt(tags.length.toString(), VIDEOS_CONSTRAINTS_FIELDS.TAGS) &&
56          tags.every(tag => isVideoTagValid(tag))
57 }
58
59 function isVideoAbuseReasonValid (value: string) {
60   return exists(value) && validator.isLength(value, VIDEO_ABUSES_CONSTRAINTS_FIELDS.REASON)
61 }
62
63 function isVideoViewsValid (value: string) {
64   return exists(value) && validator.isInt(value + '', VIDEOS_CONSTRAINTS_FIELDS.VIEWS)
65 }
66
67 function isVideoRatingTypeValid (value: string) {
68   return values(VIDEO_RATE_TYPES).indexOf(value as VideoRateType) !== -1
69 }
70
71 function isVideoFile (files: { [ fieldname: string ]: Express.Multer.File[] } | Express.Multer.File[]) {
72   // Should have files
73   if (!files) return false
74   if (isArray(files)) return false
75
76   // Should have videofile file
77   const videofile = files['videofile']
78   if (!videofile || videofile.length === 0) return false
79
80   // The file should exist
81   const file = videofile[0]
82   if (!file || !file.originalname) return false
83
84   return new RegExp('^video/(webm|mp4|ogg)$', 'i').test(file.mimetype)
85 }
86
87 function isVideoPrivacyValid (value: string) {
88   return validator.isInt(value + '') && VIDEO_PRIVACIES[value] !== undefined
89 }
90
91 function isVideoFileInfoHashValid (value: string) {
92   return exists(value) && validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.INFO_HASH)
93 }
94
95 function isVideoFileResolutionValid (value: string) {
96   return exists(value) && validator.isInt(value + '')
97 }
98
99 function isVideoFileSizeValid (value: string) {
100   return exists(value) && validator.isInt(value + '', VIDEOS_CONSTRAINTS_FIELDS.FILE_SIZE)
101 }
102
103 async function isVideoExist (id: string, res: Response) {
104   let video: VideoInstance
105
106   if (validator.isInt(id)) {
107     video = await db.Video.loadAndPopulateAccountAndServerAndTags(+id)
108   } else { // UUID
109     video = await db.Video.loadByUUIDAndPopulateAccountAndServerAndTags(id)
110   }
111
112   if (!video) {
113     res.status(404)
114       .json({ error: 'Video not found' })
115       .end()
116
117     return false
118   }
119
120   res.locals.video = video
121   return true
122 }
123
124 // ---------------------------------------------------------------------------
125
126 export {
127   isVideoCategoryValid,
128   isVideoLicenceValid,
129   isVideoLanguageValid,
130   isVideoNSFWValid,
131   isVideoTruncatedDescriptionValid,
132   isVideoDescriptionValid,
133   isVideoFileInfoHashValid,
134   isVideoNameValid,
135   isVideoTagsValid,
136   isVideoAbuseReasonValid,
137   isVideoFile,
138   isVideoViewsValid,
139   isVideoRatingTypeValid,
140   isVideoDurationValid,
141   isVideoTagValid,
142   isVideoPrivacyValid,
143   isVideoFileResolutionValid,
144   isVideoFileSizeValid,
145   isVideoExist
146 }