diff --git a/forge/db/controllers/Project.js b/forge/db/controllers/Project.js index bb1e872a64..77f46d44ee 100644 --- a/forge/db/controllers/Project.js +++ b/forge/db/controllers/Project.js @@ -183,7 +183,7 @@ module.exports = { const moduleList = result.palette?.modules || await app.db.controllers.StorageSettings.getProjectModules(project) || [] const modules = {} moduleList.forEach(module => { - modules[module.name] = module.version + modules[module.name] = module.version || '*' }) // ensure email alert settings for resources have a value that matches // what we show in the UI when no value is set in the DB diff --git a/forge/routes/logging/index.js b/forge/routes/logging/index.js index ad0b3497f3..4c35d0a656 100644 --- a/forge/routes/logging/index.js +++ b/forge/routes/logging/index.js @@ -133,7 +133,7 @@ module.exports = async function (app) { // handle some special cases: install/remove modules if (event === 'nodes.install' && !error) { - await app.db.controllers.Project.addProjectModule(request.project, auditEvent.module, auditEvent.version) + await app.db.controllers.Project.addProjectModule(request.project, auditEvent.module, auditEvent.version || '*') } else if (event === 'nodes.remove' && !error) { await app.db.controllers.Project.removeProjectModule(request.project, auditEvent.module) } else if (event === 'modules.install' && !error) { diff --git a/test/unit/forge/db/controllers/Project_spec.js b/test/unit/forge/db/controllers/Project_spec.js index 131f026d3f..7a4a27dad1 100644 --- a/test/unit/forge/db/controllers/Project_spec.js +++ b/test/unit/forge/db/controllers/Project_spec.js @@ -195,6 +195,27 @@ describe('Project controller', function () { result.palette.modules.should.have.property('node-red-node-ping', '0.3.3') // unchanged (still has project value) result.palette.modules.should.not.have.property('node-red-node-badwords') // template item NOT merged into project settings }) + it('defaults a module saved without a version to any version in runtime settings', async function () { + const project = await app.db.models.Project.create({ + name: 'testProject-001b', + type: '', + url: '' + }) + await project.updateSetting('settings', { + palette: { + modules: [ + { name: 'node-red-node-random', version: '1.2.3', local: true }, + { name: '@flowfuse-certified-nodes/redis', local: true } + ] + } + }) + + const reloadedProject = await app.db.models.Project.byId(project.id) + const result = await app.db.controllers.Project.getRuntimeSettings(reloadedProject) + + result.palette.modules.should.have.property('node-red-node-random', '1.2.3') + result.palette.modules.should.have.property('@flowfuse-certified-nodes/redis', '*') + }) }) describe('addProjectModule', function () { diff --git a/test/unit/forge/routes/logging/index_spec.js b/test/unit/forge/routes/logging/index_spec.js index 9991b67563..0b5d068554 100644 --- a/test/unit/forge/routes/logging/index_spec.js +++ b/test/unit/forge/routes/logging/index_spec.js @@ -142,6 +142,22 @@ describe('Logging API', function () { args[2].should.equal('0.4.0') }) + it('Adds module with any version to instance settings for nodes.install event without a version', async function () { + const url = `/logging/${TestObjects.project1.id}/audit` + const response = await app.inject({ + method: 'POST', + url, + headers: { + authorization: `Bearer ${TestObjects.tokens.project1}` + }, + payload: { event: 'nodes.install', module: '@flowfuse/unversioned', path: '/nodes' } + }) + response.should.have.property('statusCode', 200) + const args = app.db.controllers.Project.addProjectModule.lastCall.args + args[1].should.equal('@flowfuse/unversioned') + args[2].should.equal('*') + }) + it('Does not add module to instance settings for nodes.install event with error', async function () { const url = `/logging/${TestObjects.project1.id}/audit` const response = await app.inject({