routes/pluginAssetRoutes.ts
Rama main · réplica de lectura del repositorio original.
import express from 'express';
import fs from 'fs';
import path from 'path';
import { PLUGINS_DIR } from '../core/loadPlugins';
import { PLACEHOLDER_FILE_RE } from '../core/placeholderImage';
/**
* Static assets materialized inside a plugin folder (currently the default cover).
*
* Served by a dedicated route rather than express.static(PLUGINS_DIR): the folder also
* holds plugin.json and .ts sources, which must never be reachable over HTTP. Only the
* content-hashed placeholder names are accepted, so the response can be cached forever.
*
* Public on purpose: covers show up on pages rendered before auth resolves (login
* redirects, PWA shell) and the image carries nothing sensitive.
*/
const router = express.Router();
const PLUGIN_ID_RE = /^[a-z][a-z0-9-]{1,29}$/;
router.get('/:pluginId/:file', (req: any, res: any) => {
const { pluginId, file } = req.params;
if (!PLUGIN_ID_RE.test(pluginId) || !PLACEHOLDER_FILE_RE.test(file)) {
return res.status(404).end();
}
const filePath = path.join(PLUGINS_DIR, pluginId, file);
if (!fs.existsSync(filePath)) return res.status(404).end();
// The file name carries a hash of its own bytes, so a changed image means a changed URL.
res.set('Cache-Control', 'public, max-age=31536000, immutable');
res.sendFile(filePath);
});
export default router;