Release v1.5.10

This commit is contained in:
2026-07-26 12:32:01 +01:00
parent b5fbf79af7
commit 07ec17ad91
24 changed files with 1113 additions and 352 deletions
+49 -1
View File
@@ -8,6 +8,7 @@ module.exports = function registerAdminContentRoutes(app, deps) {
const collectUploadReferencesFromSlide = deps.collectUploadReferencesFromSlide;
const collectUploadReferencesFromTemplate = deps.collectUploadReferencesFromTemplate;
const collectUploadReferencesFromPayload = deps.collectUploadReferencesFromPayload;
const removeUnusedUploadFiles = deps.removeUnusedUploadFiles;
const syncPlaylistUploadsOnChange = deps.syncPlaylistUploadsOnChange;
const getAuditUserId = deps.getAuditUserId;
const redirectAfterSave = deps.redirectAfterSave;
@@ -18,14 +19,30 @@ module.exports = function registerAdminContentRoutes(app, deps) {
const getTemplateDeleteBlockMessage = deps.getTemplateDeleteBlockMessage;
const getCanvasSizeDeleteBlockMessage = deps.getCanvasSizeDeleteBlockMessage;
const requirePermission = deps.requirePermission;
const hasAnyPermission = deps.hasAnyPermission;
const { buildPagination } = require('../../lib/pagination');
const LIST_PAGE_SIZE = 10;
if (!pool || !common || !pages || !upload || typeof fetchScreensBySlideId !== 'function' || typeof fetchScreensByTemplateId !== 'function' || typeof collectUploadReferencesFromSlide !== 'function' || typeof collectUploadReferencesFromTemplate !== 'function' || typeof collectUploadReferencesFromPayload !== 'function' || typeof syncPlaylistUploadsOnChange !== 'function' || typeof getAuditUserId !== 'function' || typeof redirectAfterSave !== 'function' || typeof notifyPlayerScreens !== 'function' || typeof broadcastDashboardState !== 'function' || typeof getSlideDeleteBlockMessage !== 'function' || typeof getTemplateDeleteBlockMessage !== 'function' || typeof getCanvasSizeDeleteBlockMessage !== 'function') {
if (!pool || !common || !pages || !upload || typeof fetchScreensBySlideId !== 'function' || typeof fetchScreensByTemplateId !== 'function' || typeof collectUploadReferencesFromSlide !== 'function' || typeof collectUploadReferencesFromTemplate !== 'function' || typeof collectUploadReferencesFromPayload !== 'function' || typeof removeUnusedUploadFiles !== 'function' || typeof syncPlaylistUploadsOnChange !== 'function' || typeof getAuditUserId !== 'function' || typeof redirectAfterSave !== 'function' || typeof notifyPlayerScreens !== 'function' || typeof broadcastDashboardState !== 'function' || typeof getSlideDeleteBlockMessage !== 'function' || typeof getTemplateDeleteBlockMessage !== 'function' || typeof getCanvasSizeDeleteBlockMessage !== 'function' || typeof hasAnyPermission !== 'function') {
throw new Error('registerAdminContentRoutes requires the content route dependencies.');
}
function requireSlideUploadPermission(req, res, next) {
if (!req.currentUser) {
return res.redirect('/login?message=' + encodeURIComponent('Please sign in to continue.'));
}
if (hasAnyPermission(req.currentUser, ['slides.create', 'slides.update'])) {
return next();
}
const error = new Error('You do not have permission to access this area.');
error.statusCode = 403;
error.expose = true;
next(error);
}
function queueSlideThumbnailRefresh(slideId, previousThumbnailPath) {
if (!backgroundTaskQueue || typeof backgroundTaskQueue.enqueueTask !== 'function') {
return Promise.resolve(null);
@@ -145,6 +162,37 @@ module.exports = function registerAdminContentRoutes(app, deps) {
}
});
app.post('/slides/uploads', requireSlideUploadPermission, upload.single('file'), async function (req, res, next) {
try {
if (!req.file) {
return res.status(400).json({ error: 'No file was uploaded.' });
}
res.json({
path: '/media/uploads/' + req.file.filename,
filename: req.file.filename,
originalName: req.file.originalname || ''
});
} catch (error) {
next(error);
}
});
app.post('/slides/uploads/cleanup', requireSlideUploadPermission, async function (req, res, next) {
try {
const uploadPaths = Array.isArray(req.body && req.body.uploadPaths)
? req.body.uploadPaths
: Array.isArray(req.body && req.body.paths)
? req.body.paths
: [];
await removeUnusedUploadFiles(pool, deps.uploadDir, uploadPaths);
res.json({ ok: true });
} catch (error) {
next(error);
}
});
app.post('/slides', requirePermission('slides.create'), upload.any(), async function (req, res, next) {
try {
const payload = await common.buildSlidePayload(pool, req, null);
+11 -1
View File
@@ -369,7 +369,17 @@ module.exports = function registerAdminRbacRoutes(app, deps) {
return res.redirect('/rbac/' + roleId + '/edit?message=' + encodeURIComponent('One or more selected permissions are invalid.'));
}
await rbacData.syncRolePermissions(pool, roleId, normalizedPermissionKeys);
const connection = await pool.getConnection();
try {
await connection.beginTransaction();
await rbacData.syncRolePermissions(connection, roleId, normalizedPermissionKeys);
await connection.commit();
} catch (error) {
await connection.rollback();
throw error;
} finally {
connection.release();
}
res.redirect('/rbac/' + roleId + '/edit?message=' + encodeURIComponent('Permissions updated.'));
} catch (error) {
next(error);