X-Git-Url: https://git.immae.eu/?a=blobdiff_plain;f=server%2Fcontrollers%2Fplugins.ts;h=51db1ad89f4c5798ffce0d50fd6e0275df2ccd1e;hb=0260dc8aca952f9412a8620e433b9e16e675696e;hp=f255d13e840ec3b279ca7b06583534cf853b3186;hpb=b5f919ac8eb2a1c20e26582fdfd377d687710d8f;p=github%2FChocobozzz%2FPeerTube.git diff --git a/server/controllers/plugins.ts b/server/controllers/plugins.ts index f255d13e8..51db1ad89 100644 --- a/server/controllers/plugins.ts +++ b/server/controllers/plugins.ts @@ -1,10 +1,20 @@ -import * as express from 'express' -import { PLUGIN_GLOBAL_CSS_PATH } from '../initializers/constants' +import express from 'express' import { join } from 'path' -import { RegisteredPlugin } from '../lib/plugins/plugin-manager' -import { servePluginStaticDirectoryValidator } from '../middlewares/validators/plugins' -import { serveThemeCSSValidator } from '../middlewares/validators/themes' +import { logger } from '@server/helpers/logger' +import { optionalAuthenticate } from '@server/middlewares/auth' +import { getCompleteLocale, is18nLocale } from '../../shared/core-utils/i18n' +import { HttpStatusCode } from '../../shared/models/http/http-error-codes' import { PluginType } from '../../shared/models/plugins/plugin.type' +import { isProdInstance } from '../helpers/core-utils' +import { PLUGIN_GLOBAL_CSS_PATH } from '../initializers/constants' +import { PluginManager, RegisteredPlugin } from '../lib/plugins/plugin-manager' +import { getExternalAuthValidator, getPluginValidator, pluginStaticDirectoryValidator } from '../middlewares/validators/plugins' +import { serveThemeCSSValidator } from '../middlewares/validators/themes' + +const sendFileOptions = { + maxAge: '30 days', + immutable: isProdInstance() +} const pluginsRouter = express.Router() @@ -12,23 +22,49 @@ pluginsRouter.get('/plugins/global.css', servePluginGlobalCSS ) +pluginsRouter.get('/plugins/translations/:locale.json', + getPluginTranslations +) + +pluginsRouter.get('/plugins/:pluginName/:pluginVersion/auth/:authName', + getPluginValidator(PluginType.PLUGIN), + getExternalAuthValidator, + handleAuthInPlugin +) + pluginsRouter.get('/plugins/:pluginName/:pluginVersion/static/:staticEndpoint(*)', - servePluginStaticDirectoryValidator(PluginType.PLUGIN), + getPluginValidator(PluginType.PLUGIN), + pluginStaticDirectoryValidator, servePluginStaticDirectory ) pluginsRouter.get('/plugins/:pluginName/:pluginVersion/client-scripts/:staticEndpoint(*)', - servePluginStaticDirectoryValidator(PluginType.PLUGIN), + getPluginValidator(PluginType.PLUGIN), + pluginStaticDirectoryValidator, servePluginClientScripts ) +pluginsRouter.use('/plugins/:pluginName/router', + getPluginValidator(PluginType.PLUGIN, false), + optionalAuthenticate, + servePluginCustomRoutes +) + +pluginsRouter.use('/plugins/:pluginName/:pluginVersion/router', + getPluginValidator(PluginType.PLUGIN), + optionalAuthenticate, + servePluginCustomRoutes +) + pluginsRouter.get('/themes/:pluginName/:pluginVersion/static/:staticEndpoint(*)', - servePluginStaticDirectoryValidator(PluginType.THEME), + getPluginValidator(PluginType.THEME), + pluginStaticDirectoryValidator, servePluginStaticDirectory ) pluginsRouter.get('/themes/:pluginName/:pluginVersion/client-scripts/:staticEndpoint(*)', - servePluginStaticDirectoryValidator(PluginType.THEME), + getPluginValidator(PluginType.THEME), + pluginStaticDirectoryValidator, servePluginClientScripts ) @@ -46,7 +82,25 @@ export { // --------------------------------------------------------------------------- function servePluginGlobalCSS (req: express.Request, res: express.Response) { - return res.sendFile(PLUGIN_GLOBAL_CSS_PATH) + // Only cache requests that have a ?hash=... query param + const globalCSSOptions = req.query.hash + ? sendFileOptions + : {} + + return res.sendFile(PLUGIN_GLOBAL_CSS_PATH, globalCSSOptions) +} + +function getPluginTranslations (req: express.Request, res: express.Response) { + const locale = req.params.locale + + if (is18nLocale(locale)) { + const completeLocale = getCompleteLocale(locale) + const json = PluginManager.Instance.getTranslations(completeLocale) + + return res.json(json) + } + + return res.status(HttpStatusCode.NOT_FOUND_404).end() } function servePluginStaticDirectory (req: express.Request, res: express.Response) { @@ -56,12 +110,19 @@ function servePluginStaticDirectory (req: express.Request, res: express.Response const [ directory, ...file ] = staticEndpoint.split('/') const staticPath = plugin.staticDirs[directory] - if (!staticPath) { - return res.sendStatus(404) - } + if (!staticPath) return res.status(HttpStatusCode.NOT_FOUND_404).end() const filepath = file.join('/') - return res.sendFile(join(plugin.path, staticPath, filepath)) + return res.sendFile(join(plugin.path, staticPath, filepath), sendFileOptions) +} + +function servePluginCustomRoutes (req: express.Request, res: express.Response, next: express.NextFunction) { + const plugin: RegisteredPlugin = res.locals.registeredPlugin + const router = PluginManager.Instance.getRouter(plugin.npmName) + + if (!router) return res.status(HttpStatusCode.NOT_FOUND_404).end() + + return router(req, res, next) } function servePluginClientScripts (req: express.Request, res: express.Response) { @@ -69,11 +130,9 @@ function servePluginClientScripts (req: express.Request, res: express.Response) const staticEndpoint = req.params.staticEndpoint const file = plugin.clientScripts[staticEndpoint] - if (!file) { - return res.sendStatus(404) - } + if (!file) return res.status(HttpStatusCode.NOT_FOUND_404).end() - return res.sendFile(join(plugin.path, staticEndpoint)) + return res.sendFile(join(plugin.path, staticEndpoint), sendFileOptions) } function serveThemeCSSDirectory (req: express.Request, res: express.Response) { @@ -81,8 +140,19 @@ function serveThemeCSSDirectory (req: express.Request, res: express.Response) { const staticEndpoint = req.params.staticEndpoint if (plugin.css.includes(staticEndpoint) === false) { - return res.sendStatus(404) + return res.status(HttpStatusCode.NOT_FOUND_404).end() } - return res.sendFile(join(plugin.path, staticEndpoint)) + return res.sendFile(join(plugin.path, staticEndpoint), sendFileOptions) +} + +function handleAuthInPlugin (req: express.Request, res: express.Response) { + const authOptions = res.locals.externalAuth + + try { + logger.debug('Forwarding auth plugin request in %s of plugin %s.', authOptions.authName, res.locals.registeredPlugin.npmName) + authOptions.onAuthRequest(req, res) + } catch (err) { + logger.error('Forward request error in auth %s of plugin %s.', authOptions.authName, res.locals.registeredPlugin.npmName, { err }) + } }