From 4f9c36ee44007f418f82a8fc4ca172a1165b4d49 Mon Sep 17 00:00:00 2001 From: Koen Kanters Date: Sat, 19 Sep 2020 10:57:39 +0200 Subject: [PATCH] Don't allow renaming to not allowed friendlyName. https://github.com/Koenkk/zigbee2mqtt/issues/3281 --- lib/extension/bridge.js | 5 +++++ lib/util/settings.js | 7 +------ lib/util/utils.js | 11 +++++++++++ test/bridge.test.js | 12 ++++++++++++ 4 files changed, 29 insertions(+), 6 deletions(-) diff --git a/lib/extension/bridge.js b/lib/extension/bridge.js index d0843018a..7b2cadceb 100644 --- a/lib/extension/bridge.js +++ b/lib/extension/bridge.js @@ -307,6 +307,11 @@ class Bridge extends Extension { throw new Error('No device has joined since start'); } + const validationErrors = utils.validateFriendlyName(message.to); + if (validationErrors.length !== 0) { + throw new Error(validationErrors[0]); + } + const from = deviceAndHasLast ? this.lastJoinedDeviceIeeeAddr : message.from; const to = message.to; const homeAssisantRename = message.hasOwnProperty('homeassistant_rename') ? diff --git a/lib/util/settings.js b/lib/util/settings.js index ffa8136c6..389dce4a1 100644 --- a/lib/util/settings.js +++ b/lib/util/settings.js @@ -360,14 +360,9 @@ function validate() { // Verify that all friendly names are unique const names = []; - const postfixes = utils.getEndpointNames(); const check = (name) => { if (names.includes(name)) errors.push(`Duplicate friendly_name '${name}' found`); - if (postfixes.includes(name)) errors.push(`Following friendly_name are not allowed: '${postfixes}'`); - if (name.match(/.*\/\d*$/)) errors.push(`Friendly name cannot end with a "/DIGIT" ('${name}')`); - if (name.includes('#') || name.includes('+')) { - errors.push(`MQTT wildcard (+ and #) not allowed in friendly_name ('${name}')`); - } + errors.push(...utils.validateFriendlyName(name)); names.push(name); }; diff --git a/lib/util/utils.js b/lib/util/utils.js index 6a2d2a202..4982ace14 100644 --- a/lib/util/utils.js +++ b/lib/util/utils.js @@ -169,6 +169,16 @@ function toSnakeCase(value) { } } +function validateFriendlyName(name) { + const errors = []; + if (endpointNames.includes(name)) errors.push(`Following friendly_name are not allowed: '${endpointNames}'`); + if (name.match(/.*\/\d*$/)) errors.push(`Friendly name cannot end with a "/DIGIT" ('${name}')`); + if (name.includes('#') || name.includes('+')) { + errors.push(`MQTT wildcard (+ and #) not allowed in friendly_name ('${name}')`); + } + return errors; +} + module.exports = { millisecondsToSeconds: (milliseconds) => milliseconds / 1000, secondsToMilliseconds: (seconds) => seconds * 1000, @@ -188,4 +198,5 @@ module.exports = { capitalize, parseJSON, getExternalConvertersDefinitions, + validateFriendlyName, }; diff --git a/test/bridge.test.js b/test/bridge.test.js index 70a5b33fd..2cd3247f8 100644 --- a/test/bridge.test.js +++ b/test/bridge.test.js @@ -465,6 +465,18 @@ describe('Bridge', () => { ); }); + it('Should throw error when renaming device through not allowed friendlyName', async () => { + MQTT.publish.mockClear(); + MQTT.events.message('zigbee2mqtt/bridge/request/device/rename', stringify({from: 'bulb', to: 'bulb_new_name/1'})); + await flushPromises(); + console.log(MQTT.publish.mock.calls); + expect(MQTT.publish).toHaveBeenCalledWith( + 'zigbee2mqtt/bridge/response/device/rename', + stringify({"data":{},"status":"error","error":`Friendly name cannot end with a "/DIGIT" ('bulb_new_name/1')`}), + {retain: false, qos: 0}, expect.any(Function) + ); + }); + it('Should throw error when renaming last joined device but none has joined', async () => { MQTT.publish.mockClear(); MQTT.events.message('zigbee2mqtt/bridge/request/device/rename', stringify({last: true, to: 'bulb_new_name'}));