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'
9 availablePluginsSortValidator,
16 } from '@server/middlewares'
18 existingPluginValidator,
19 installOrUpdatePluginValidator,
20 listAvailablePluginsValidator,
22 uninstallPluginValidator,
23 updatePluginSettingsValidator
24 } from '@server/middlewares/validators/plugins'
25 import { PluginModel } from '@server/models/server/plugin'
28 InstallOrUpdatePlugin,
30 PeertubePluginIndexList,
32 RegisteredServerSettings,
34 } from '@shared/models'
36 const pluginRouter = express.Router()
38 pluginRouter.get('/available',
39 openapiOperationDoc({ operationId: 'getAvailablePlugins' }),
41 ensureUserHasRight(UserRight.MANAGE_PLUGINS),
42 listAvailablePluginsValidator,
44 availablePluginsSortValidator,
47 asyncMiddleware(listAvailablePlugins)
51 openapiOperationDoc({ operationId: 'getPlugins' }),
53 ensureUserHasRight(UserRight.MANAGE_PLUGINS),
59 asyncMiddleware(listPlugins)
62 pluginRouter.get('/:npmName/registered-settings',
64 ensureUserHasRight(UserRight.MANAGE_PLUGINS),
65 asyncMiddleware(existingPluginValidator),
66 getPluginRegisteredSettings
69 pluginRouter.get('/:npmName/public-settings',
70 asyncMiddleware(existingPluginValidator),
71 getPublicPluginSettings
74 pluginRouter.put('/:npmName/settings',
76 ensureUserHasRight(UserRight.MANAGE_PLUGINS),
77 updatePluginSettingsValidator,
78 asyncMiddleware(existingPluginValidator),
79 asyncMiddleware(updatePluginSettings)
82 pluginRouter.get('/:npmName',
84 ensureUserHasRight(UserRight.MANAGE_PLUGINS),
85 asyncMiddleware(existingPluginValidator),
89 pluginRouter.post('/install',
90 openapiOperationDoc({ operationId: 'addPlugin' }),
92 ensureUserHasRight(UserRight.MANAGE_PLUGINS),
93 installOrUpdatePluginValidator,
94 asyncMiddleware(installPlugin)
97 pluginRouter.post('/update',
98 openapiOperationDoc({ operationId: 'updatePlugin' }),
100 ensureUserHasRight(UserRight.MANAGE_PLUGINS),
101 installOrUpdatePluginValidator,
102 asyncMiddleware(updatePlugin)
105 pluginRouter.post('/uninstall',
106 openapiOperationDoc({ operationId: 'uninstallPlugin' }),
108 ensureUserHasRight(UserRight.MANAGE_PLUGINS),
109 uninstallPluginValidator,
110 asyncMiddleware(uninstallPlugin)
113 // ---------------------------------------------------------------------------
119 // ---------------------------------------------------------------------------
121 async function listPlugins (req: express.Request, res: express.Response) {
122 const pluginType = req.query.pluginType
123 const uninstalled = req.query.uninstalled
125 const resultList = await PluginModel.listForApi({
128 start: req.query.start,
129 count: req.query.count,
133 return res.json(getFormattedObjects(resultList.data, resultList.total))
136 function getPlugin (req: express.Request, res: express.Response) {
137 const plugin = res.locals.plugin
139 return res.json(plugin.toFormattedJSON())
142 async function installPlugin (req: express.Request, res: express.Response) {
143 const body: InstallOrUpdatePlugin = req.body
145 const fromDisk = !!body.path
146 const toInstall = body.npmName || body.path
148 const plugin = await PluginManager.Instance.install(toInstall, undefined, fromDisk)
150 return res.json(plugin.toFormattedJSON())
152 logger.warn('Cannot install plugin %s.', toInstall, { err })
153 return res.fail({ message: 'Cannot install plugin ' + toInstall })
157 async function updatePlugin (req: express.Request, res: express.Response) {
158 const body: InstallOrUpdatePlugin = req.body
160 const fromDisk = !!body.path
161 const toUpdate = body.npmName || body.path
163 const plugin = await PluginManager.Instance.update(toUpdate, fromDisk)
165 return res.json(plugin.toFormattedJSON())
167 logger.warn('Cannot update plugin %s.', toUpdate, { err })
168 return res.fail({ message: 'Cannot update plugin ' + toUpdate })
172 async function uninstallPlugin (req: express.Request, res: express.Response) {
173 const body: ManagePlugin = req.body
175 await PluginManager.Instance.uninstall(body.npmName)
177 return res.status(HttpStatusCode.NO_CONTENT_204).end()
180 function getPublicPluginSettings (req: express.Request, res: express.Response) {
181 const plugin = res.locals.plugin
182 const registeredSettings = PluginManager.Instance.getRegisteredSettings(req.params.npmName)
183 const publicSettings = plugin.getPublicSettings(registeredSettings)
185 const json: PublicServerSetting = { publicSettings }
187 return res.json(json)
190 function getPluginRegisteredSettings (req: express.Request, res: express.Response) {
191 const registeredSettings = PluginManager.Instance.getRegisteredSettings(req.params.npmName)
193 const json: RegisteredServerSettings = { registeredSettings }
195 return res.json(json)
198 async function updatePluginSettings (req: express.Request, res: express.Response) {
199 const plugin = res.locals.plugin
201 plugin.settings = req.body.settings
204 await PluginManager.Instance.onSettingsChanged(plugin.name, plugin.settings)
206 return res.status(HttpStatusCode.NO_CONTENT_204).end()
209 async function listAvailablePlugins (req: express.Request, res: express.Response) {
210 const query: PeertubePluginIndexList = req.query
212 const resultList = await listAvailablePluginsFromIndex(query)
216 status: HttpStatusCode.SERVICE_UNAVAILABLE_503,
217 message: 'Plugin index unavailable. Please retry later'
221 return res.json(resultList)