@homebridge-plugins/homebridge-resideo 3.1.3 → 3.1.5

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,16 @@
1
+ ## v3.1.5 (2026-07-24)
2
+
3
+ ### Changed
4
+
5
+ - fix(ui): spell out that the sign-in window wants the resideo app account, not the developer account (#930) (@dash16)
6
+
7
+ ## v3.1.4 (2026-07-20)
8
+
9
+ ### Changed
10
+
11
+ - fix(ui): use the working resideo api host for login, so the setup flow stops failing on an expired certificate (#927) (@cowboydaks) (@carlosfranceschi)
12
+ - fix(ui): exchange the login code with fetch instead of shelling out to curl
13
+
1
14
  ## v3.1.3 (2026-07-20)
2
15
 
3
16
  ### Changed
@@ -7,8 +7,13 @@
7
7
  <p class="lead text-center">Thank you for installing <strong>homebridge-resideo</strong></p>
8
8
  <p class="lead text-center">Before continuing:</p>
9
9
  <ol>
10
- <li class="mb-3">Login / create an account at <a href="https://developer.honeywellhome.com/user" target="_blank"
11
- rel="noreferrer noopener">https://developer.honeywellhome.com/user</a>.</li>
10
+ <li class="mb-3">Login / create a <strong>developer</strong> account at <a
11
+ href="https://developer.honeywellhome.com/user" target="_blank"
12
+ rel="noreferrer noopener">https://developer.honeywellhome.com/user</a>.
13
+ <br>
14
+ <small class="text-muted">This is a separate account from the one you use in the Honeywell Home / Resideo
15
+ app. It is only used to generate the key and secret below.</small>
16
+ </li>
12
17
  <li class="mb-3">Click <strong>Create New App</strong>.</li>
13
18
  <li class="mb-3">
14
19
  Give your application a name, and enter the 'Callback URL' exactly as it is displayed below.
@@ -63,6 +68,17 @@
63
68
  <label for="inputConsumerSecret">Consumer Secret <span class="text-danger">*</span></label>
64
69
  <input type="text" class="form-control" id="inputConsumerSecret">
65
70
  </div>
71
+ <div class="alert alert-info">
72
+ <strong>Which account does the next window want?</strong>
73
+ <br>
74
+ Continuing opens a Honeywell/Resideo sign-in window. Sign in there with your
75
+ <strong>Honeywell Home / Resideo app</strong> account &mdash; the same email and password you use in the phone
76
+ app to see your thermostats. That is <em>not</em> the developer account you used above, and your browser may try
77
+ to autofill the wrong one.
78
+ <br>
79
+ <small>If that account will not sign in even though the password is right, use <strong>Forgot
80
+ password</strong> in that window and reset it &mdash; that has fixed it for others.</small>
81
+ </div>
66
82
  <div class="form-group text-center">
67
83
  <button type="button" class="btn btn-primary" id="backToIntro">&larr;</button>
68
84
  <button type="button" class="btn btn-primary" id="linkButton">Continue &rarr;</button>
@@ -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, '&amp;')
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.5",
6
6
  "description": "The Resideo plugin allows you to access your Resideo device(s) from HomeKit.",
7
7
  "author": {
8
8
  "name": "bwp91",
@@ -45,6 +45,7 @@
45
45
  },
46
46
  "keywords": [
47
47
  "homebridge-plugin",
48
+ "supports-matter",
48
49
  "homebridge-matter",
49
50
  "honeywell",
50
51
  "honeywell-home",