From 6c5b22684bdb30598dd7166f8fd4104ab7bd177b Mon Sep 17 00:00:00 2001 From: cliffmccarthy <16453869+cliffmccarthy@users.noreply.github.com> Date: Wed, 11 Jun 2025 08:52:36 -0500 Subject: [PATCH 1/4] fix: Revise package hash check in Docker entrypoint.sh (#13483) - In the build_forum() function, the file install_hash.md5 is intended to track the content of package.json and detect changes that imply the need to run 'nodebb upgrade'. - The check to compare the current checksum of package.json to the one saved in install_hash.md5 is reversed. The "package.json was updated" branch is taken when the hashes are the same, not when they are different. - When install_hash.md5 does not exist, the comparison value becomes the null string, which never matches the checksum of package.json. As a result, the code always takes the "No changes in package.json" branch and returns from the function without creating install_hash.md5. As a result, install_hash.md5 never gets created on a new installation. - Revised build_forum() to use "not equals" when comparing the two checksums. This causes it to run 'nodebb upgrade' when the checksums are different, and also when install_hash.md5 does not yet exist. If the checksum saved in install_hash.md5 matches the current package.json checksum, it proceeds to either the "Build before start" case or the "No changes" case. --- install/docker/entrypoint.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/docker/entrypoint.sh b/install/docker/entrypoint.sh index dd17d707e7..db2a637ee0 100755 --- a/install/docker/entrypoint.sh +++ b/install/docker/entrypoint.sh @@ -103,7 +103,7 @@ build_forum() { local config="$1" local start_build="$2" local package_hash=$(md5sum install/package.json | head -c 32) - if [ "$package_hash" = "$(cat $CONFIG_DIR/install_hash.md5 || true)" ]; then + if [ "$package_hash" != "$(cat $CONFIG_DIR/install_hash.md5 || true)" ]; then echo "package.json was updated. Upgrading..." /usr/src/app/nodebb upgrade --config="$config" || { echo "Failed to build NodeBB. Exiting..." From 84d99a0fc775f01e1dc28b4c80ad78b58d539263 Mon Sep 17 00:00:00 2001 From: Eli Sheinfeld Date: Wed, 11 Jun 2025 20:13:23 +0300 Subject: [PATCH 2/4] feat: Add live reload functionality with Grunt watch and Socket.IO (#13489) - Added livereload event to Grunt watch tasks for instant browser refresh - Integrated Socket.IO WebSocket communication for real-time updates - Enhanced development workflow with immediate file change detection - Improved developer experience with automatic browser reload on file changes Changes: - Gruntfile.js: Send livereload message when files change - src/start.js: Handle livereload events and broadcast via Socket.IO --- Gruntfile.js | 2 ++ src/start.js | 7 +++++++ 2 files changed, 9 insertions(+) diff --git a/Gruntfile.js b/Gruntfile.js index dcfa831cd6..53a4b7e06f 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -174,6 +174,8 @@ module.exports = function (grunt) { } if (worker) { worker.send({ compiling: compiling }); + // Send livereload event via Socket.IO for instant browser refresh + worker.send({ livereload: true }); } }); }); diff --git a/src/start.js b/src/start.js index 99f3b662c5..a15aa44c6a 100644 --- a/src/start.js +++ b/src/start.js @@ -115,6 +115,13 @@ function addProcessHandlers() { const translator = require('./translator'); translator.flush(); } + } else if (msg && msg.livereload) { + // Send livereload event to all connected clients via Socket.IO + const websockets = require('./socket.io'); + if (websockets.server) { + websockets.server.emit('event:livereload'); + winston.info('[livereload] Sent reload event to all clients'); + } } }); } From dc37789b5dd4888332c6ef4c3ede65fedcdd2452 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bar=C4=B1=C5=9F=20Soner=20U=C5=9Fakl=C4=B1?= Date: Wed, 11 Jun 2025 13:16:52 -0400 Subject: [PATCH 3/4] refactor: send single message --- Gruntfile.js | 7 ++++--- src/start.js | 30 +++++++++++++++++------------- 2 files changed, 21 insertions(+), 16 deletions(-) diff --git a/Gruntfile.js b/Gruntfile.js index 53a4b7e06f..60d8f8b23e 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -173,9 +173,10 @@ module.exports = function (grunt) { winston.error(err.stack); } if (worker) { - worker.send({ compiling: compiling }); - // Send livereload event via Socket.IO for instant browser refresh - worker.send({ livereload: true }); + worker.send({ + compiling: compiling, + livereload: true, // Send livereload event via Socket.IO for instant browser refresh + }); } }); }); diff --git a/src/start.js b/src/start.js index a15aa44c6a..c4dd925aad 100644 --- a/src/start.js +++ b/src/start.js @@ -107,20 +107,24 @@ function addProcessHandlers() { shutdown(1); }); process.on('message', (msg) => { - if (msg && Array.isArray(msg.compiling)) { - if (msg.compiling.includes('tpl')) { - const benchpressjs = require('benchpressjs'); - benchpressjs.flush(); - } else if (msg.compiling.includes('lang')) { - const translator = require('./translator'); - translator.flush(); + if (msg) { + if (Array.isArray(msg.compiling)) { + if (msg.compiling.includes('tpl')) { + const benchpressjs = require('benchpressjs'); + benchpressjs.flush(); + } else if (msg.compiling.includes('lang')) { + const translator = require('./translator'); + translator.flush(); + } } - } else if (msg && msg.livereload) { - // Send livereload event to all connected clients via Socket.IO - const websockets = require('./socket.io'); - if (websockets.server) { - websockets.server.emit('event:livereload'); - winston.info('[livereload] Sent reload event to all clients'); + + if (msg.livereload) { + // Send livereload event to all connected clients via Socket.IO + const websockets = require('./socket.io'); + if (websockets.server) { + websockets.server.emit('event:livereload'); + winston.info('[livereload] Sent reload event to all clients'); + } } } }); From da2597f81ce5c7df5e02a90d5215e2da087d1f47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bar=C4=B1=C5=9F=20Soner=20U=C5=9Fakl=C4=B1?= Date: Wed, 11 Jun 2025 17:13:56 -0400 Subject: [PATCH 4/4] fix: sanitize svg when uploading site-logo, default avatar and og:image --- src/controllers/admin/uploads.js | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/controllers/admin/uploads.js b/src/controllers/admin/uploads.js index 56d64674cf..ccd4261b36 100644 --- a/src/controllers/admin/uploads.js +++ b/src/controllers/admin/uploads.js @@ -258,10 +258,6 @@ uploadsController.uploadMaskableIcon = async function (req, res, next) { } }; -uploadsController.uploadLogo = async function (req, res, next) { - await upload('site-logo', req, res, next); -}; - uploadsController.uploadFile = async function (req, res, next) { const uploadedFile = req.files.files[0]; let params; @@ -285,6 +281,10 @@ uploadsController.uploadFile = async function (req, res, next) { } }; +uploadsController.uploadLogo = async function (req, res, next) { + await upload('site-logo', req, res, next); +}; + uploadsController.uploadDefaultAvatar = async function (req, res, next) { await upload('avatar-default', req, res, next); }; @@ -296,6 +296,10 @@ uploadsController.uploadOgImage = async function (req, res, next) { async function upload(name, req, res, next) { const uploadedFile = req.files.files[0]; + if (uploadedFile.path.endsWith('.svg')) { + await sanitizeSvg(uploadedFile.path); + } + await validateUpload(uploadedFile, allowedImageTypes); const filename = name + path.extname(uploadedFile.name); await uploadImage(filename, 'system', uploadedFile, req, res, next);