diff --git a/lib/util/settings.js b/lib/util/settings.js index a51bbdba62..6ba96cb30b 100644 --- a/lib/util/settings.js +++ b/lib/util/settings.js @@ -6,6 +6,7 @@ const fs = require('./fs'); const onChangeHandlers = []; const defaults = { + ban: [], permit_join: false, mqtt: { include_device_information: false, @@ -167,6 +168,17 @@ function addDevice(ieeeAddr) { writeRead(); } +function banDevice(ieeeAddr) { + const settings = getSettings(); + if (!settings.ban) { + settings.ban = []; + } + + settings.ban.push(ieeeAddr); + + writeRead(); +} + function removeDevice(ieeeAddr) { const settings = getSettings(); if (!settings.devices || !settings.devices[ieeeAddr]) return; @@ -291,6 +303,7 @@ module.exports = { getGroup, getGroups, getDevices, + banDevice: (ieeeAddr) => banDevice(ieeeAddr), addDevice: (ieeeAddr) => addDevice(ieeeAddr), removeDevice: (ieeeAddr) => removeDevice(ieeeAddr), addGroup: (name) => addGroup(name), diff --git a/lib/zigbee.js b/lib/zigbee.js index f8a26514e7..4a52f34b91 100644 --- a/lib/zigbee.js +++ b/lib/zigbee.js @@ -68,13 +68,13 @@ class Zigbee { ); callback(error); } else { - this.logStartupInfo(); + this._handleStarted(); callback(null); } }); }, utils.secondsToMilliseconds(60)); } else { - this.logStartupInfo(); + this._handleStarted(); callback(null); } }); @@ -83,6 +83,32 @@ class Zigbee { this.shepherd.on('ready', this.onReady); this.shepherd.on('ind', this.onMessage); this.shepherd.on('error', this.onError); + this._acceptDevIncoming = this._acceptDevIncoming.bind(this); + this.shepherd.acceptDevIncoming = this._acceptDevIncoming; + } + + _handleStarted() { + this.logStartupInfo(); + + this.getAllClients().forEach((device) => { + if (settings.get().ban.includes(device.ieeeAddr)) { + logger.warn(`Banned device is connected (${device.ieeeAddr}), removing..`); + this.removeDevice(device.ieeeAddr, false, () => {}); + } + }); + } + + _acceptDevIncoming(devInfo, callback) { + if (this.getPermitJoin()) { + if (settings.get().ban.includes(devInfo.ieeeAddr)) { + logger.info(`Banned device tried to connect (${devInfo.ieeeAddr})`); + callback(null, false); + } else { + callback(null, true); + } + } else { + callback(null, false); + } } logStartupInfo() { @@ -163,11 +189,16 @@ class Zigbee { } removeDevice(deviceID, ban, callback) { - this.shepherd.remove(deviceID, {reJoin: !ban}, (error) => { + if (ban) { + settings.banDevice(deviceID); + } + + this.shepherd.remove(deviceID, {reJoin: true}, (error) => { if (error) { logger.warn(`Failed to remove '${deviceID}', trying force remove...`); this.forceRemove(deviceID, callback); } else { + logger.info(`Removed ${deviceID}`); callback(null); } }); @@ -177,7 +208,10 @@ class Zigbee { const device = this.shepherd._findDevByAddr(deviceID); if (device) { - return this.shepherd._unregisterDev(device, (error) => callback(error)); + return this.shepherd._unregisterDev(device, (error) => { + logger.info(`Force removed ${deviceID}`); + callback(error) + }); } else { logger.warn(`Could not find ${deviceID} for force removal`); callback(true);