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