homebridge-nuheat2 1.2.15 → 1.2.17
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 +14 -0
- package/README.md +7 -5
- package/config.schema.json +3 -3
- package/homebridge-ui/public/index.html +9 -7
- package/homebridge-ui/public/index.js +32 -28
- package/lib/NuHeatAPI.js +65 -34
- package/lib/settings.js +2 -2
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,20 @@ All notable changes to this project should be documented in this file
|
|
|
4
4
|
|
|
5
5
|
## [Unreleased]
|
|
6
6
|
|
|
7
|
+
## [1.2.17] - 2026-04-29
|
|
8
|
+
|
|
9
|
+
### Fixed
|
|
10
|
+
|
|
11
|
+
- Treat the built-in Nuheat public client ID as PKCE-only even when it is explicitly saved in Advanced OAuth settings
|
|
12
|
+
- Ignore and clear stale saved client secrets when users return to the built-in PKCE public client
|
|
13
|
+
|
|
14
|
+
## [1.2.16] - 2026-04-29
|
|
15
|
+
|
|
16
|
+
### Changed
|
|
17
|
+
|
|
18
|
+
- Switch the built-in Nuheat OAuth client to Authorization Code with PKCE using the public `homebridge-nuheat2_260421` client ID
|
|
19
|
+
- Keep legacy confidential-client OAuth overrides available when a custom `clientSecret` is explicitly configured
|
|
20
|
+
|
|
7
21
|
## [1.2.15] - 2026-04-27
|
|
8
22
|
|
|
9
23
|
### Fixed
|
package/README.md
CHANGED
|
@@ -15,6 +15,7 @@ This project builds on the original [`senorshaun/homebridge-nuheat`](https://git
|
|
|
15
15
|
- Optionally creates HomeKit switches for Nuheat group away mode
|
|
16
16
|
- Supports permanent, scheduled, and timed holds
|
|
17
17
|
- Uses Nuheat's OAuth-based API instead of legacy site scraping
|
|
18
|
+
- Uses the official Nuheat PKCE public client by default, with no distributable client secret
|
|
18
19
|
- Includes compatibility improvements for Homebridge 1.8+ and 2.0 betas
|
|
19
20
|
- Can optionally expose a schedule switch for each thermostat
|
|
20
21
|
- Allows advanced OAuth overrides for long-term API stability
|
|
@@ -89,8 +90,8 @@ The equivalent JSON looks like this:
|
|
|
89
90
|
- `refresh`: Poll interval in seconds, default `60`. Values lower than `30` are raised to `30` to reduce API traffic
|
|
90
91
|
- `enableNotifications`: Enables Nuheat SignalR notifications for faster updates. Defaults to `true`; set to `false` only while troubleshooting
|
|
91
92
|
- `debug`: Enables verbose Nuheat API, notification, and accessory logging. Defaults to `false`
|
|
92
|
-
- `clientId`: Optional advanced override for the Nuheat OAuth client ID.
|
|
93
|
-
- `clientSecret`: Optional legacy OAuth client secret override for confidential-client credentials.
|
|
93
|
+
- `clientId`: Optional advanced override for the Nuheat OAuth client ID. Leave blank to use the built-in PKCE public client ID, `homebridge-nuheat2_260421`
|
|
94
|
+
- `clientSecret`: Optional legacy OAuth client secret override for confidential-client credentials. Leave blank for the PKCE public-client flow. Do not publish or share this value
|
|
94
95
|
- `redirectUri`: Optional advanced override for the Nuheat OAuth redirect URI, default `http://localhost`
|
|
95
96
|
|
|
96
97
|
### Hold Length Behavior
|
|
@@ -114,7 +115,9 @@ Nuheat's public OpenAPI documentation indicates that third-party developers shou
|
|
|
114
115
|
- [Nuheat OpenAPI docs](https://api.mynuheat.com/)
|
|
115
116
|
- [Nuheat API access request page](https://www.nuheat.com/openapi)
|
|
116
117
|
|
|
117
|
-
This fork
|
|
118
|
+
This fork uses Nuheat's PKCE-based public client for normal authentication. The built-in public `clientId` is `homebridge-nuheat2_260421`; there is no distributable client secret.
|
|
119
|
+
|
|
120
|
+
Legacy confidential-client credentials can still be supplied with `clientId` and `clientSecret` for testing alternate Nuheat-issued clients. Keep any `clientSecret` out of GitHub, npm, screenshots, and shared logs.
|
|
118
121
|
|
|
119
122
|
## What's New In This Fork
|
|
120
123
|
|
|
@@ -173,7 +176,6 @@ After that, bump the version in `package.json`, push to `master`, and GitHub Act
|
|
|
173
176
|
|
|
174
177
|
## Future Work
|
|
175
178
|
|
|
176
|
-
- Validate the
|
|
177
|
-
- Move the normal OAuth path to Nuheat's PKCE-based public client once the new client details are issued.
|
|
179
|
+
- Validate the PKCE public-client flow against more real-world Nuheat accounts.
|
|
178
180
|
- Verify group and away-mode behavior against current live API responses.
|
|
179
181
|
- Evaluate whether SignalR notifications can reduce polling further in real-world deployments.
|
package/config.schema.json
CHANGED
|
@@ -125,13 +125,13 @@
|
|
|
125
125
|
"clientId": {
|
|
126
126
|
"title": "Nuheat Client ID",
|
|
127
127
|
"type": "string",
|
|
128
|
-
"description": "Advanced OAuth override.
|
|
128
|
+
"description": "Advanced OAuth override. Leave blank to use the built-in PKCE public client ID."
|
|
129
129
|
},
|
|
130
130
|
"clientSecret": {
|
|
131
131
|
"title": "Nuheat Client Secret (Legacy)",
|
|
132
132
|
"type": "string",
|
|
133
133
|
"format": "password",
|
|
134
|
-
"description": "
|
|
134
|
+
"description": "Legacy OAuth override for confidential-client credentials. Leave blank for the PKCE public-client flow. Do not publish or share this value."
|
|
135
135
|
},
|
|
136
136
|
"redirectUri": {
|
|
137
137
|
"title": "Nuheat Redirect URI",
|
|
@@ -177,7 +177,7 @@
|
|
|
177
177
|
"title": "Advanced OAuth",
|
|
178
178
|
"expandable": true,
|
|
179
179
|
"expanded": false,
|
|
180
|
-
"description": "Only change these fields when testing Nuheat-issued API credentials.",
|
|
180
|
+
"description": "Only change these fields when testing alternate Nuheat-issued API credentials.",
|
|
181
181
|
"items": [
|
|
182
182
|
"clientId",
|
|
183
183
|
"clientSecret",
|
|
@@ -173,19 +173,21 @@
|
|
|
173
173
|
<div>
|
|
174
174
|
<h2>Advanced OAuth</h2>
|
|
175
175
|
<p class="help">
|
|
176
|
-
Leave these fields blank
|
|
177
|
-
|
|
178
|
-
|
|
176
|
+
Leave these fields blank to use the built-in Nuheat PKCE public
|
|
177
|
+
client. Only change them when testing alternate Nuheat-issued API
|
|
178
|
+
credentials.
|
|
179
179
|
</p>
|
|
180
180
|
</div>
|
|
181
|
-
<span id="oauth-status" class="status-pill
|
|
181
|
+
<span id="oauth-status" class="status-pill good">Built-in PKCE</span>
|
|
182
182
|
</div>
|
|
183
183
|
|
|
184
184
|
<div class="settings-grid">
|
|
185
185
|
<label class="field">
|
|
186
186
|
<span>Nuheat Client ID</span>
|
|
187
187
|
<input id="client-id" type="text" placeholder="Optional client ID" />
|
|
188
|
-
<small>
|
|
188
|
+
<small>
|
|
189
|
+
Advanced override. Blank uses homebridge-nuheat2_260421.
|
|
190
|
+
</small>
|
|
189
191
|
</label>
|
|
190
192
|
|
|
191
193
|
<label id="client-secret-row" class="field">
|
|
@@ -196,8 +198,8 @@
|
|
|
196
198
|
placeholder="Leave blank to keep existing"
|
|
197
199
|
/>
|
|
198
200
|
<small>
|
|
199
|
-
|
|
200
|
-
|
|
201
|
+
Leave blank for PKCE public-client auth. Only use this for legacy
|
|
202
|
+
confidential-client credentials.
|
|
201
203
|
</small>
|
|
202
204
|
</label>
|
|
203
205
|
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
const PLATFORM_NAME = "NuHeat";
|
|
2
|
+
const BUILT_IN_CLIENT_ID = "homebridge-nuheat2_260421";
|
|
2
3
|
|
|
3
4
|
const elements = {
|
|
4
5
|
name: document.getElementById("name"),
|
|
@@ -139,7 +140,9 @@ function renderConfig(config) {
|
|
|
139
140
|
|
|
140
141
|
elements.clientId.value = config.clientId || "";
|
|
141
142
|
elements.clientSecret.value = "";
|
|
142
|
-
state.hasClientSecret = Boolean(
|
|
143
|
+
state.hasClientSecret = Boolean(
|
|
144
|
+
config.clientSecret && config.clientId !== BUILT_IN_CLIENT_ID,
|
|
145
|
+
);
|
|
143
146
|
elements.clientSecret.placeholder = state.hasClientSecret
|
|
144
147
|
? "Saved secret (leave blank to keep)"
|
|
145
148
|
: "Optional client secret";
|
|
@@ -313,6 +316,7 @@ async function saveOauth() {
|
|
|
313
316
|
const clientId = elements.clientId.value.trim();
|
|
314
317
|
const clientSecret = elements.clientSecret.value;
|
|
315
318
|
const redirectUri = elements.redirectUri.value.trim();
|
|
319
|
+
const usesBuiltInClient = !clientId || clientId === BUILT_IN_CLIENT_ID;
|
|
316
320
|
|
|
317
321
|
if (!clientId && clientSecret) {
|
|
318
322
|
showToast("error", "A client secret requires a Nuheat client ID.");
|
|
@@ -320,34 +324,26 @@ async function saveOauth() {
|
|
|
320
324
|
return;
|
|
321
325
|
}
|
|
322
326
|
|
|
323
|
-
if (clientId && !hasUsableClientSecret(clientId) && !clientSecret) {
|
|
324
|
-
showToast(
|
|
325
|
-
"error",
|
|
326
|
-
"Current OAuth overrides require a matching client ID and client secret.",
|
|
327
|
-
);
|
|
328
|
-
elements.clientSecret.focus();
|
|
329
|
-
return;
|
|
330
|
-
}
|
|
331
|
-
|
|
332
327
|
const patch = {
|
|
333
|
-
clientId:
|
|
328
|
+
clientId: usesBuiltInClient ? undefined : clientId,
|
|
334
329
|
redirectUri: redirectUri && redirectUri !== "http://localhost" ? redirectUri : undefined,
|
|
335
330
|
};
|
|
336
331
|
|
|
337
|
-
if (clientSecret) {
|
|
332
|
+
if (clientSecret && !usesBuiltInClient) {
|
|
338
333
|
patch.clientSecret = clientSecret;
|
|
339
|
-
} else if (
|
|
334
|
+
} else if (usesBuiltInClient || clientId !== (state.config?.clientId || "")) {
|
|
340
335
|
patch.clientSecret = undefined;
|
|
341
336
|
}
|
|
342
337
|
|
|
343
338
|
await persistPatch(patch);
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
339
|
+
state.hasClientSecret = Boolean(state.config?.clientSecret);
|
|
340
|
+
elements.clientId.value = state.config?.clientId || "";
|
|
341
|
+
elements.clientSecret.value = "";
|
|
342
|
+
elements.clientSecret.placeholder = state.hasClientSecret
|
|
343
|
+
? "Saved secret (leave blank to keep)"
|
|
344
|
+
: "Optional client secret";
|
|
345
|
+
updateStatuses();
|
|
346
|
+
renderDiagnostics();
|
|
351
347
|
showToast("success", "OAuth settings saved.");
|
|
352
348
|
}
|
|
353
349
|
|
|
@@ -446,17 +442,22 @@ function updateBehaviorStatus() {
|
|
|
446
442
|
}
|
|
447
443
|
|
|
448
444
|
function updateOauthStatus() {
|
|
449
|
-
const
|
|
450
|
-
const
|
|
445
|
+
const clientId = elements.clientId.value.trim();
|
|
446
|
+
const hasClientId = clientId.length > 0 && clientId !== BUILT_IN_CLIENT_ID;
|
|
447
|
+
const hasClientSecret = hasUsableClientSecret(clientId);
|
|
451
448
|
const text = hasClientId
|
|
452
449
|
? hasClientSecret
|
|
453
|
-
? "Custom OAuth"
|
|
454
|
-
: "
|
|
455
|
-
: "Built-in
|
|
456
|
-
setStatus(elements.oauthStatus,
|
|
450
|
+
? "Custom legacy OAuth"
|
|
451
|
+
: "Custom PKCE"
|
|
452
|
+
: "Built-in PKCE";
|
|
453
|
+
setStatus(elements.oauthStatus, true, text);
|
|
457
454
|
}
|
|
458
455
|
|
|
459
456
|
function hasUsableClientSecret(clientId) {
|
|
457
|
+
if (!clientId || clientId === BUILT_IN_CLIENT_ID) {
|
|
458
|
+
return false;
|
|
459
|
+
}
|
|
460
|
+
|
|
460
461
|
if (elements.clientSecret.value) {
|
|
461
462
|
return true;
|
|
462
463
|
}
|
|
@@ -586,13 +587,16 @@ function getHoldSummary(value) {
|
|
|
586
587
|
}
|
|
587
588
|
|
|
588
589
|
function getOauthMode(config) {
|
|
590
|
+
if (!config.clientId || config.clientId === BUILT_IN_CLIENT_ID) {
|
|
591
|
+
return "built-in PKCE public client";
|
|
592
|
+
}
|
|
593
|
+
|
|
589
594
|
if (config.clientId && hasUsableClientSecret(config.clientId)) {
|
|
590
595
|
return "configured confidential client";
|
|
591
596
|
}
|
|
592
597
|
if (config.clientId) {
|
|
593
|
-
return "
|
|
598
|
+
return "configured PKCE public client";
|
|
594
599
|
}
|
|
595
|
-
return "built-in fallback credentials";
|
|
596
600
|
}
|
|
597
601
|
|
|
598
602
|
function normalizeHoldLength(value) {
|
package/lib/NuHeatAPI.js
CHANGED
|
@@ -6,6 +6,7 @@ const FetchError = fetchModule.FetchError;
|
|
|
6
6
|
const HeadersCtor = fetchModule.Headers;
|
|
7
7
|
const isRedirect = fetchModule.isRedirect;
|
|
8
8
|
const { parse } = htmlParser;
|
|
9
|
+
const node_crypto_1 = require("node:crypto");
|
|
9
10
|
const settings_1 = require("./settings");
|
|
10
11
|
const NuHeatModels_1 = require("./NuHeatModels");
|
|
11
12
|
const OAUTH_SCOPES = ["openapi", "openid", "profile", "offline_access"];
|
|
@@ -16,7 +17,9 @@ class NuHeatAPI {
|
|
|
16
17
|
oauthClientId;
|
|
17
18
|
oauthClientSecret;
|
|
18
19
|
oauthRedirectUri;
|
|
19
|
-
|
|
20
|
+
usingBuiltInClient;
|
|
21
|
+
usePkce;
|
|
22
|
+
pkceCodeVerifier;
|
|
20
23
|
headers;
|
|
21
24
|
accessToken;
|
|
22
25
|
accessTokenTimestamp;
|
|
@@ -28,23 +31,20 @@ class NuHeatAPI {
|
|
|
28
31
|
this.email = email;
|
|
29
32
|
this.password = password;
|
|
30
33
|
this.log = log;
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
this.oauthClientSecret =
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
settings_1.NUHEAT_API_CLIENT_SECRET;
|
|
34
|
+
const configuredClientId = options.clientId || process.env.NUHEAT_API_CLIENT_ID || "";
|
|
35
|
+
const configuredClientSecret = options.clientSecret || process.env.NUHEAT_API_CLIENT_SECRET || "";
|
|
36
|
+
const usingBuiltInPublicClient = !configuredClientId || configuredClientId === settings_1.NUHEAT_API_CLIENT_ID;
|
|
37
|
+
this.oauthClientId = configuredClientId || settings_1.NUHEAT_API_CLIENT_ID;
|
|
38
|
+
this.oauthClientSecret = usingBuiltInPublicClient
|
|
39
|
+
? ""
|
|
40
|
+
: configuredClientSecret || settings_1.NUHEAT_API_CLIENT_SECRET;
|
|
39
41
|
this.oauthRedirectUri =
|
|
40
42
|
options.redirectUri ||
|
|
41
43
|
process.env.NUHEAT_API_REDIRECT_URI ||
|
|
42
44
|
settings_1.NUHEAT_API_REDIRECT_URI;
|
|
43
|
-
this.
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
!options.clientSecret &&
|
|
47
|
-
!process.env.NUHEAT_API_CLIENT_SECRET;
|
|
45
|
+
this.usingBuiltInClient = usingBuiltInPublicClient;
|
|
46
|
+
this.usePkce = !this.oauthClientSecret;
|
|
47
|
+
this.pkceCodeVerifier = "";
|
|
48
48
|
this.headers = new HeadersCtor();
|
|
49
49
|
this.headers.set("Content-Type", "application/json");
|
|
50
50
|
this.headers.set("Accept", "application/json");
|
|
@@ -54,8 +54,10 @@ class NuHeatAPI {
|
|
|
54
54
|
this.refreshToken = "";
|
|
55
55
|
this.tokenScope = "";
|
|
56
56
|
this.tokenType = "Bearer";
|
|
57
|
-
if (this.
|
|
58
|
-
this.log.
|
|
57
|
+
if (this.usingBuiltInClient) {
|
|
58
|
+
this.log.info("NuHeatAPI: Using built-in Nuheat PKCE public client ID " +
|
|
59
|
+
this.oauthClientId +
|
|
60
|
+
".");
|
|
59
61
|
}
|
|
60
62
|
else {
|
|
61
63
|
this.log.info("NuHeatAPI: Using configured OAuth client ID " + this.oauthClientId + ".");
|
|
@@ -63,11 +65,48 @@ class NuHeatAPI {
|
|
|
63
65
|
this.log.debug("NuHeatAPI: OAuth redirect URI " +
|
|
64
66
|
this.oauthRedirectUri +
|
|
65
67
|
". Requested scopes: " +
|
|
66
|
-
this.getRequestedScope()
|
|
68
|
+
this.getRequestedScope() +
|
|
69
|
+
". OAuth flow: " +
|
|
70
|
+
(this.usePkce ? "authorization_code_pkce" : "authorization_code_secret"));
|
|
67
71
|
}
|
|
68
72
|
getRequestedScope() {
|
|
69
73
|
return OAUTH_SCOPES.join(" ");
|
|
70
74
|
}
|
|
75
|
+
generatePkceCodeVerifier() {
|
|
76
|
+
return (0, node_crypto_1.randomBytes)(64).toString("base64url");
|
|
77
|
+
}
|
|
78
|
+
getPkceCodeChallenge(codeVerifier) {
|
|
79
|
+
return (0, node_crypto_1.createHash)("sha256").update(codeVerifier).digest("base64url");
|
|
80
|
+
}
|
|
81
|
+
buildAuthorizationCodeTokenRequest(redirectUrl) {
|
|
82
|
+
const requestBody = new URLSearchParams({
|
|
83
|
+
client_id: this.oauthClientId,
|
|
84
|
+
code: redirectUrl.searchParams.get("code") || "",
|
|
85
|
+
grant_type: "authorization_code",
|
|
86
|
+
redirect_uri: this.oauthRedirectUri,
|
|
87
|
+
scope: redirectUrl.searchParams.get("scope") || "",
|
|
88
|
+
});
|
|
89
|
+
if (this.usePkce) {
|
|
90
|
+
requestBody.set("code_verifier", this.pkceCodeVerifier);
|
|
91
|
+
}
|
|
92
|
+
else {
|
|
93
|
+
requestBody.set("client_secret", this.oauthClientSecret);
|
|
94
|
+
}
|
|
95
|
+
return requestBody;
|
|
96
|
+
}
|
|
97
|
+
buildRefreshTokenRequest() {
|
|
98
|
+
const requestBody = new URLSearchParams({
|
|
99
|
+
client_id: this.oauthClientId,
|
|
100
|
+
grant_type: "refresh_token",
|
|
101
|
+
refresh_token: this.refreshToken,
|
|
102
|
+
scope: this.tokenScope,
|
|
103
|
+
});
|
|
104
|
+
if (!this.usePkce) {
|
|
105
|
+
requestBody.set("client_secret", this.oauthClientSecret);
|
|
106
|
+
requestBody.set("redirect_uri", this.oauthRedirectUri);
|
|
107
|
+
}
|
|
108
|
+
return requestBody;
|
|
109
|
+
}
|
|
71
110
|
async setAwayMode(groupId, awayMode) {
|
|
72
111
|
const callURL = "https://api.mynuheat.com/api/v1/Group";
|
|
73
112
|
const callOptions = {
|
|
@@ -248,8 +287,14 @@ class NuHeatAPI {
|
|
|
248
287
|
authEndpoint.searchParams.set("client_id", this.oauthClientId);
|
|
249
288
|
authEndpoint.searchParams.set("redirect_uri", this.oauthRedirectUri);
|
|
250
289
|
authEndpoint.searchParams.set("scope", this.getRequestedScope());
|
|
290
|
+
if (this.usePkce) {
|
|
291
|
+
this.pkceCodeVerifier = this.generatePkceCodeVerifier();
|
|
292
|
+
authEndpoint.searchParams.set("code_challenge", this.getPkceCodeChallenge(this.pkceCodeVerifier));
|
|
293
|
+
authEndpoint.searchParams.set("code_challenge_method", "S256");
|
|
294
|
+
}
|
|
251
295
|
this.log.debug("NuHeatAPI: Requesting OAuth authorization page with scopes: " +
|
|
252
|
-
this.getRequestedScope()
|
|
296
|
+
this.getRequestedScope() +
|
|
297
|
+
(this.usePkce ? " using PKCE." : "."));
|
|
253
298
|
const response = await this.fetch(authEndpoint.toString(), {
|
|
254
299
|
redirect: "follow",
|
|
255
300
|
});
|
|
@@ -396,14 +441,7 @@ class NuHeatAPI {
|
|
|
396
441
|
return null;
|
|
397
442
|
}
|
|
398
443
|
const redirectUrl = new URL(response.headers.get("location") || "");
|
|
399
|
-
const requestBody =
|
|
400
|
-
client_id: this.oauthClientId,
|
|
401
|
-
client_secret: this.oauthClientSecret,
|
|
402
|
-
code: redirectUrl.searchParams.get("code") || "",
|
|
403
|
-
grant_type: "authorization_code",
|
|
404
|
-
redirect_uri: this.oauthRedirectUri,
|
|
405
|
-
scope: redirectUrl.searchParams.get("scope") || "",
|
|
406
|
-
});
|
|
444
|
+
const requestBody = this.buildAuthorizationCodeTokenRequest(redirectUrl);
|
|
407
445
|
response = await this.fetch(settings_1.NUHEAT_API_TOKEN_URI, {
|
|
408
446
|
body: requestBody.toString(),
|
|
409
447
|
headers: {
|
|
@@ -426,14 +464,7 @@ class NuHeatAPI {
|
|
|
426
464
|
return null;
|
|
427
465
|
}
|
|
428
466
|
async getRefreshedAccessToken() {
|
|
429
|
-
const requestBody =
|
|
430
|
-
client_id: this.oauthClientId,
|
|
431
|
-
client_secret: this.oauthClientSecret,
|
|
432
|
-
grant_type: "refresh_token",
|
|
433
|
-
redirect_uri: this.oauthRedirectUri,
|
|
434
|
-
refresh_token: this.refreshToken,
|
|
435
|
-
scope: this.tokenScope,
|
|
436
|
-
});
|
|
467
|
+
const requestBody = this.buildRefreshTokenRequest();
|
|
437
468
|
const response = await this.fetch(settings_1.NUHEAT_API_TOKEN_URI, {
|
|
438
469
|
body: requestBody.toString(),
|
|
439
470
|
headers: {
|
package/lib/settings.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.NUHEAT_API_CONSENT_URI = exports.NUHEAT_API_TOKEN_URI = exports.NUHEAT_API_AUTHORIZE_URI = exports.NUHEAT_API_REDIRECT_URI = exports.NUHEAT_API_CLIENT_SECRET = exports.NUHEAT_API_CLIENT_ID = void 0;
|
|
4
|
-
exports.NUHEAT_API_CLIENT_ID = "homebridge-
|
|
5
|
-
exports.NUHEAT_API_CLIENT_SECRET = "
|
|
4
|
+
exports.NUHEAT_API_CLIENT_ID = "homebridge-nuheat2_260421";
|
|
5
|
+
exports.NUHEAT_API_CLIENT_SECRET = "";
|
|
6
6
|
exports.NUHEAT_API_REDIRECT_URI = "http://localhost";
|
|
7
7
|
exports.NUHEAT_API_AUTHORIZE_URI = "https://identity.mynuheat.com/connect/authorize";
|
|
8
8
|
exports.NUHEAT_API_TOKEN_URI = "https://identity.mynuheat.com/connect/token";
|