]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blob - server/middlewares/validators/config.ts
Add option to not transcode original resolution
[github/Chocobozzz/PeerTube.git] / server / middlewares / validators / config.ts
1 import express from 'express'
2 import { body } from 'express-validator'
3 import { isIntOrNull } from '@server/helpers/custom-validators/misc'
4 import { CONFIG, isEmailEnabled } from '@server/initializers/config'
5 import { CustomConfig } from '../../../shared/models/server/custom-config.model'
6 import { isThemeNameValid } from '../../helpers/custom-validators/plugins'
7 import { isUserNSFWPolicyValid, isUserVideoQuotaDailyValid, isUserVideoQuotaValid } from '../../helpers/custom-validators/users'
8 import { logger } from '../../helpers/logger'
9 import { isThemeRegistered } from '../../lib/plugins/theme-utils'
10 import { areValidationErrors } from './shared'
11 import { HttpStatusCode } from '@shared/models/http/http-error-codes'
12
13 const customConfigUpdateValidator = [
14 body('instance.name').exists().withMessage('Should have a valid instance name'),
15 body('instance.shortDescription').exists().withMessage('Should have a valid instance short description'),
16 body('instance.description').exists().withMessage('Should have a valid instance description'),
17 body('instance.terms').exists().withMessage('Should have a valid instance terms'),
18 body('instance.defaultNSFWPolicy').custom(isUserNSFWPolicyValid).withMessage('Should have a valid NSFW policy'),
19 body('instance.defaultClientRoute').exists().withMessage('Should have a valid instance default client route'),
20 body('instance.customizations.css').exists().withMessage('Should have a valid instance CSS customization'),
21 body('instance.customizations.javascript').exists().withMessage('Should have a valid instance JavaScript customization'),
22
23 body('services.twitter.username').exists().withMessage('Should have a valid twitter username'),
24 body('services.twitter.whitelisted').isBoolean().withMessage('Should have a valid twitter whitelisted boolean'),
25
26 body('cache.previews.size').isInt().withMessage('Should have a valid previews cache size'),
27 body('cache.captions.size').isInt().withMessage('Should have a valid captions cache size'),
28 body('cache.torrents.size').isInt().withMessage('Should have a valid torrents cache size'),
29
30 body('signup.enabled').isBoolean().withMessage('Should have a valid signup enabled boolean'),
31 body('signup.limit').isInt().withMessage('Should have a valid signup limit'),
32 body('signup.requiresEmailVerification').isBoolean().withMessage('Should have a valid requiresEmailVerification boolean'),
33 body('signup.minimumAge').isInt().withMessage('Should have a valid minimum age required'),
34
35 body('admin.email').isEmail().withMessage('Should have a valid administrator email'),
36 body('contactForm.enabled').isBoolean().withMessage('Should have a valid contact form enabled boolean'),
37
38 body('user.videoQuota').custom(isUserVideoQuotaValid).withMessage('Should have a valid video quota'),
39 body('user.videoQuotaDaily').custom(isUserVideoQuotaDailyValid).withMessage('Should have a valid daily video quota'),
40
41 body('videoChannels.maxPerUser').isInt().withMessage('Should have a valid maximum amount of video channels per user'),
42
43 body('transcoding.enabled').isBoolean().withMessage('Should have a valid transcoding enabled boolean'),
44 body('transcoding.allowAdditionalExtensions').isBoolean().withMessage('Should have a valid additional extensions boolean'),
45 body('transcoding.threads').isInt().withMessage('Should have a valid transcoding threads number'),
46 body('transcoding.concurrency').isInt({ min: 1 }).withMessage('Should have a valid transcoding concurrency number'),
47 body('transcoding.resolutions.0p').isBoolean().withMessage('Should have a valid transcoding 0p resolution enabled boolean'),
48 body('transcoding.resolutions.144p').isBoolean().withMessage('Should have a valid transcoding 144p resolution enabled boolean'),
49 body('transcoding.resolutions.240p').isBoolean().withMessage('Should have a valid transcoding 240p resolution enabled boolean'),
50 body('transcoding.resolutions.360p').isBoolean().withMessage('Should have a valid transcoding 360p resolution enabled boolean'),
51 body('transcoding.resolutions.480p').isBoolean().withMessage('Should have a valid transcoding 480p resolution enabled boolean'),
52 body('transcoding.resolutions.720p').isBoolean().withMessage('Should have a valid transcoding 720p resolution enabled boolean'),
53 body('transcoding.resolutions.1080p').isBoolean().withMessage('Should have a valid transcoding 1080p resolution enabled boolean'),
54 body('transcoding.resolutions.1440p').isBoolean().withMessage('Should have a valid transcoding 1440p resolution enabled boolean'),
55 body('transcoding.resolutions.2160p').isBoolean().withMessage('Should have a valid transcoding 2160p resolution enabled boolean'),
56
57 body('transcoding.alwaysTranscodeOriginalResolution').isBoolean()
58 .withMessage('Should have a valid always transcode original resolution boolean'),
59
60 body('transcoding.webtorrent.enabled').isBoolean().withMessage('Should have a valid webtorrent transcoding enabled boolean'),
61 body('transcoding.hls.enabled').isBoolean().withMessage('Should have a valid hls transcoding enabled boolean'),
62
63 body('videoStudio.enabled').isBoolean().withMessage('Should have a valid video studio enabled boolean'),
64
65 body('import.videos.concurrency').isInt({ min: 0 }).withMessage('Should have a valid import concurrency number'),
66 body('import.videos.http.enabled').isBoolean().withMessage('Should have a valid import video http enabled boolean'),
67 body('import.videos.torrent.enabled').isBoolean().withMessage('Should have a valid import video torrent enabled boolean'),
68
69 body('trending.videos.algorithms.default').exists().withMessage('Should have a valid default trending algorithm'),
70 body('trending.videos.algorithms.enabled').exists().withMessage('Should have a valid array of enabled trending algorithms'),
71
72 body('followers.instance.enabled').isBoolean().withMessage('Should have a valid followers of instance boolean'),
73 body('followers.instance.manualApproval').isBoolean().withMessage('Should have a valid manual approval boolean'),
74
75 body('theme.default').custom(v => isThemeNameValid(v) && isThemeRegistered(v)).withMessage('Should have a valid theme'),
76
77 body('broadcastMessage.enabled').isBoolean().withMessage('Should have a valid broadcast message enabled boolean'),
78 body('broadcastMessage.message').exists().withMessage('Should have a valid broadcast message'),
79 body('broadcastMessage.level').exists().withMessage('Should have a valid broadcast level'),
80 body('broadcastMessage.dismissable').isBoolean().withMessage('Should have a valid broadcast dismissable boolean'),
81
82 body('live.enabled').isBoolean().withMessage('Should have a valid live enabled boolean'),
83 body('live.allowReplay').isBoolean().withMessage('Should have a valid live allow replay boolean'),
84 body('live.maxDuration').isInt().withMessage('Should have a valid live max duration'),
85 body('live.maxInstanceLives').custom(isIntOrNull).withMessage('Should have a valid max instance lives'),
86 body('live.maxUserLives').custom(isIntOrNull).withMessage('Should have a valid max user lives'),
87 body('live.transcoding.enabled').isBoolean().withMessage('Should have a valid live transcoding enabled boolean'),
88 body('live.transcoding.threads').isInt().withMessage('Should have a valid live transcoding threads'),
89 body('live.transcoding.resolutions.144p').isBoolean().withMessage('Should have a valid transcoding 144p resolution enabled boolean'),
90 body('live.transcoding.resolutions.240p').isBoolean().withMessage('Should have a valid transcoding 240p resolution enabled boolean'),
91 body('live.transcoding.resolutions.360p').isBoolean().withMessage('Should have a valid transcoding 360p resolution enabled boolean'),
92 body('live.transcoding.resolutions.480p').isBoolean().withMessage('Should have a valid transcoding 480p resolution enabled boolean'),
93 body('live.transcoding.resolutions.720p').isBoolean().withMessage('Should have a valid transcoding 720p resolution enabled boolean'),
94 body('live.transcoding.resolutions.1080p').isBoolean().withMessage('Should have a valid transcoding 1080p resolution enabled boolean'),
95 body('live.transcoding.resolutions.1440p').isBoolean().withMessage('Should have a valid transcoding 1440p resolution enabled boolean'),
96 body('live.transcoding.resolutions.2160p').isBoolean().withMessage('Should have a valid transcoding 2160p resolution enabled boolean'),
97 body('live.transcoding.alwaysTranscodeOriginalResolution').isBoolean()
98 .withMessage('Should have a valid always transcode live original resolution boolean'),
99
100 body('search.remoteUri.users').isBoolean().withMessage('Should have a remote URI search for users boolean'),
101 body('search.remoteUri.anonymous').isBoolean().withMessage('Should have a valid remote URI search for anonymous boolean'),
102 body('search.searchIndex.enabled').isBoolean().withMessage('Should have a valid search index enabled boolean'),
103 body('search.searchIndex.url').exists().withMessage('Should have a valid search index URL'),
104 body('search.searchIndex.disableLocalSearch').isBoolean().withMessage('Should have a valid search index disable local search boolean'),
105 body('search.searchIndex.isDefaultSearch').isBoolean().withMessage('Should have a valid search index default enabled boolean'),
106
107 (req: express.Request, res: express.Response, next: express.NextFunction) => {
108 logger.debug('Checking customConfigUpdateValidator parameters', { parameters: req.body })
109
110 if (areValidationErrors(req, res)) return
111 if (!checkInvalidConfigIfEmailDisabled(req.body, res)) return
112 if (!checkInvalidTranscodingConfig(req.body, res)) return
113 if (!checkInvalidLiveConfig(req.body, res)) return
114 if (!checkInvalidVideoStudioConfig(req.body, res)) return
115
116 return next()
117 }
118 ]
119
120 function ensureConfigIsEditable (req: express.Request, res: express.Response, next: express.NextFunction) {
121 if (!CONFIG.WEBADMIN.CONFIGURATION.EDITION.ALLOWED) {
122 return res.fail({
123 status: HttpStatusCode.METHOD_NOT_ALLOWED_405,
124 message: 'Server configuration is static and cannot be edited'
125 })
126 }
127
128 return next()
129 }
130
131 // ---------------------------------------------------------------------------
132
133 export {
134 customConfigUpdateValidator,
135 ensureConfigIsEditable
136 }
137
138 function checkInvalidConfigIfEmailDisabled (customConfig: CustomConfig, res: express.Response) {
139 if (isEmailEnabled()) return true
140
141 if (customConfig.signup.requiresEmailVerification === true) {
142 res.fail({ message: 'Emailer is disabled but you require signup email verification.' })
143 return false
144 }
145
146 return true
147 }
148
149 function checkInvalidTranscodingConfig (customConfig: CustomConfig, res: express.Response) {
150 if (customConfig.transcoding.enabled === false) return true
151
152 if (customConfig.transcoding.webtorrent.enabled === false && customConfig.transcoding.hls.enabled === false) {
153 res.fail({ message: 'You need to enable at least webtorrent transcoding or hls transcoding' })
154 return false
155 }
156
157 return true
158 }
159
160 function checkInvalidLiveConfig (customConfig: CustomConfig, res: express.Response) {
161 if (customConfig.live.enabled === false) return true
162
163 if (customConfig.live.allowReplay === true && customConfig.transcoding.enabled === false) {
164 res.fail({ message: 'You cannot allow live replay if transcoding is not enabled' })
165 return false
166 }
167
168 return true
169 }
170
171 function checkInvalidVideoStudioConfig (customConfig: CustomConfig, res: express.Response) {
172 if (customConfig.videoStudio.enabled === false) return true
173
174 if (customConfig.videoStudio.enabled === true && customConfig.transcoding.enabled === false) {
175 res.fail({ message: 'You cannot enable video studio if transcoding is not enabled' })
176 return false
177 }
178
179 return true
180 }