Move models to typescript-sequelize
[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,
12   VIDEO_PRIVACIES,
13   VIDEO_RATE_TYPES
14 } from '../../initializers'
15 import { VideoModel } from '../../models/video/video'
16 import { exists, isArray } 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 isVideoNSFWValid (value: any) {
34   return typeof value === 'boolean' || (typeof value === 'string' && validator.isBoolean(value))
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 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 values(VIDEO_RATE_TYPES).indexOf(value as VideoRateType) !== -1
73 }
74
75 function isVideoFile (files: { [ fieldname: string ]: Express.Multer.File[] } | Express.Multer.File[]) {
76   // Should have files
77   if (!files) return false
78   if (isArray(files)) return false
79
80   // Should have videofile file
81   const videofile = files['videofile']
82   if (!videofile || videofile.length === 0) return false
83
84   // The file should exist
85   const file = videofile[0]
86   if (!file || !file.originalname) return false
87
88   return new RegExp('^video/(webm|mp4|ogg)$', 'i').test(file.mimetype)
89 }
90
91 function isVideoPrivacyValid (value: string) {
92   return validator.isInt(value + '') && VIDEO_PRIVACIES[value] !== undefined
93 }
94
95 function isVideoFileInfoHashValid (value: string) {
96   return exists(value) && validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.INFO_HASH)
97 }
98
99 function isVideoFileResolutionValid (value: string) {
100   return exists(value) && validator.isInt(value + '')
101 }
102
103 function isVideoFileSizeValid (value: string) {
104   return exists(value) && validator.isInt(value + '', VIDEOS_CONSTRAINTS_FIELDS.FILE_SIZE)
105 }
106
107 async function isVideoExist (id: string, res: Response) {
108   let video: VideoModel
109
110   if (validator.isInt(id)) {
111     video = await VideoModel.loadAndPopulateAccountAndServerAndTags(+id)
112   } else { // UUID
113     video = await VideoModel.loadByUUIDAndPopulateAccountAndServerAndTags(id)
114   }
115
116   if (!video) {
117     res.status(404)
118       .json({ error: 'Video not found' })
119       .end()
120
121     return false
122   }
123
124   res.locals.video = video
125   return true
126 }
127
128 // ---------------------------------------------------------------------------
129
130 export {
131   isVideoCategoryValid,
132   isVideoLicenceValid,
133   isVideoLanguageValid,
134   isVideoNSFWValid,
135   isVideoTruncatedDescriptionValid,
136   isVideoDescriptionValid,
137   isVideoFileInfoHashValid,
138   isVideoNameValid,
139   isVideoTagsValid,
140   isVideoAbuseReasonValid,
141   isVideoFile,
142   isVideoViewsValid,
143   isVideoRatingTypeValid,
144   isVideoDurationValid,
145   isVideoTagValid,
146   isVideoPrivacyValid,
147   isVideoFileResolutionValid,
148   isVideoFileSizeValid,
149   isVideoExist
150 }