]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blob - server/controllers/api/plugins.ts
de9e055dc0fe4b9bf7db4b7c0a5484237a44ebc9
[github/Chocobozzz/PeerTube.git] / server / controllers / api / plugins.ts
1 import express from 'express'
2 import { logger } from '@server/helpers/logger'
3 import { getFormattedObjects } from '@server/helpers/utils'
4 import { listAvailablePluginsFromIndex } from '@server/lib/plugins/plugin-index'
5 import { PluginManager } from '@server/lib/plugins/plugin-manager'
6 import {
7 asyncMiddleware,
8 authenticate,
9 availablePluginsSortValidator,
10 ensureUserHasRight,
11 openapiOperationDoc,
12 paginationValidator,
13 pluginsSortValidator,
14 setDefaultPagination,
15 setDefaultSort
16 } from '@server/middlewares'
17 import {
18 existingPluginValidator,
19 installOrUpdatePluginValidator,
20 listAvailablePluginsValidator,
21 listPluginsValidator,
22 uninstallPluginValidator,
23 updatePluginSettingsValidator
24 } from '@server/middlewares/validators/plugins'
25 import { PluginModel } from '@server/models/server/plugin'
26 import {
27 HttpStatusCode,
28 InstallOrUpdatePlugin,
29 ManagePlugin,
30 PeertubePluginIndexList,
31 PublicServerSetting,
32 RegisteredServerSettings,
33 UserRight
34 } from '@shared/models'
35
36 const pluginRouter = express.Router()
37
38 pluginRouter.get('/available',
39 openapiOperationDoc({ operationId: 'getAvailablePlugins' }),
40 authenticate,
41 ensureUserHasRight(UserRight.MANAGE_PLUGINS),
42 listAvailablePluginsValidator,
43 paginationValidator,
44 availablePluginsSortValidator,
45 setDefaultSort,
46 setDefaultPagination,
47 asyncMiddleware(listAvailablePlugins)
48 )
49
50 pluginRouter.get('/',
51 openapiOperationDoc({ operationId: 'getPlugins' }),
52 authenticate,
53 ensureUserHasRight(UserRight.MANAGE_PLUGINS),
54 listPluginsValidator,
55 paginationValidator,
56 pluginsSortValidator,
57 setDefaultSort,
58 setDefaultPagination,
59 asyncMiddleware(listPlugins)
60 )
61
62 pluginRouter.get('/:npmName/registered-settings',
63 authenticate,
64 ensureUserHasRight(UserRight.MANAGE_PLUGINS),
65 asyncMiddleware(existingPluginValidator),
66 getPluginRegisteredSettings
67 )
68
69 pluginRouter.get('/:npmName/public-settings',
70 asyncMiddleware(existingPluginValidator),
71 getPublicPluginSettings
72 )
73
74 pluginRouter.put('/:npmName/settings',
75 authenticate,
76 ensureUserHasRight(UserRight.MANAGE_PLUGINS),
77 updatePluginSettingsValidator,
78 asyncMiddleware(existingPluginValidator),
79 asyncMiddleware(updatePluginSettings)
80 )
81
82 pluginRouter.get('/:npmName',
83 authenticate,
84 ensureUserHasRight(UserRight.MANAGE_PLUGINS),
85 asyncMiddleware(existingPluginValidator),
86 getPlugin
87 )
88
89 pluginRouter.post('/install',
90 openapiOperationDoc({ operationId: 'addPlugin' }),
91 authenticate,
92 ensureUserHasRight(UserRight.MANAGE_PLUGINS),
93 installOrUpdatePluginValidator,
94 asyncMiddleware(installPlugin)
95 )
96
97 pluginRouter.post('/update',
98 openapiOperationDoc({ operationId: 'updatePlugin' }),
99 authenticate,
100 ensureUserHasRight(UserRight.MANAGE_PLUGINS),
101 installOrUpdatePluginValidator,
102 asyncMiddleware(updatePlugin)
103 )
104
105 pluginRouter.post('/uninstall',
106 openapiOperationDoc({ operationId: 'uninstallPlugin' }),
107 authenticate,
108 ensureUserHasRight(UserRight.MANAGE_PLUGINS),
109 uninstallPluginValidator,
110 asyncMiddleware(uninstallPlugin)
111 )
112
113 // ---------------------------------------------------------------------------
114
115 export {
116 pluginRouter
117 }
118
119 // ---------------------------------------------------------------------------
120
121 async function listPlugins (req: express.Request, res: express.Response) {
122 const pluginType = req.query.pluginType
123 const uninstalled = req.query.uninstalled
124
125 const resultList = await PluginModel.listForApi({
126 pluginType,
127 uninstalled,
128 start: req.query.start,
129 count: req.query.count,
130 sort: req.query.sort
131 })
132
133 return res.json(getFormattedObjects(resultList.data, resultList.total))
134 }
135
136 function getPlugin (req: express.Request, res: express.Response) {
137 const plugin = res.locals.plugin
138
139 return res.json(plugin.toFormattedJSON())
140 }
141
142 async function installPlugin (req: express.Request, res: express.Response) {
143 const body: InstallOrUpdatePlugin = req.body
144
145 const fromDisk = !!body.path
146 const toInstall = body.npmName || body.path
147
148 const pluginVersion = body.pluginVersion && body.npmName
149 ? body.pluginVersion
150 : undefined
151
152 try {
153 const plugin = await PluginManager.Instance.install(toInstall, pluginVersion, fromDisk)
154
155 return res.json(plugin.toFormattedJSON())
156 } catch (err) {
157 logger.warn('Cannot install plugin %s.', toInstall, { err })
158 return res.fail({ message: 'Cannot install plugin ' + toInstall })
159 }
160 }
161
162 async function updatePlugin (req: express.Request, res: express.Response) {
163 const body: InstallOrUpdatePlugin = req.body
164
165 const fromDisk = !!body.path
166 const toUpdate = body.npmName || body.path
167 try {
168 const plugin = await PluginManager.Instance.update(toUpdate, fromDisk)
169
170 return res.json(plugin.toFormattedJSON())
171 } catch (err) {
172 logger.warn('Cannot update plugin %s.', toUpdate, { err })
173 return res.fail({ message: 'Cannot update plugin ' + toUpdate })
174 }
175 }
176
177 async function uninstallPlugin (req: express.Request, res: express.Response) {
178 const body: ManagePlugin = req.body
179
180 await PluginManager.Instance.uninstall(body.npmName)
181
182 return res.status(HttpStatusCode.NO_CONTENT_204).end()
183 }
184
185 function getPublicPluginSettings (req: express.Request, res: express.Response) {
186 const plugin = res.locals.plugin
187 const registeredSettings = PluginManager.Instance.getRegisteredSettings(req.params.npmName)
188 const publicSettings = plugin.getPublicSettings(registeredSettings)
189
190 const json: PublicServerSetting = { publicSettings }
191
192 return res.json(json)
193 }
194
195 function getPluginRegisteredSettings (req: express.Request, res: express.Response) {
196 const registeredSettings = PluginManager.Instance.getRegisteredSettings(req.params.npmName)
197
198 const json: RegisteredServerSettings = { registeredSettings }
199
200 return res.json(json)
201 }
202
203 async function updatePluginSettings (req: express.Request, res: express.Response) {
204 const plugin = res.locals.plugin
205
206 plugin.settings = req.body.settings
207 await plugin.save()
208
209 await PluginManager.Instance.onSettingsChanged(plugin.name, plugin.settings)
210
211 return res.status(HttpStatusCode.NO_CONTENT_204).end()
212 }
213
214 async function listAvailablePlugins (req: express.Request, res: express.Response) {
215 const query: PeertubePluginIndexList = req.query
216
217 const resultList = await listAvailablePluginsFromIndex(query)
218
219 if (!resultList) {
220 return res.fail({
221 status: HttpStatusCode.SERVICE_UNAVAILABLE_503,
222 message: 'Plugin index unavailable. Please retry later'
223 })
224 }
225
226 return res.json(resultList)
227 }