]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blob - server/middlewares/validators/config.ts
Channel sync (#5135)
[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('import.videoChannelSynchronization.enabled').isBoolean().withMessage('Should have a valid synchronization enabled boolean'),
70
71 body('trending.videos.algorithms.default').exists().withMessage('Should have a valid default trending algorithm'),
72 body('trending.videos.algorithms.enabled').exists().withMessage('Should have a valid array of enabled trending algorithms'),
73
74 body('followers.instance.enabled').isBoolean().withMessage('Should have a valid followers of instance boolean'),
75 body('followers.instance.manualApproval').isBoolean().withMessage('Should have a valid manual approval boolean'),
76
77 body('theme.default').custom(v => isThemeNameValid(v) && isThemeRegistered(v)).withMessage('Should have a valid theme'),
78
79 body('broadcastMessage.enabled').isBoolean().withMessage('Should have a valid broadcast message enabled boolean'),
80 body('broadcastMessage.message').exists().withMessage('Should have a valid broadcast message'),
81 body('broadcastMessage.level').exists().withMessage('Should have a valid broadcast level'),
82 body('broadcastMessage.dismissable').isBoolean().withMessage('Should have a valid broadcast dismissable boolean'),
83
84 body('live.enabled').isBoolean().withMessage('Should have a valid live enabled boolean'),
85 body('live.allowReplay').isBoolean().withMessage('Should have a valid live allow replay boolean'),
86 body('live.maxDuration').isInt().withMessage('Should have a valid live max duration'),
87 body('live.maxInstanceLives').custom(isIntOrNull).withMessage('Should have a valid max instance lives'),
88 body('live.maxUserLives').custom(isIntOrNull).withMessage('Should have a valid max user lives'),
89 body('live.transcoding.enabled').isBoolean().withMessage('Should have a valid live transcoding enabled boolean'),
90 body('live.transcoding.threads').isInt().withMessage('Should have a valid live transcoding threads'),
91 body('live.transcoding.resolutions.144p').isBoolean().withMessage('Should have a valid transcoding 144p resolution enabled boolean'),
92 body('live.transcoding.resolutions.240p').isBoolean().withMessage('Should have a valid transcoding 240p resolution enabled boolean'),
93 body('live.transcoding.resolutions.360p').isBoolean().withMessage('Should have a valid transcoding 360p resolution enabled boolean'),
94 body('live.transcoding.resolutions.480p').isBoolean().withMessage('Should have a valid transcoding 480p resolution enabled boolean'),
95 body('live.transcoding.resolutions.720p').isBoolean().withMessage('Should have a valid transcoding 720p resolution enabled boolean'),
96 body('live.transcoding.resolutions.1080p').isBoolean().withMessage('Should have a valid transcoding 1080p resolution enabled boolean'),
97 body('live.transcoding.resolutions.1440p').isBoolean().withMessage('Should have a valid transcoding 1440p resolution enabled boolean'),
98 body('live.transcoding.resolutions.2160p').isBoolean().withMessage('Should have a valid transcoding 2160p resolution enabled boolean'),
99 body('live.transcoding.alwaysTranscodeOriginalResolution').isBoolean()
100 .withMessage('Should have a valid always transcode live original resolution boolean'),
101
102 body('search.remoteUri.users').isBoolean().withMessage('Should have a remote URI search for users boolean'),
103 body('search.remoteUri.anonymous').isBoolean().withMessage('Should have a valid remote URI search for anonymous boolean'),
104 body('search.searchIndex.enabled').isBoolean().withMessage('Should have a valid search index enabled boolean'),
105 body('search.searchIndex.url').exists().withMessage('Should have a valid search index URL'),
106 body('search.searchIndex.disableLocalSearch').isBoolean().withMessage('Should have a valid search index disable local search boolean'),
107 body('search.searchIndex.isDefaultSearch').isBoolean().withMessage('Should have a valid search index default enabled boolean'),
108
109 (req: express.Request, res: express.Response, next: express.NextFunction) => {
110 logger.debug('Checking customConfigUpdateValidator parameters', { parameters: req.body })
111
112 if (areValidationErrors(req, res)) return
113 if (!checkInvalidConfigIfEmailDisabled(req.body, res)) return
114 if (!checkInvalidTranscodingConfig(req.body, res)) return
115 if (!checkInvalidSynchronizationConfig(req.body, res)) return
116 if (!checkInvalidLiveConfig(req.body, res)) return
117 if (!checkInvalidVideoStudioConfig(req.body, res)) return
118
119 return next()
120 }
121 ]
122
123 function ensureConfigIsEditable (req: express.Request, res: express.Response, next: express.NextFunction) {
124 if (!CONFIG.WEBADMIN.CONFIGURATION.EDITION.ALLOWED) {
125 return res.fail({
126 status: HttpStatusCode.METHOD_NOT_ALLOWED_405,
127 message: 'Server configuration is static and cannot be edited'
128 })
129 }
130
131 return next()
132 }
133
134 // ---------------------------------------------------------------------------
135
136 export {
137 customConfigUpdateValidator,
138 ensureConfigIsEditable
139 }
140
141 function checkInvalidConfigIfEmailDisabled (customConfig: CustomConfig, res: express.Response) {
142 if (isEmailEnabled()) return true
143
144 if (customConfig.signup.requiresEmailVerification === true) {
145 res.fail({ message: 'Emailer is disabled but you require signup email verification.' })
146 return false
147 }
148
149 return true
150 }
151
152 function checkInvalidTranscodingConfig (customConfig: CustomConfig, res: express.Response) {
153 if (customConfig.transcoding.enabled === false) return true
154
155 if (customConfig.transcoding.webtorrent.enabled === false && customConfig.transcoding.hls.enabled === false) {
156 res.fail({ message: 'You need to enable at least webtorrent transcoding or hls transcoding' })
157 return false
158 }
159
160 return true
161 }
162
163 function checkInvalidSynchronizationConfig (customConfig: CustomConfig, res: express.Response) {
164 if (customConfig.import.videoChannelSynchronization.enabled && !customConfig.import.videos.http.enabled) {
165 res.fail({ message: 'You need to enable HTTP video import in order to enable channel synchronization' })
166 return false
167 }
168 return true
169 }
170
171 function checkInvalidLiveConfig (customConfig: CustomConfig, res: express.Response) {
172 if (customConfig.live.enabled === false) return true
173
174 if (customConfig.live.allowReplay === true && customConfig.transcoding.enabled === false) {
175 res.fail({ message: 'You cannot allow live replay if transcoding is not enabled' })
176 return false
177 }
178
179 return true
180 }
181
182 function checkInvalidVideoStudioConfig (customConfig: CustomConfig, res: express.Response) {
183 if (customConfig.videoStudio.enabled === false) return true
184
185 if (customConfig.videoStudio.enabled === true && customConfig.transcoding.enabled === false) {
186 res.fail({ message: 'You cannot enable video studio if transcoding is not enabled' })
187 return false
188 }
189
190 return true
191 }