]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blob - server/middlewares/validators/config.ts
Enable external plugins to test the PR
[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 { HttpStatusCode } from '@shared/models/http/http-error-codes'
6 import { CustomConfig } from '../../../shared/models/server/custom-config.model'
7 import { isThemeNameValid } from '../../helpers/custom-validators/plugins'
8 import { isUserNSFWPolicyValid, isUserVideoQuotaDailyValid, isUserVideoQuotaValid } from '../../helpers/custom-validators/users'
9 import { isThemeRegistered } from '../../lib/plugins/theme-utils'
10 import { areValidationErrors } from './shared'
11
12 const customConfigUpdateValidator = [
13 body('instance.name').exists(),
14 body('instance.shortDescription').exists(),
15 body('instance.description').exists(),
16 body('instance.terms').exists(),
17 body('instance.defaultNSFWPolicy').custom(isUserNSFWPolicyValid),
18 body('instance.defaultClientRoute').exists(),
19 body('instance.customizations.css').exists(),
20 body('instance.customizations.javascript').exists(),
21
22 body('services.twitter.username').exists(),
23 body('services.twitter.whitelisted').isBoolean(),
24
25 body('cache.previews.size').isInt(),
26 body('cache.captions.size').isInt(),
27 body('cache.torrents.size').isInt(),
28
29 body('signup.enabled').isBoolean(),
30 body('signup.limit').isInt(),
31 body('signup.requiresEmailVerification').isBoolean(),
32 body('signup.requiresApproval').isBoolean(),
33 body('signup.minimumAge').isInt(),
34
35 body('admin.email').isEmail(),
36 body('contactForm.enabled').isBoolean(),
37
38 body('user.history.videos.enabled').isBoolean(),
39 body('user.videoQuota').custom(isUserVideoQuotaValid),
40 body('user.videoQuotaDaily').custom(isUserVideoQuotaDailyValid),
41
42 body('videoChannels.maxPerUser').isInt(),
43
44 body('transcoding.enabled').isBoolean(),
45 body('transcoding.allowAdditionalExtensions').isBoolean(),
46 body('transcoding.threads').isInt(),
47 body('transcoding.concurrency').isInt({ min: 1 }),
48 body('transcoding.resolutions.0p').isBoolean(),
49 body('transcoding.resolutions.144p').isBoolean(),
50 body('transcoding.resolutions.240p').isBoolean(),
51 body('transcoding.resolutions.360p').isBoolean(),
52 body('transcoding.resolutions.480p').isBoolean(),
53 body('transcoding.resolutions.720p').isBoolean(),
54 body('transcoding.resolutions.1080p').isBoolean(),
55 body('transcoding.resolutions.1440p').isBoolean(),
56 body('transcoding.resolutions.2160p').isBoolean(),
57 body('transcoding.remoteRunners.enabled').isBoolean(),
58
59 body('transcoding.alwaysTranscodeOriginalResolution').isBoolean(),
60
61 body('transcoding.webtorrent.enabled').isBoolean(),
62 body('transcoding.hls.enabled').isBoolean(),
63
64 body('videoStudio.enabled').isBoolean(),
65
66 body('import.videos.concurrency').isInt({ min: 0 }),
67 body('import.videos.http.enabled').isBoolean(),
68 body('import.videos.torrent.enabled').isBoolean(),
69
70 body('import.videoChannelSynchronization.enabled').isBoolean(),
71
72 body('trending.videos.algorithms.default').exists(),
73 body('trending.videos.algorithms.enabled').exists(),
74
75 body('followers.instance.enabled').isBoolean(),
76 body('followers.instance.manualApproval').isBoolean(),
77
78 body('theme.default').custom(v => isThemeNameValid(v) && isThemeRegistered(v)),
79
80 body('broadcastMessage.enabled').isBoolean(),
81 body('broadcastMessage.message').exists(),
82 body('broadcastMessage.level').exists(),
83 body('broadcastMessage.dismissable').isBoolean(),
84
85 body('live.enabled').isBoolean(),
86 body('live.allowReplay').isBoolean(),
87 body('live.maxDuration').isInt(),
88 body('live.maxInstanceLives').custom(isIntOrNull),
89 body('live.maxUserLives').custom(isIntOrNull),
90 body('live.transcoding.enabled').isBoolean(),
91 body('live.transcoding.threads').isInt(),
92 body('live.transcoding.resolutions.144p').isBoolean(),
93 body('live.transcoding.resolutions.240p').isBoolean(),
94 body('live.transcoding.resolutions.360p').isBoolean(),
95 body('live.transcoding.resolutions.480p').isBoolean(),
96 body('live.transcoding.resolutions.720p').isBoolean(),
97 body('live.transcoding.resolutions.1080p').isBoolean(),
98 body('live.transcoding.resolutions.1440p').isBoolean(),
99 body('live.transcoding.resolutions.2160p').isBoolean(),
100 body('live.transcoding.alwaysTranscodeOriginalResolution').isBoolean(),
101 body('live.transcoding.remoteRunners.enabled').isBoolean(),
102
103 body('search.remoteUri.users').isBoolean(),
104 body('search.remoteUri.anonymous').isBoolean(),
105 body('search.searchIndex.enabled').isBoolean(),
106 body('search.searchIndex.url').exists(),
107 body('search.searchIndex.disableLocalSearch').isBoolean(),
108 body('search.searchIndex.isDefaultSearch').isBoolean(),
109
110 (req: express.Request, res: express.Response, next: express.NextFunction) => {
111 if (areValidationErrors(req, res)) return
112 if (!checkInvalidConfigIfEmailDisabled(req.body, res)) return
113 if (!checkInvalidTranscodingConfig(req.body, res)) return
114 if (!checkInvalidSynchronizationConfig(req.body, res)) return
115 if (!checkInvalidLiveConfig(req.body, res)) return
116 if (!checkInvalidVideoStudioConfig(req.body, res)) return
117
118 return next()
119 }
120 ]
121
122 function ensureConfigIsEditable (req: express.Request, res: express.Response, next: express.NextFunction) {
123 if (!CONFIG.WEBADMIN.CONFIGURATION.EDITION.ALLOWED) {
124 return res.fail({
125 status: HttpStatusCode.METHOD_NOT_ALLOWED_405,
126 message: 'Server configuration is static and cannot be edited'
127 })
128 }
129
130 return next()
131 }
132
133 // ---------------------------------------------------------------------------
134
135 export {
136 customConfigUpdateValidator,
137 ensureConfigIsEditable
138 }
139
140 function checkInvalidConfigIfEmailDisabled (customConfig: CustomConfig, res: express.Response) {
141 if (isEmailEnabled()) return true
142
143 if (customConfig.signup.requiresEmailVerification === true) {
144 res.fail({ message: 'Emailer is disabled but you require signup email verification.' })
145 return false
146 }
147
148 return true
149 }
150
151 function checkInvalidTranscodingConfig (customConfig: CustomConfig, res: express.Response) {
152 if (customConfig.transcoding.enabled === false) return true
153
154 if (customConfig.transcoding.webtorrent.enabled === false && customConfig.transcoding.hls.enabled === false) {
155 res.fail({ message: 'You need to enable at least webtorrent transcoding or hls transcoding' })
156 return false
157 }
158
159 return true
160 }
161
162 function checkInvalidSynchronizationConfig (customConfig: CustomConfig, res: express.Response) {
163 if (customConfig.import.videoChannelSynchronization.enabled && !customConfig.import.videos.http.enabled) {
164 res.fail({ message: 'You need to enable HTTP video import in order to enable channel synchronization' })
165 return false
166 }
167 return true
168 }
169
170 function checkInvalidLiveConfig (customConfig: CustomConfig, res: express.Response) {
171 if (customConfig.live.enabled === false) return true
172
173 if (customConfig.live.allowReplay === true && customConfig.transcoding.enabled === false) {
174 res.fail({ message: 'You cannot allow live replay if transcoding is not enabled' })
175 return false
176 }
177
178 return true
179 }
180
181 function checkInvalidVideoStudioConfig (customConfig: CustomConfig, res: express.Response) {
182 if (customConfig.videoStudio.enabled === false) return true
183
184 if (customConfig.videoStudio.enabled === true && customConfig.transcoding.enabled === false) {
185 res.fail({ message: 'You cannot enable video studio if transcoding is not enabled' })
186 return false
187 }
188
189 return true
190 }