1 import express from 'express'
2 import { body, param, query, ValidationChain } from 'express-validator'
3 import { HttpStatusCode } from '../../../shared/models/http/http-error-codes'
4 import { PluginType } from '../../../shared/models/plugins/plugin.type'
5 import { InstallOrUpdatePlugin } from '../../../shared/models/plugins/server/api/install-plugin.model'
6 import { exists, isBooleanValid, isSafePath, toBooleanOrNull, toIntOrNull } from '../../helpers/custom-validators/misc'
7 import { isNpmPluginNameValid, isPluginNameValid, isPluginTypeValid, isPluginVersionValid } from '../../helpers/custom-validators/plugins'
8 import { logger } from '../../helpers/logger'
9 import { CONFIG } from '../../initializers/config'
10 import { PluginManager } from '../../lib/plugins/plugin-manager'
11 import { PluginModel } from '../../models/server/plugin'
12 import { areValidationErrors } from './shared'
14 const getPluginValidator = (pluginType: PluginType, withVersion = true) => {
15 const validators: (ValidationChain | express.Handler)[] = [
17 .custom(isPluginNameValid)
22 param('pluginVersion')
23 .custom(isPluginVersionValid)
27 return validators.concat([
28 (req: express.Request, res: express.Response, next: express.NextFunction) => {
29 logger.debug('Checking getPluginValidator parameters', { parameters: req.params })
31 if (areValidationErrors(req, res)) return
33 const npmName = PluginModel.buildNpmName(req.params.pluginName, pluginType)
34 const plugin = PluginManager.Instance.getRegisteredPluginOrTheme(npmName)
38 status: HttpStatusCode.NOT_FOUND_404,
39 message: 'No plugin found named ' + npmName
42 if (withVersion && plugin.version !== req.params.pluginVersion) {
44 status: HttpStatusCode.NOT_FOUND_404,
45 message: 'No plugin found named ' + npmName + ' with version ' + req.params.pluginVersion
49 res.locals.registeredPlugin = plugin
56 const getExternalAuthValidator = [
60 (req: express.Request, res: express.Response, next: express.NextFunction) => {
61 logger.debug('Checking getExternalAuthValidator parameters', { parameters: req.params })
63 if (areValidationErrors(req, res)) return
65 const plugin = res.locals.registeredPlugin
66 if (!plugin.registerHelpers) {
68 status: HttpStatusCode.NOT_FOUND_404,
69 message: 'No registered helpers were found for this plugin'
73 const externalAuth = plugin.registerHelpers.getExternalAuths().find(a => a.authName === req.params.authName)
76 status: HttpStatusCode.NOT_FOUND_404,
77 message: 'No external auths were found for this plugin'
81 res.locals.externalAuth = externalAuth
87 const pluginStaticDirectoryValidator = [
88 param('staticEndpoint')
91 (req: express.Request, res: express.Response, next: express.NextFunction) => {
92 logger.debug('Checking pluginStaticDirectoryValidator parameters', { parameters: req.params })
94 if (areValidationErrors(req, res)) return
100 const listPluginsValidator = [
103 .customSanitizer(toIntOrNull)
104 .custom(isPluginTypeValid),
107 .customSanitizer(toBooleanOrNull)
108 .custom(isBooleanValid),
110 (req: express.Request, res: express.Response, next: express.NextFunction) => {
111 logger.debug('Checking listPluginsValidator parameters', { parameters: req.query })
113 if (areValidationErrors(req, res)) return
119 const installOrUpdatePluginValidator = [
122 .custom(isNpmPluginNameValid),
123 body('pluginVersion')
125 .custom(isPluginVersionValid),
130 (req: express.Request, res: express.Response, next: express.NextFunction) => {
131 logger.debug('Checking installOrUpdatePluginValidator parameters', { parameters: req.body })
133 if (areValidationErrors(req, res)) return
135 const body: InstallOrUpdatePlugin = req.body
136 if (!body.path && !body.npmName) {
137 return res.fail({ message: 'Should have either a npmName or a path' })
139 if (body.pluginVersion && !body.npmName) {
140 return res.fail({ message: 'Should have a npmName when specifying a pluginVersion' })
147 const uninstallPluginValidator = [
149 .custom(isNpmPluginNameValid),
151 (req: express.Request, res: express.Response, next: express.NextFunction) => {
152 logger.debug('Checking uninstallPluginValidator parameters', { parameters: req.body })
154 if (areValidationErrors(req, res)) return
160 const existingPluginValidator = [
162 .custom(isNpmPluginNameValid),
164 async (req: express.Request, res: express.Response, next: express.NextFunction) => {
165 logger.debug('Checking enabledPluginValidator parameters', { parameters: req.params })
167 if (areValidationErrors(req, res)) return
169 const plugin = await PluginModel.loadByNpmName(req.params.npmName)
172 status: HttpStatusCode.NOT_FOUND_404,
173 message: 'Plugin not found'
177 res.locals.plugin = plugin
182 const updatePluginSettingsValidator = [
186 (req: express.Request, res: express.Response, next: express.NextFunction) => {
187 logger.debug('Checking enabledPluginValidator parameters', { parameters: req.body })
189 if (areValidationErrors(req, res)) return
195 const listAvailablePluginsValidator = [
201 .customSanitizer(toIntOrNull)
202 .custom(isPluginTypeValid),
203 query('currentPeerTubeEngine')
205 .custom(isPluginVersionValid),
207 (req: express.Request, res: express.Response, next: express.NextFunction) => {
208 logger.debug('Checking enabledPluginValidator parameters', { parameters: req.query })
210 if (areValidationErrors(req, res)) return
212 if (CONFIG.PLUGINS.INDEX.ENABLED === false) {
213 return res.fail({ message: 'Plugin index is not enabled' })
220 // ---------------------------------------------------------------------------
223 pluginStaticDirectoryValidator,
225 updatePluginSettingsValidator,
226 uninstallPluginValidator,
227 listAvailablePluginsValidator,
228 existingPluginValidator,
229 installOrUpdatePluginValidator,
230 listPluginsValidator,
231 getExternalAuthValidator