Skip to content

Commit 8b1325f

Browse files
committed
Update Hue security
1 parent a9e997d commit 8b1325f

File tree

7 files changed

+291
-199
lines changed

7 files changed

+291
-199
lines changed

CHANGELOG.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,22 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
88

99
### ⚠️ Breaking Changes
1010

11+
- Align Hue Bridge processing to Philips' guidance on security, i.e. no self-signed certificates for orginal bridges
12+
1113
---
1214

1315
### ✨ Added
1416

1517
- HTTPS support for homeassistant LED devices (#1886)
18+
- Hue Bridge - Use https and certificates for all API calls, support Bridge Pro (V3)
19+
- Hue Bridge - Alternate certificate support
1620

1721
---
1822

19-
2023
### 🔧 Changed
2124

25+
- Hue Bridge - Wizard updates to support bridge-ids
26+
2227
- **Fixes:**
2328
- UI - Language is not selectable (#1877)
2429
- CEC-Handler is not stopped properly

assets/webconfig/i18n/en.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -668,6 +668,7 @@
668668
"edt_dev_spec_PBFiFo_title": "Pi-Blaster FiFo",
669669
"edt_dev_spec_baudrate_title": "Baudrate",
670670
"edt_dev_spec_blackLightsTimeout_title": "Signal detection timeout on black",
671+
"edt_dev_spec_bridgeid_title": "Bridge-ID",
671672
"edt_dev_spec_brightnessFactor_title": "Brightness factor",
672673
"edt_dev_spec_brightnessMax_title": "Brightness maximum",
673674
"edt_dev_spec_brightnessMin_title": "Brightness minimum",

assets/webconfig/js/wizards/LedDevice_philipshue.js

Lines changed: 34 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,10 @@ const philipshueWizard = (() => {
2929
if (hueIPs[hueIPsinc]) {
3030
const host = hueIPs[hueIPsinc].host;
3131
const port = hueIPs[hueIPsinc].port;
32+
const bridgeid = hueIPs[hueIPsinc].bridgeid ? hueIPs[hueIPsinc].bridgeid.toUpperCase() : undefined;
3233

3334
if (usr != '') {
34-
getProperties(cb, decodeURIComponent(host), port, usr);
35+
getProperties(cb, decodeURIComponent(host), port, bridgeid, usr);
3536
}
3637
else {
3738
cb(false, usr);
@@ -47,8 +48,9 @@ const philipshueWizard = (() => {
4748
if (reply) {
4849
//abort checking, first reachable result is used
4950
$('#wiz_hue_ipstate').html("");
50-
$('#host').val(hueIPs[hueIPsinc].host)
51-
$('#port').val(hueIPs[hueIPsinc].port)
51+
$('#host').val(hueIPs[hueIPsinc].host);
52+
$('#port').val(hueIPs[hueIPsinc].port);
53+
$('#bridgeid').val(hueIPs[hueIPsinc].bridgeid);
5254

5355
$('#usrcont').toggle(true);
5456

@@ -289,22 +291,26 @@ const philipshueWizard = (() => {
289291
if (device) {
290292
let host;
291293
let port;
294+
let bridgeid;
292295
if (discoveryMethod === "ssdp") {
293-
if (device.hostname && device.domain) {
296+
// Use hostname + domain, if available and not an IP address
297+
if (device.hostname && device.domain && !(isValidIPv4(device.hostname) || isValidIPv6(device.hostname))) {
294298
host = device.hostname + "." + device.domain;
295299
port = device.port;
296300
} else {
297301
host = device.ip;
298302
port = device.port;
299303
}
304+
bridgeid = device.other?.["hue-bridgeid"]?.toUpperCase();
300305
} else {
301-
host = device.service;
302-
port = device.port;
306+
host = device.service;
307+
port = device.port;
308+
bridgeid = device.txt?.["bridgeid"]?.toUpperCase();
303309
}
304-
if (host) {
305310

311+
if (host) {
306312
if (!hueIPs.some(item => item.host === host)) {
307-
hueIPs.push({ host: host, port: port });
313+
hueIPs.push({ host, port, bridgeid });
308314
}
309315
}
310316
}
@@ -313,19 +319,20 @@ const philipshueWizard = (() => {
313319
$('#wiz_hue_ipstate').html("");
314320
$('#host').val(hueIPs[hueIPsinc].host)
315321
$('#port').val(hueIPs[hueIPsinc].port)
322+
$('#bridgeid').val(hueIPs[hueIPsinc].bridgeid)
316323

317324
$('#hue_bridge_select').html("");
318325

319326
for (const key in hueIPs) {
320-
$('#hue_bridge_select').append(createSelOpt(key, hueIPs[key].host));
327+
$('#hue_bridge_select').append(createSelOpt(key, hueIPs[key].bridgeid));
321328
}
322329

323330
$('.hue_bridge_sel_watch').on("click", function () {
324331
hueIPsinc = $(this).val();
325332

326-
const name = $("#hue_bridge_select option:selected").text();
327-
$('#host').val(name);
328-
$('#port').val(hueIPs[hueIPsinc].port)
333+
$('#host').val(hueIPs[hueIPsinc].host);
334+
$('#port').val(hueIPs[hueIPsinc].port);
335+
$('#bridgeid').val(hueIPs[hueIPsinc].bridgeid);
329336

330337
const usr = $('#user').val();
331338
if (usr != "") {
@@ -361,8 +368,8 @@ const philipshueWizard = (() => {
361368
keyMap.set(username, ledDeviceProperties);
362369
}
363370

364-
async function getProperties(cb, hostAddress, port, username, resourceFilter) {
365-
let params = { host: hostAddress, username: username, filter: resourceFilter };
371+
async function getProperties(cb, hostAddress, port, bridgeid, username, resourceFilter) {
372+
let params = { host: hostAddress, bridgeid, username, filter: resourceFilter };
366373
if (port !== 'undefined') {
367374
params.port = parseInt(port);
368375
}
@@ -403,12 +410,12 @@ const philipshueWizard = (() => {
403410
}
404411
}
405412

406-
async function identify(hostAddress, port, username, name, id, id_v1) {
413+
async function identify(hostAddress, port, bridgeid, username, name, id, id_v1) {
407414
const disabled = $('#btn_wiz_save').is(':disabled');
408415
// Take care that new record cannot be save during background process
409416
$('#btn_wiz_save').prop('disabled', true);
410417

411-
let params = { host: decodeURIComponent(hostAddress), username: username, lightName: decodeURIComponent(name), lightId: id, lightId_v1: id_v1 };
418+
let params = { host: decodeURIComponent(hostAddress), bridgeid, username, lightName: decodeURIComponent(name), lightId: id, lightId_v1: id_v1 };
412419

413420
if (port !== 'undefined') {
414421
params.port = parseInt(port);
@@ -450,7 +457,7 @@ const philipshueWizard = (() => {
450457
else {
451458
$('#port').val('');
452459
}
453-
hueIPs.push({ host: host, port: port });
460+
hueIPs.push({ host, port });
454461

455462
if (usr != "") {
456463
checkHueBridge(checkUserResult, usr);
@@ -584,6 +591,7 @@ const philipshueWizard = (() => {
584591
let d = {};
585592
d.host = $('#host').val();
586593
d.port = parseInt($('#port').val());
594+
d.bridgeid = $('#bridgeid').val();
587595
d.username = $('#user').val();
588596
d.type = 'philipshue';
589597
d.colorOrder = 'rgb';
@@ -745,12 +753,13 @@ const philipshueWizard = (() => {
745753
$('#wizp2_body').on('click', '.btn-identify', function () {
746754
const hostname = $(this).data('hostname');
747755
const port = $(this).data('port');
756+
const bridgeid = $(this).data('bridgeid');
748757
const user = $(this).data('user');
749758
const lightName = $(this).data('light-name');
750759
const lightId = $(this).data('light-id');
751760
const lightId_v1 = $(this).data('light-id-v1');
752761

753-
identify(hostname, port, user, lightName, lightId, lightId_v1);
762+
identify(hostname, port, bridgeid, user, lightName, lightId, lightId_v1);
754763
});
755764
}
756765
function attachGroupButtonEvent() {
@@ -777,6 +786,7 @@ const philipshueWizard = (() => {
777786

778787
function get_hue_lights(username) {
779788
const host = hueIPs[hueIPsinc].host;
789+
const port = hueIPs[hueIPsinc].port;
780790

781791
const ledProperties = getLedDeviceProperty('philipshue', host, username);
782792
if (ledProperties) {
@@ -787,6 +797,8 @@ const philipshueWizard = (() => {
787797
}
788798
} else if (Array.isArray(ledProperties?.lights) && ledProperties.lights.length > 0) {
789799
hueLights = ledProperties.lights;
800+
} else {
801+
hueLights = ledProperties.lights;
790802
}
791803

792804
if (Object.keys(hueLights).length > 0) {
@@ -867,7 +879,7 @@ const philipshueWizard = (() => {
867879
'<select id="hue_' + lightId + '" class="hue_sel_watch form-control">'
868880
+ options
869881
+ '</select>',
870-
'<button class="btn btn-sm btn-primary btn-identify" data-hostname="' + encodeURIComponent($(" #host").val()) + '" data-port="' + $('#port').val() + '" data-user="' + $("#user").val() + '" data-light-name="' + encodeURIComponent(lightName) + '" data-light-id="' + lightId + '" data-light-id-v1="' + lightId_v1 + '">'
882+
'<button class="btn btn-sm btn-primary btn-identify" data-hostname="' + encodeURIComponent(host) + '" data-port="' + port + '" data-bridgeid="' + $('#bridgeid').val() + '" data-user="' + $("#user").val() + '" data-light-name="' + encodeURIComponent(lightName) + '" data-light-id="' + lightId + '" data-light-id-v1="' + lightId_v1 + '">'
871883
+ $.i18n('wiz_hue_blinkblue', id)
872884
+ '</button>']));
873885
}
@@ -931,8 +943,10 @@ const philipshueWizard = (() => {
931943
'<span class="input-group-addon">:</span>' +
932944
'<input type="text" class="input-group form-control" id="port" placeholder="' + $.i18n('edt_conf_general_port_title') + '"></div></div>';
933945
}
934-
935946
topContainer_html += '</div><p><span style="font-weight:bold;color:red" id="wiz_hue_ipstate"></span><span style="font-weight:bold;" id="wiz_hue_discovered"></span></p>';
947+
948+
// Hidden fields
949+
topContainer_html += '<div class="form-group" id="bridgeid" style="display:none"></div>';
936950
topContainer_html += '<div class="form-group" id="usrcont" style="display:none"></div>';
937951

938952
$('#wh_topcontainer').append(topContainer_html);

0 commit comments

Comments
 (0)