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