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