]>
Commit | Line | Data |
---|---|---|
41fb13c3 | 1 | import express from 'express' |
5e2b2e27 | 2 | import { body, param, query, ValidationChain } from 'express-validator' |
c0e8b12e | 3 | import { HttpStatusCode } from '../../../shared/models/http/http-error-codes' |
428ccb8b C |
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' | |
b5f919ac | 7 | import { isNpmPluginNameValid, isPluginNameValid, isPluginTypeValid, isPluginVersionValid } from '../../helpers/custom-validators/plugins' |
428ccb8b | 8 | import { CONFIG } from '../../initializers/config' |
345da516 | 9 | import { PluginManager } from '../../lib/plugins/plugin-manager' |
ad91e700 | 10 | import { PluginModel } from '../../models/server/plugin' |
10363c74 | 11 | import { areValidationErrors } from './shared' |
345da516 | 12 | |
5e2b2e27 C |
13 | const getPluginValidator = (pluginType: PluginType, withVersion = true) => { |
14 | const validators: (ValidationChain | express.Handler)[] = [ | |
396f6f01 C |
15 | param('pluginName') |
16 | .custom(isPluginNameValid) | |
5e2b2e27 | 17 | ] |
345da516 | 18 | |
5e2b2e27 C |
19 | if (withVersion) { |
20 | validators.push( | |
396f6f01 C |
21 | param('pluginVersion') |
22 | .custom(isPluginVersionValid) | |
5e2b2e27 C |
23 | ) |
24 | } | |
345da516 | 25 | |
5e2b2e27 C |
26 | return validators.concat([ |
27 | (req: express.Request, res: express.Response, next: express.NextFunction) => { | |
5e2b2e27 C |
28 | if (areValidationErrors(req, res)) return |
29 | ||
30 | const npmName = PluginModel.buildNpmName(req.params.pluginName, pluginType) | |
31 | const plugin = PluginManager.Instance.getRegisteredPluginOrTheme(npmName) | |
32 | ||
76148b27 RK |
33 | if (!plugin) { |
34 | return res.fail({ | |
35 | status: HttpStatusCode.NOT_FOUND_404, | |
36 | message: 'No plugin found named ' + npmName | |
37 | }) | |
38 | } | |
39 | if (withVersion && plugin.version !== req.params.pluginVersion) { | |
40 | return res.fail({ | |
41 | status: HttpStatusCode.NOT_FOUND_404, | |
42 | message: 'No plugin found named ' + npmName + ' with version ' + req.params.pluginVersion | |
43 | }) | |
44 | } | |
345da516 | 45 | |
5e2b2e27 | 46 | res.locals.registeredPlugin = plugin |
345da516 | 47 | |
5e2b2e27 | 48 | return next() |
345da516 | 49 | } |
5e2b2e27 C |
50 | ]) |
51 | } | |
52 | ||
4a8d113b | 53 | const getExternalAuthValidator = [ |
396f6f01 C |
54 | param('authName') |
55 | .custom(exists), | |
4a8d113b C |
56 | |
57 | (req: express.Request, res: express.Response, next: express.NextFunction) => { | |
4a8d113b C |
58 | if (areValidationErrors(req, res)) return |
59 | ||
60 | const plugin = res.locals.registeredPlugin | |
76148b27 RK |
61 | if (!plugin.registerHelpers) { |
62 | return res.fail({ | |
63 | status: HttpStatusCode.NOT_FOUND_404, | |
64 | message: 'No registered helpers were found for this plugin' | |
65 | }) | |
66 | } | |
4a8d113b | 67 | |
1896bca0 | 68 | const externalAuth = plugin.registerHelpers.getExternalAuths().find(a => a.authName === req.params.authName) |
76148b27 RK |
69 | if (!externalAuth) { |
70 | return res.fail({ | |
71 | status: HttpStatusCode.NOT_FOUND_404, | |
72 | message: 'No external auths were found for this plugin' | |
73 | }) | |
74 | } | |
4a8d113b C |
75 | |
76 | res.locals.externalAuth = externalAuth | |
77 | ||
78 | return next() | |
79 | } | |
80 | ] | |
81 | ||
5e2b2e27 | 82 | const pluginStaticDirectoryValidator = [ |
396f6f01 C |
83 | param('staticEndpoint') |
84 | .custom(isSafePath), | |
345da516 | 85 | |
5e2b2e27 | 86 | (req: express.Request, res: express.Response, next: express.NextFunction) => { |
5e2b2e27 | 87 | if (areValidationErrors(req, res)) return |
345da516 C |
88 | |
89 | return next() | |
90 | } | |
91 | ] | |
92 | ||
ad91e700 | 93 | const listPluginsValidator = [ |
6702a1b2 | 94 | query('pluginType') |
ad91e700 | 95 | .optional() |
a02b93ce | 96 | .customSanitizer(toIntOrNull) |
396f6f01 | 97 | .custom(isPluginTypeValid), |
ad91e700 C |
98 | query('uninstalled') |
99 | .optional() | |
c8861d5d | 100 | .customSanitizer(toBooleanOrNull) |
396f6f01 | 101 | .custom(isBooleanValid), |
ad91e700 C |
102 | |
103 | (req: express.Request, res: express.Response, next: express.NextFunction) => { | |
ad91e700 C |
104 | if (areValidationErrors(req, res)) return |
105 | ||
106 | return next() | |
107 | } | |
108 | ] | |
109 | ||
b5f919ac | 110 | const installOrUpdatePluginValidator = [ |
8d2be0ed C |
111 | body('npmName') |
112 | .optional() | |
396f6f01 | 113 | .custom(isNpmPluginNameValid), |
3a1157a6 JL |
114 | body('pluginVersion') |
115 | .optional() | |
396f6f01 | 116 | .custom(isPluginVersionValid), |
8d2be0ed C |
117 | body('path') |
118 | .optional() | |
396f6f01 | 119 | .custom(isSafePath), |
ad91e700 C |
120 | |
121 | (req: express.Request, res: express.Response, next: express.NextFunction) => { | |
ad91e700 C |
122 | if (areValidationErrors(req, res)) return |
123 | ||
b5f919ac | 124 | const body: InstallOrUpdatePlugin = req.body |
8d2be0ed | 125 | if (!body.path && !body.npmName) { |
76148b27 | 126 | return res.fail({ message: 'Should have either a npmName or a path' }) |
8d2be0ed | 127 | } |
3a1157a6 JL |
128 | if (body.pluginVersion && !body.npmName) { |
129 | return res.fail({ message: 'Should have a npmName when specifying a pluginVersion' }) | |
130 | } | |
8d2be0ed | 131 | |
ad91e700 C |
132 | return next() |
133 | } | |
134 | ] | |
135 | ||
136 | const uninstallPluginValidator = [ | |
396f6f01 C |
137 | body('npmName') |
138 | .custom(isNpmPluginNameValid), | |
ad91e700 C |
139 | |
140 | (req: express.Request, res: express.Response, next: express.NextFunction) => { | |
ad91e700 C |
141 | if (areValidationErrors(req, res)) return |
142 | ||
143 | return next() | |
144 | } | |
145 | ] | |
146 | ||
dba85a1e | 147 | const existingPluginValidator = [ |
396f6f01 C |
148 | param('npmName') |
149 | .custom(isNpmPluginNameValid), | |
ad91e700 C |
150 | |
151 | async (req: express.Request, res: express.Response, next: express.NextFunction) => { | |
ad91e700 C |
152 | if (areValidationErrors(req, res)) return |
153 | ||
dba85a1e | 154 | const plugin = await PluginModel.loadByNpmName(req.params.npmName) |
ad91e700 | 155 | if (!plugin) { |
76148b27 RK |
156 | return res.fail({ |
157 | status: HttpStatusCode.NOT_FOUND_404, | |
158 | message: 'Plugin not found' | |
159 | }) | |
ad91e700 C |
160 | } |
161 | ||
162 | res.locals.plugin = plugin | |
ad91e700 C |
163 | return next() |
164 | } | |
165 | ] | |
166 | ||
167 | const updatePluginSettingsValidator = [ | |
396f6f01 C |
168 | body('settings') |
169 | .exists(), | |
ad91e700 C |
170 | |
171 | (req: express.Request, res: express.Response, next: express.NextFunction) => { | |
ad91e700 C |
172 | if (areValidationErrors(req, res)) return |
173 | ||
174 | return next() | |
175 | } | |
176 | ] | |
177 | ||
6702a1b2 | 178 | const listAvailablePluginsValidator = [ |
6702a1b2 C |
179 | query('search') |
180 | .optional() | |
396f6f01 | 181 | .exists(), |
6702a1b2 C |
182 | query('pluginType') |
183 | .optional() | |
a02b93ce | 184 | .customSanitizer(toIntOrNull) |
396f6f01 | 185 | .custom(isPluginTypeValid), |
09071200 C |
186 | query('currentPeerTubeEngine') |
187 | .optional() | |
396f6f01 | 188 | .custom(isPluginVersionValid), |
6702a1b2 C |
189 | |
190 | (req: express.Request, res: express.Response, next: express.NextFunction) => { | |
6702a1b2 C |
191 | if (areValidationErrors(req, res)) return |
192 | ||
193 | if (CONFIG.PLUGINS.INDEX.ENABLED === false) { | |
76148b27 | 194 | return res.fail({ message: 'Plugin index is not enabled' }) |
6702a1b2 C |
195 | } |
196 | ||
197 | return next() | |
198 | } | |
199 | ] | |
200 | ||
345da516 C |
201 | // --------------------------------------------------------------------------- |
202 | ||
203 | export { | |
5e2b2e27 C |
204 | pluginStaticDirectoryValidator, |
205 | getPluginValidator, | |
ad91e700 C |
206 | updatePluginSettingsValidator, |
207 | uninstallPluginValidator, | |
6702a1b2 | 208 | listAvailablePluginsValidator, |
dba85a1e | 209 | existingPluginValidator, |
b5f919ac | 210 | installOrUpdatePluginValidator, |
4a8d113b C |
211 | listPluginsValidator, |
212 | getExternalAuthValidator | |
345da516 | 213 | } |