@homebridge-plugins/homebridge-resideo 3.1.3 → 3.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,10 @@
1
+ ## v3.1.4 (2026-07-20)
2
+
3
+ ### Changed
4
+
5
+ - fix(ui): use the working resideo api host for login, so the setup flow stops failing on an expired certificate (#927) (@cowboydaks) (@carlosfranceschi)
6
+ - fix(ui): exchange the login code with fetch instead of shelling out to curl
7
+
1
8
  ## v3.1.3 (2026-07-20)
2
9
 
3
10
  ### Changed
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/homebridge-ui/server.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,wBAAwB,EAAE,MAAM,6BAA6B,CAAA;AAStE,qBAAa,cAAe,SAAQ,wBAAwB;IACnD,GAAG,EAAG,MAAM,CAAA;IACZ,MAAM,EAAG,MAAM,CAAA;IACf,QAAQ,EAAG,MAAM,CAAA;;CAyHzB"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/homebridge-ui/server.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,wBAAwB,EAAE,MAAM,6BAA6B,CAAA;AAwBtE,qBAAa,cAAe,SAAQ,wBAAwB;IACnD,GAAG,EAAG,MAAM,CAAA;IACZ,MAAM,EAAG,MAAM,CAAA;IACf,QAAQ,EAAG,MAAM,CAAA;;CA2IzB"}
@@ -1,11 +1,23 @@
1
1
  import { Buffer } from 'node:buffer';
2
- import { exec as execCb } from 'node:child_process';
3
2
  import fs from 'node:fs';
4
3
  import http from 'node:http';
5
- import util from 'node:util';
6
4
  /* eslint-disable no-console */
7
5
  import { HomebridgePluginUiServer } from '@homebridge/plugin-ui-utils';
8
- const exec = util.promisify(execCb);
6
+ import { AuthorizeURL, TokenURL } from '../settings.js';
7
+ /**
8
+ * Escape text that is about to be written into the setup page.
9
+ *
10
+ * The failure messages come from Resideo, so they are not ours to trust with
11
+ * raw HTML.
12
+ */
13
+ function escapeHtml(value) {
14
+ return value
15
+ .replace(/&/g, '&')
16
+ .replace(/</g, '&lt;')
17
+ .replace(/>/g, '&gt;')
18
+ .replace(/"/g, '&quot;')
19
+ .replace(/'/g, '&#39;');
20
+ }
9
21
  export class PluginUiServer extends HomebridgePluginUiServer {
10
22
  key;
11
23
  secret;
@@ -25,7 +37,7 @@ export class PluginUiServer extends HomebridgePluginUiServer {
25
37
  this.secret = query.get('secret');
26
38
  this.hostname = query.get('host');
27
39
  const redirectUrl = `http://${this.hostname}:8585/auth`;
28
- const authUrl = `https://api.honeywell.com/oauth2/authorize?response_type=code&appSelect=1&redirect_uri=${encodeURI(redirectUrl)}&client_id=${query.get('key')}`;
40
+ const authUrl = `${AuthorizeURL}response_type=code&appSelect=1&redirect_uri=${encodeURI(redirectUrl)}&client_id=${encodeURIComponent(this.key)}`;
29
41
  res.end(`<script>window.location.replace('${authUrl}');</script>`);
30
42
  break;
31
43
  }
@@ -33,20 +45,26 @@ export class PluginUiServer extends HomebridgePluginUiServer {
33
45
  if (query.get('code')) {
34
46
  const code = query.get('code');
35
47
  const auth = Buffer.from(`${this.key}:${this.secret}`).toString('base64');
36
- let curlString = '';
37
- curlString += 'curl -X POST ';
38
- curlString += `--header "Authorization: Basic ${auth}" `;
39
- curlString += '--header "Accept: application/json" ';
40
- curlString += '--header "Content-Type: application/x-www-form-urlencoded" ';
41
- curlString += '-d "';
42
- curlString += 'grant_type=authorization_code&';
43
- curlString += `code=${code}&`;
44
- curlString += `redirect_uri=${encodeURI(`http://${this.hostname}:8585/auth`)}`;
45
- curlString += '" ';
46
- curlString += '"https://api.honeywell.com/oauth2/token"';
47
48
  try {
48
- const { stdout } = await exec(curlString);
49
- const response = JSON.parse(stdout);
49
+ // Exchanged with fetch rather than by shelling out to curl:
50
+ // curl is not present on every install, it validates against
51
+ // the system CA store rather than the one Node ships, and
52
+ // building a shell command by hand means anything arriving in
53
+ // the query string ends up inside that command.
54
+ const tokenResponse = await fetch(TokenURL, {
55
+ method: 'POST',
56
+ headers: {
57
+ 'Authorization': `Basic ${auth}`,
58
+ 'Accept': 'application/json',
59
+ 'Content-Type': 'application/x-www-form-urlencoded',
60
+ },
61
+ body: new URLSearchParams({
62
+ grant_type: 'authorization_code',
63
+ code,
64
+ redirect_uri: `http://${this.hostname}:8585/auth`,
65
+ }),
66
+ });
67
+ const response = await tokenResponse.json();
50
68
  if (response.access_token) {
51
69
  this.pushEvent('creds-received', {
52
70
  key: this.key,
@@ -57,11 +75,16 @@ export class PluginUiServer extends HomebridgePluginUiServer {
57
75
  res.end('Success. You can close this window now.');
58
76
  }
59
77
  else {
60
- res.end('oops.');
78
+ // Report only what Resideo said went wrong. The request
79
+ // carries the consumer secret, so the request itself must
80
+ // never be echoed back to the page.
81
+ const reason = response.error_description ?? response.error ?? `unexpected response (HTTP ${tokenResponse.status})`;
82
+ res.end(`<strong>Could not get a token:</strong><br>${escapeHtml(reason)}<br><br>Close this window and start again`);
61
83
  }
62
84
  }
63
85
  catch (err) {
64
- res.end(`<strong>An error occurred:</strong><br>${JSON.stringify(err)}<br><br>Close this window and start again`);
86
+ const reason = err instanceof Error ? err.message : String(err);
87
+ res.end(`<strong>An error occurred:</strong><br>${escapeHtml(reason)}<br><br>Close this window and start again`);
65
88
  }
66
89
  }
67
90
  else {
@@ -1 +1 @@
1
- {"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/homebridge-ui/server.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/homebridge-ui/server.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=server.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.test.d.ts","sourceRoot":"","sources":["../../src/homebridge-ui/server.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,37 @@
1
+ import { readFileSync } from 'node:fs';
2
+ import { join } from 'node:path';
3
+ import { describe, expect, it } from 'vitest';
4
+ import { AuthorizeURL, TokenURL } from '../settings.js';
5
+ const source = readFileSync(join(import.meta.dirname, 'server.ts'), 'utf8');
6
+ describe('setup server', () => {
7
+ it('uses the same host as the rest of the plugin', () => {
8
+ // api.honeywell.com served an expired certificate from 18 May 2026, which
9
+ // broke the login flow for everyone while the plugin itself kept working
10
+ // on api.honeywellhome.com (#927).
11
+ expect(AuthorizeURL).toContain('api.honeywellhome.com');
12
+ expect(TokenURL).toContain('api.honeywellhome.com');
13
+ });
14
+ it('does not hardcode an api host of its own', () => {
15
+ expect(source).not.toContain('api.honeywell.com/');
16
+ expect(source).not.toContain('https://api.honeywellhome.com');
17
+ });
18
+ it('exchanges the code without shelling out', () => {
19
+ // curl is not installed everywhere, it trusts the system CA store rather
20
+ // than the one Node ships, and a hand-built command line means query
21
+ // string values end up inside it.
22
+ expect(source).not.toContain('child_process');
23
+ expect(source).not.toMatch(/\bexec\(/);
24
+ expect(source).not.toContain('curlString');
25
+ expect(source).toContain('await fetch(TokenURL');
26
+ });
27
+ it('never echoes the request back to the page', () => {
28
+ // The token request carries the consumer secret in a Basic auth header, so
29
+ // dumping the error object (which used to include the whole command) put
30
+ // the user's own secret on screen.
31
+ expect(source).not.toContain('JSON.stringify(err)');
32
+ });
33
+ it('escapes anything it writes into the page', () => {
34
+ expect(source).toContain('escapeHtml');
35
+ });
36
+ });
37
+ //# sourceMappingURL=server.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.test.js","sourceRoot":"","sources":["../../src/homebridge-ui/server.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AACtC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAEhC,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAA;AAE7C,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AAEvD,MAAM,MAAM,GAAG,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,WAAW,CAAC,EAAE,MAAM,CAAC,CAAA;AAE3E,QAAQ,CAAC,cAAc,EAAE,GAAG,EAAE;IAC5B,EAAE,CAAC,8CAA8C,EAAE,GAAG,EAAE;QACtD,0EAA0E;QAC1E,yEAAyE;QACzE,mCAAmC;QACnC,MAAM,CAAC,YAAY,CAAC,CAAC,SAAS,CAAC,uBAAuB,CAAC,CAAA;QACvD,MAAM,CAAC,QAAQ,CAAC,CAAC,SAAS,CAAC,uBAAuB,CAAC,CAAA;IACrD,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,0CAA0C,EAAE,GAAG,EAAE;QAClD,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,oBAAoB,CAAC,CAAA;QAClD,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,+BAA+B,CAAC,CAAA;IAC/D,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,yCAAyC,EAAE,GAAG,EAAE;QACjD,yEAAyE;QACzE,qEAAqE;QACrE,kCAAkC;QAClC,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,eAAe,CAAC,CAAA;QAC7C,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,UAAU,CAAC,CAAA;QACtC,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,YAAY,CAAC,CAAA;QAC1C,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,sBAAsB,CAAC,CAAA;IAClD,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,2CAA2C,EAAE,GAAG,EAAE;QACnD,2EAA2E;QAC3E,yEAAyE;QACzE,mCAAmC;QACnC,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,qBAAqB,CAAC,CAAA;IACrD,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,0CAA0C,EAAE,GAAG,EAAE;QAClD,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,YAAY,CAAC,CAAA;IACxC,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA"}
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@homebridge-plugins/homebridge-resideo",
3
3
  "displayName": "Resideo",
4
4
  "type": "module",
5
- "version": "3.1.3",
5
+ "version": "3.1.4",
6
6
  "description": "The Resideo plugin allows you to access your Resideo device(s) from HomeKit.",
7
7
  "author": {
8
8
  "name": "bwp91",