]>
Commit | Line | Data |
---|---|---|
345da516 C |
1 | import * as express from 'express' |
2 | import { PLUGIN_GLOBAL_CSS_PATH } from '../initializers/constants' | |
b5f919ac | 3 | import { join } from 'path' |
d75db01f | 4 | import { PluginManager, RegisteredPlugin } from '../lib/plugins/plugin-manager' |
4a8d113b | 5 | import { getPluginValidator, pluginStaticDirectoryValidator, getExternalAuthValidator } from '../middlewares/validators/plugins' |
b5f919ac | 6 | import { serveThemeCSSValidator } from '../middlewares/validators/themes' |
2d53be02 RK |
7 | import { HttpStatusCode } from '../../shared/core-utils/miscs/http-error-codes' |
8 | import { getCompleteLocale, is18nLocale } from '../../shared/core-utils/i18n' | |
b5f919ac | 9 | import { PluginType } from '../../shared/models/plugins/plugin.type' |
a8b666e9 | 10 | import { isTestInstance } from '../helpers/core-utils' |
4a8d113b | 11 | import { logger } from '@server/helpers/logger' |
a8b666e9 C |
12 | |
13 | const sendFileOptions = { | |
14 | maxAge: '30 days', | |
15 | immutable: !isTestInstance() | |
16 | } | |
345da516 C |
17 | |
18 | const pluginsRouter = express.Router() | |
19 | ||
b5f919ac | 20 | pluginsRouter.get('/plugins/global.css', |
2c053942 | 21 | servePluginGlobalCSS |
345da516 C |
22 | ) |
23 | ||
d75db01f C |
24 | pluginsRouter.get('/plugins/translations/:locale.json', |
25 | getPluginTranslations | |
26 | ) | |
27 | ||
4a8d113b C |
28 | pluginsRouter.get('/plugins/:pluginName/:pluginVersion/auth/:authName', |
29 | getPluginValidator(PluginType.PLUGIN), | |
30 | getExternalAuthValidator, | |
31 | handleAuthInPlugin | |
32 | ) | |
33 | ||
b5f919ac | 34 | pluginsRouter.get('/plugins/:pluginName/:pluginVersion/static/:staticEndpoint(*)', |
5e2b2e27 C |
35 | getPluginValidator(PluginType.PLUGIN), |
36 | pluginStaticDirectoryValidator, | |
345da516 C |
37 | servePluginStaticDirectory |
38 | ) | |
39 | ||
b5f919ac | 40 | pluginsRouter.get('/plugins/:pluginName/:pluginVersion/client-scripts/:staticEndpoint(*)', |
5e2b2e27 C |
41 | getPluginValidator(PluginType.PLUGIN), |
42 | pluginStaticDirectoryValidator, | |
345da516 C |
43 | servePluginClientScripts |
44 | ) | |
45 | ||
5e2b2e27 C |
46 | pluginsRouter.use('/plugins/:pluginName/router', |
47 | getPluginValidator(PluginType.PLUGIN, false), | |
48 | servePluginCustomRoutes | |
49 | ) | |
50 | ||
51 | pluginsRouter.use('/plugins/:pluginName/:pluginVersion/router', | |
52 | getPluginValidator(PluginType.PLUGIN), | |
53 | servePluginCustomRoutes | |
54 | ) | |
55 | ||
b5f919ac | 56 | pluginsRouter.get('/themes/:pluginName/:pluginVersion/static/:staticEndpoint(*)', |
5e2b2e27 C |
57 | getPluginValidator(PluginType.THEME), |
58 | pluginStaticDirectoryValidator, | |
b5f919ac C |
59 | servePluginStaticDirectory |
60 | ) | |
61 | ||
62 | pluginsRouter.get('/themes/:pluginName/:pluginVersion/client-scripts/:staticEndpoint(*)', | |
5e2b2e27 C |
63 | getPluginValidator(PluginType.THEME), |
64 | pluginStaticDirectoryValidator, | |
b5f919ac C |
65 | servePluginClientScripts |
66 | ) | |
67 | ||
68 | pluginsRouter.get('/themes/:themeName/:themeVersion/css/:staticEndpoint(*)', | |
69 | serveThemeCSSValidator, | |
70 | serveThemeCSSDirectory | |
71 | ) | |
72 | ||
345da516 C |
73 | // --------------------------------------------------------------------------- |
74 | ||
75 | export { | |
76 | pluginsRouter | |
77 | } | |
78 | ||
79 | // --------------------------------------------------------------------------- | |
80 | ||
2c053942 | 81 | function servePluginGlobalCSS (req: express.Request, res: express.Response) { |
a8b666e9 C |
82 | // Only cache requests that have a ?hash=... query param |
83 | const globalCSSOptions = req.query.hash | |
84 | ? sendFileOptions | |
85 | : {} | |
86 | ||
87 | return res.sendFile(PLUGIN_GLOBAL_CSS_PATH, globalCSSOptions) | |
2c053942 C |
88 | } |
89 | ||
d75db01f C |
90 | function getPluginTranslations (req: express.Request, res: express.Response) { |
91 | const locale = req.params.locale | |
92 | ||
93 | if (is18nLocale(locale)) { | |
94 | const completeLocale = getCompleteLocale(locale) | |
95 | const json = PluginManager.Instance.getTranslations(completeLocale) | |
96 | ||
97 | return res.json(json) | |
98 | } | |
99 | ||
2d53be02 | 100 | return res.sendStatus(HttpStatusCode.NOT_FOUND_404) |
d75db01f C |
101 | } |
102 | ||
345da516 C |
103 | function servePluginStaticDirectory (req: express.Request, res: express.Response) { |
104 | const plugin: RegisteredPlugin = res.locals.registeredPlugin | |
105 | const staticEndpoint = req.params.staticEndpoint | |
106 | ||
2c053942 C |
107 | const [ directory, ...file ] = staticEndpoint.split('/') |
108 | ||
109 | const staticPath = plugin.staticDirs[directory] | |
2d53be02 | 110 | if (!staticPath) return res.sendStatus(HttpStatusCode.NOT_FOUND_404) |
345da516 | 111 | |
2c053942 | 112 | const filepath = file.join('/') |
a8b666e9 | 113 | return res.sendFile(join(plugin.path, staticPath, filepath), sendFileOptions) |
345da516 C |
114 | } |
115 | ||
5e2b2e27 C |
116 | function servePluginCustomRoutes (req: express.Request, res: express.Response, next: express.NextFunction) { |
117 | const plugin: RegisteredPlugin = res.locals.registeredPlugin | |
118 | const router = PluginManager.Instance.getRouter(plugin.npmName) | |
119 | ||
2d53be02 | 120 | if (!router) return res.sendStatus(HttpStatusCode.NOT_FOUND_404) |
5e2b2e27 C |
121 | |
122 | return router(req, res, next) | |
123 | } | |
124 | ||
345da516 C |
125 | function servePluginClientScripts (req: express.Request, res: express.Response) { |
126 | const plugin: RegisteredPlugin = res.locals.registeredPlugin | |
127 | const staticEndpoint = req.params.staticEndpoint | |
128 | ||
2c053942 | 129 | const file = plugin.clientScripts[staticEndpoint] |
2d53be02 | 130 | if (!file) return res.sendStatus(HttpStatusCode.NOT_FOUND_404) |
2c053942 | 131 | |
a8b666e9 | 132 | return res.sendFile(join(plugin.path, staticEndpoint), sendFileOptions) |
345da516 | 133 | } |
b5f919ac C |
134 | |
135 | function serveThemeCSSDirectory (req: express.Request, res: express.Response) { | |
136 | const plugin: RegisteredPlugin = res.locals.registeredPlugin | |
137 | const staticEndpoint = req.params.staticEndpoint | |
138 | ||
139 | if (plugin.css.includes(staticEndpoint) === false) { | |
2d53be02 | 140 | return res.sendStatus(HttpStatusCode.NOT_FOUND_404) |
b5f919ac C |
141 | } |
142 | ||
a8b666e9 | 143 | return res.sendFile(join(plugin.path, staticEndpoint), sendFileOptions) |
b5f919ac | 144 | } |
4a8d113b C |
145 | |
146 | function handleAuthInPlugin (req: express.Request, res: express.Response) { | |
147 | const authOptions = res.locals.externalAuth | |
148 | ||
149 | try { | |
150 | logger.debug('Forwarding auth plugin request in %s of plugin %s.', authOptions.authName, res.locals.registeredPlugin.npmName) | |
151 | authOptions.onAuthRequest(req, res) | |
152 | } catch (err) { | |
dadc90bc | 153 | logger.error('Forward request error in auth %s of plugin %s.', authOptions.authName, res.locals.registeredPlugin.npmName, { err }) |
4a8d113b C |
154 | } |
155 | } |