]>
Commit | Line | Data |
---|---|---|
345da516 | 1 | import * as express from 'express' |
5e2b2e27 | 2 | import { body, param, query, ValidationChain } from 'express-validator' |
345da516 C |
3 | import { logger } from '../../helpers/logger' |
4 | import { areValidationErrors } from './utils' | |
b5f919ac | 5 | import { isNpmPluginNameValid, isPluginNameValid, isPluginTypeValid, isPluginVersionValid } from '../../helpers/custom-validators/plugins' |
345da516 | 6 | import { PluginManager } from '../../lib/plugins/plugin-manager' |
c8861d5d | 7 | import { isBooleanValid, isSafePath, toBooleanOrNull } from '../../helpers/custom-validators/misc' |
ad91e700 | 8 | import { PluginModel } from '../../models/server/plugin' |
b5f919ac C |
9 | import { InstallOrUpdatePlugin } from '../../../shared/models/plugins/install-plugin.model' |
10 | import { PluginType } from '../../../shared/models/plugins/plugin.type' | |
6702a1b2 | 11 | import { CONFIG } from '../../initializers/config' |
345da516 | 12 | |
5e2b2e27 C |
13 | const getPluginValidator = (pluginType: PluginType, withVersion = true) => { |
14 | const validators: (ValidationChain | express.Handler)[] = [ | |
15 | param('pluginName').custom(isPluginNameValid).withMessage('Should have a valid plugin name') | |
16 | ] | |
345da516 | 17 | |
5e2b2e27 C |
18 | if (withVersion) { |
19 | validators.push( | |
20 | param('pluginVersion').custom(isPluginVersionValid).withMessage('Should have a valid plugin version') | |
21 | ) | |
22 | } | |
345da516 | 23 | |
5e2b2e27 C |
24 | return validators.concat([ |
25 | (req: express.Request, res: express.Response, next: express.NextFunction) => { | |
26 | logger.debug('Checking getPluginValidator parameters', { parameters: req.params }) | |
27 | ||
28 | if (areValidationErrors(req, res)) return | |
29 | ||
30 | const npmName = PluginModel.buildNpmName(req.params.pluginName, pluginType) | |
31 | const plugin = PluginManager.Instance.getRegisteredPluginOrTheme(npmName) | |
32 | ||
33 | if (!plugin) return res.sendStatus(404) | |
34 | if (withVersion && plugin.version !== req.params.pluginVersion) return res.sendStatus(404) | |
345da516 | 35 | |
5e2b2e27 | 36 | res.locals.registeredPlugin = plugin |
345da516 | 37 | |
5e2b2e27 | 38 | return next() |
345da516 | 39 | } |
5e2b2e27 C |
40 | ]) |
41 | } | |
42 | ||
43 | const pluginStaticDirectoryValidator = [ | |
44 | param('staticEndpoint').custom(isSafePath).withMessage('Should have a valid static endpoint'), | |
345da516 | 45 | |
5e2b2e27 C |
46 | (req: express.Request, res: express.Response, next: express.NextFunction) => { |
47 | logger.debug('Checking pluginStaticDirectoryValidator parameters', { parameters: req.params }) | |
48 | ||
49 | if (areValidationErrors(req, res)) return | |
345da516 C |
50 | |
51 | return next() | |
52 | } | |
53 | ] | |
54 | ||
ad91e700 | 55 | const listPluginsValidator = [ |
6702a1b2 | 56 | query('pluginType') |
ad91e700 C |
57 | .optional() |
58 | .custom(isPluginTypeValid).withMessage('Should have a valid plugin type'), | |
59 | query('uninstalled') | |
60 | .optional() | |
c8861d5d | 61 | .customSanitizer(toBooleanOrNull) |
ad91e700 C |
62 | .custom(isBooleanValid).withMessage('Should have a valid uninstalled attribute'), |
63 | ||
64 | (req: express.Request, res: express.Response, next: express.NextFunction) => { | |
65 | logger.debug('Checking listPluginsValidator parameters', { parameters: req.query }) | |
66 | ||
67 | if (areValidationErrors(req, res)) return | |
68 | ||
69 | return next() | |
70 | } | |
71 | ] | |
72 | ||
b5f919ac | 73 | const installOrUpdatePluginValidator = [ |
8d2be0ed C |
74 | body('npmName') |
75 | .optional() | |
76 | .custom(isNpmPluginNameValid).withMessage('Should have a valid npm name'), | |
77 | body('path') | |
78 | .optional() | |
79 | .custom(isSafePath).withMessage('Should have a valid safe path'), | |
ad91e700 C |
80 | |
81 | (req: express.Request, res: express.Response, next: express.NextFunction) => { | |
b5f919ac | 82 | logger.debug('Checking installOrUpdatePluginValidator parameters', { parameters: req.body }) |
ad91e700 C |
83 | |
84 | if (areValidationErrors(req, res)) return | |
85 | ||
b5f919ac | 86 | const body: InstallOrUpdatePlugin = req.body |
8d2be0ed C |
87 | if (!body.path && !body.npmName) { |
88 | return res.status(400) | |
89 | .json({ error: 'Should have either a npmName or a path' }) | |
90 | .end() | |
91 | } | |
92 | ||
ad91e700 C |
93 | return next() |
94 | } | |
95 | ] | |
96 | ||
97 | const uninstallPluginValidator = [ | |
98 | body('npmName').custom(isNpmPluginNameValid).withMessage('Should have a valid npm name'), | |
99 | ||
100 | (req: express.Request, res: express.Response, next: express.NextFunction) => { | |
dba85a1e | 101 | logger.debug('Checking uninstallPluginValidator parameters', { parameters: req.body }) |
ad91e700 C |
102 | |
103 | if (areValidationErrors(req, res)) return | |
104 | ||
105 | return next() | |
106 | } | |
107 | ] | |
108 | ||
dba85a1e | 109 | const existingPluginValidator = [ |
60cfd4cb | 110 | param('npmName').custom(isNpmPluginNameValid).withMessage('Should have a valid plugin name'), |
ad91e700 C |
111 | |
112 | async (req: express.Request, res: express.Response, next: express.NextFunction) => { | |
dba85a1e | 113 | logger.debug('Checking enabledPluginValidator parameters', { parameters: req.params }) |
ad91e700 C |
114 | |
115 | if (areValidationErrors(req, res)) return | |
116 | ||
dba85a1e | 117 | const plugin = await PluginModel.loadByNpmName(req.params.npmName) |
ad91e700 C |
118 | if (!plugin) { |
119 | return res.status(404) | |
120 | .json({ error: 'Plugin not found' }) | |
121 | .end() | |
122 | } | |
123 | ||
124 | res.locals.plugin = plugin | |
125 | ||
126 | return next() | |
127 | } | |
128 | ] | |
129 | ||
130 | const updatePluginSettingsValidator = [ | |
131 | body('settings').exists().withMessage('Should have settings'), | |
132 | ||
133 | (req: express.Request, res: express.Response, next: express.NextFunction) => { | |
134 | logger.debug('Checking enabledPluginValidator parameters', { parameters: req.body }) | |
135 | ||
136 | if (areValidationErrors(req, res)) return | |
137 | ||
138 | return next() | |
139 | } | |
140 | ] | |
141 | ||
6702a1b2 | 142 | const listAvailablePluginsValidator = [ |
6702a1b2 C |
143 | query('search') |
144 | .optional() | |
145 | .exists().withMessage('Should have a valid search'), | |
146 | query('pluginType') | |
147 | .optional() | |
148 | .custom(isPluginTypeValid).withMessage('Should have a valid plugin type'), | |
09071200 C |
149 | query('currentPeerTubeEngine') |
150 | .optional() | |
151 | .custom(isPluginVersionValid).withMessage('Should have a valid current peertube engine'), | |
6702a1b2 C |
152 | |
153 | (req: express.Request, res: express.Response, next: express.NextFunction) => { | |
154 | logger.debug('Checking enabledPluginValidator parameters', { parameters: req.query }) | |
155 | ||
156 | if (areValidationErrors(req, res)) return | |
157 | ||
158 | if (CONFIG.PLUGINS.INDEX.ENABLED === false) { | |
159 | return res.status(400) | |
160 | .json({ error: 'Plugin index is not enabled' }) | |
161 | .end() | |
162 | } | |
163 | ||
164 | return next() | |
165 | } | |
166 | ] | |
167 | ||
345da516 C |
168 | // --------------------------------------------------------------------------- |
169 | ||
170 | export { | |
5e2b2e27 C |
171 | pluginStaticDirectoryValidator, |
172 | getPluginValidator, | |
ad91e700 C |
173 | updatePluginSettingsValidator, |
174 | uninstallPluginValidator, | |
6702a1b2 | 175 | listAvailablePluginsValidator, |
dba85a1e | 176 | existingPluginValidator, |
b5f919ac | 177 | installOrUpdatePluginValidator, |
ad91e700 | 178 | listPluginsValidator |
345da516 | 179 | } |