@homebridge-plugins/homebridge-firstalert 0.0.1-beta.4 → 0.0.1-beta.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.
|
@@ -0,0 +1,411 @@
|
|
|
1
|
+
import { Buffer } from 'node:buffer';
|
|
2
|
+
import crypto from 'node:crypto';
|
|
3
|
+
import fs from 'node:fs';
|
|
4
|
+
import { URLSearchParams } from 'node:url';
|
|
5
|
+
import { HomebridgePluginUiServer } from '@homebridge/plugin-ui-utils';
|
|
6
|
+
import { request as undiciRequest } from 'undici';
|
|
7
|
+
// Resideo/First Alert constants
|
|
8
|
+
const OAUTH_CLIENT_ID = 'SRmiA7CaYi1JgivDZdzzoZu4X5VBogGt';
|
|
9
|
+
const OAUTH_TOKEN_URL = 'https://login.resideo.com/oauth/token';
|
|
10
|
+
const AUTH0_BASE_URL = 'https://login.resideo.com';
|
|
11
|
+
const AUTH0_AUTHORIZE_URL = `${AUTH0_BASE_URL}/authorize`;
|
|
12
|
+
const AUTH0_LOGIN_URL = `${AUTH0_BASE_URL}/usernamepassword/login`;
|
|
13
|
+
const AUTH0_CALLBACK_URL = `${AUTH0_BASE_URL}/login/callback`;
|
|
14
|
+
const REDIRECT_URI = 'com.resideo.firstalert://login.resideo.com/ios/com.resideo.firstalert/callback';
|
|
15
|
+
const AUDIENCE = 'https://resideo-prod.auth0.com/api/v2/';
|
|
16
|
+
const SCOPE = 'openid profile email offline_access';
|
|
17
|
+
const TENANT = 'resideo-prod';
|
|
18
|
+
const CONNECTION = 'Username-Password-Authentication';
|
|
19
|
+
const AUTH0_CLIENT_BROWSER = 'eyJuYW1lIjoiYXV0aDAuanMtdWxwIiwidmVyc2lvbiI6IjkuMTMuMiJ9';
|
|
20
|
+
const AUTH0_CLIENT_APP = 'eyJ2ZXJzaW9uIjoiMS4xNC4wIiwibmFtZSI6ImF1dGgwLWZsdXR0ZXIiLCJlbnYiOnsiY29yZSI6IjIuMTAuMCIsImlPUyI6IjI2LjEiLCJzd2lmdCI6IjUueCJ9fQ';
|
|
21
|
+
// Regexes moved to module scope
|
|
22
|
+
const CSRF_REGEX = /_csrf=([^;]+)/;
|
|
23
|
+
const WRESULT_REGEX = /name="wresult"\s+value="([^"]+)"/;
|
|
24
|
+
const WCTX_REGEX = /name="wctx"\s+value="([^"]+)"/;
|
|
25
|
+
class PluginUiServer extends HomebridgePluginUiServer {
|
|
26
|
+
constructor() {
|
|
27
|
+
super();
|
|
28
|
+
// Resideo Auth (email/password) handler
|
|
29
|
+
this.onRequest('startResideoAuth', async (payload) => {
|
|
30
|
+
const logs = [];
|
|
31
|
+
const logAndReturn = (status, data) => {
|
|
32
|
+
logs.push(typeof data === 'string' ? data : JSON.stringify(data));
|
|
33
|
+
return { status, data, logs };
|
|
34
|
+
};
|
|
35
|
+
try {
|
|
36
|
+
const { email, password } = payload || {};
|
|
37
|
+
if (!email || !password) {
|
|
38
|
+
return logAndReturn('error', 'Missing email or password.');
|
|
39
|
+
}
|
|
40
|
+
logs.push('Generating PKCE code verifier and challenge...');
|
|
41
|
+
const codeVerifier = crypto.randomBytes(32).toString('base64url');
|
|
42
|
+
const challenge = crypto.createHash('sha256').update(codeVerifier).digest('base64url');
|
|
43
|
+
const state = crypto.randomBytes(32).toString('base64url');
|
|
44
|
+
logs.push('Step 1: Authorize (requesting Auth0 authorize endpoint)...');
|
|
45
|
+
// Add a timeout to the entire flow (e.g., 20 seconds)
|
|
46
|
+
const withTimeout = async (promise, ms = 20000, label = '') => {
|
|
47
|
+
let timeoutId;
|
|
48
|
+
return Promise.race([
|
|
49
|
+
promise,
|
|
50
|
+
new Promise((_, reject) => {
|
|
51
|
+
timeoutId = setTimeout(() => {
|
|
52
|
+
logs.push(`Timeout waiting for response${label ? ` at ${label}` : ''}`);
|
|
53
|
+
reject(new Error('Timeout waiting for response'));
|
|
54
|
+
}, ms);
|
|
55
|
+
}),
|
|
56
|
+
]).finally(() => clearTimeout(timeoutId));
|
|
57
|
+
};
|
|
58
|
+
// Define params1 before using it
|
|
59
|
+
const params1 = new URLSearchParams({
|
|
60
|
+
state,
|
|
61
|
+
scope: SCOPE,
|
|
62
|
+
signUpUrl: 'https://myid.resideo.com/sign-up?userType=consumer',
|
|
63
|
+
client_id: OAUTH_CLIENT_ID,
|
|
64
|
+
code_challenge_method: 'S256',
|
|
65
|
+
response_type: 'code',
|
|
66
|
+
max_age: '0',
|
|
67
|
+
audience: AUDIENCE,
|
|
68
|
+
redirect_uri: REDIRECT_URI,
|
|
69
|
+
code_challenge: challenge,
|
|
70
|
+
prompt: 'login',
|
|
71
|
+
auth0Client: AUTH0_CLIENT_APP,
|
|
72
|
+
});
|
|
73
|
+
logs.push('About to make Auth0 authorize request...');
|
|
74
|
+
let auth0AuthorizeRes;
|
|
75
|
+
try {
|
|
76
|
+
auth0AuthorizeRes = await withTimeout(undiciRequest(`${AUTH0_AUTHORIZE_URL}?${params1.toString()}`, {
|
|
77
|
+
method: 'GET',
|
|
78
|
+
headers: { 'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 18_0 like Mac OS X)' },
|
|
79
|
+
}), 20000, 'Auth0 authorize');
|
|
80
|
+
}
|
|
81
|
+
catch (e) {
|
|
82
|
+
logs.push('Caught error or timeout in Auth0 authorize request.');
|
|
83
|
+
return logAndReturn('error', `Timeout or error during Auth0 authorize request: ${e?.message || e}`);
|
|
84
|
+
}
|
|
85
|
+
logs.push('Auth0 authorize request completed.');
|
|
86
|
+
logs.push(`Auth0 authorize response: status ${auth0AuthorizeRes.statusCode}`);
|
|
87
|
+
if (auth0AuthorizeRes.statusCode !== 302) {
|
|
88
|
+
return logAndReturn('error', 'Expected redirect from authorize.');
|
|
89
|
+
}
|
|
90
|
+
let location1 = auth0AuthorizeRes.headers.location;
|
|
91
|
+
if (Array.isArray(location1)) {
|
|
92
|
+
location1 = location1[0];
|
|
93
|
+
}
|
|
94
|
+
if (!location1) {
|
|
95
|
+
return logAndReturn('error', 'No redirect location from authorize.');
|
|
96
|
+
}
|
|
97
|
+
const urlObj = new URL(location1, AUTH0_BASE_URL);
|
|
98
|
+
const auth0State = urlObj.searchParams.get('state');
|
|
99
|
+
if (!auth0State) {
|
|
100
|
+
return logAndReturn('error', 'No state in authorize redirect.');
|
|
101
|
+
}
|
|
102
|
+
// Step 2: Get login page (to get CSRF token)
|
|
103
|
+
logs.push('Step 2: Fetching login page for CSRF token...');
|
|
104
|
+
const loginUrl = `${AUTH0_BASE_URL}/login?state=${auth0State}`;
|
|
105
|
+
let loginRes;
|
|
106
|
+
try {
|
|
107
|
+
loginRes = await withTimeout(undiciRequest(loginUrl, {
|
|
108
|
+
method: 'GET',
|
|
109
|
+
headers: { 'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 18_0 like Mac OS X)' },
|
|
110
|
+
}), 20000, 'login page');
|
|
111
|
+
}
|
|
112
|
+
catch (e) {
|
|
113
|
+
logs.push('Caught error or timeout in login page request.');
|
|
114
|
+
return logAndReturn('error', `Timeout or error during login page request: ${e?.message || e}`);
|
|
115
|
+
}
|
|
116
|
+
logs.push(`Login page response: status ${loginRes.statusCode}`);
|
|
117
|
+
let csrfToken = '';
|
|
118
|
+
const setCookie = loginRes.headers['set-cookie'];
|
|
119
|
+
if (setCookie) {
|
|
120
|
+
const match = CSRF_REGEX.exec(Array.isArray(setCookie) ? setCookie.join(';') : setCookie);
|
|
121
|
+
if (match) {
|
|
122
|
+
csrfToken = match[1];
|
|
123
|
+
logs.push('CSRF token extracted.');
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
if (!csrfToken) {
|
|
127
|
+
logs.push('No CSRF token in login page.');
|
|
128
|
+
return logAndReturn('error', 'No CSRF token in login page.');
|
|
129
|
+
}
|
|
130
|
+
// Step 3: Submit credentials
|
|
131
|
+
logs.push('Step 3: Submitting credentials to Auth0...');
|
|
132
|
+
const loginData = {
|
|
133
|
+
client_id: OAUTH_CLIENT_ID,
|
|
134
|
+
redirect_uri: REDIRECT_URI,
|
|
135
|
+
tenant: TENANT,
|
|
136
|
+
response_type: 'code',
|
|
137
|
+
scope: SCOPE,
|
|
138
|
+
audience: AUDIENCE,
|
|
139
|
+
_csrf: csrfToken,
|
|
140
|
+
state: auth0State,
|
|
141
|
+
_intstate: 'deprecated',
|
|
142
|
+
username: email,
|
|
143
|
+
password,
|
|
144
|
+
connection: CONNECTION,
|
|
145
|
+
};
|
|
146
|
+
const loginHeaders = {
|
|
147
|
+
'Auth0-Client': AUTH0_CLIENT_BROWSER,
|
|
148
|
+
'Origin': AUTH0_BASE_URL,
|
|
149
|
+
'Content-Type': 'application/json',
|
|
150
|
+
'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 18_0 like Mac OS X)',
|
|
151
|
+
};
|
|
152
|
+
let loginPostRes;
|
|
153
|
+
try {
|
|
154
|
+
loginPostRes = await withTimeout(undiciRequest(AUTH0_LOGIN_URL, {
|
|
155
|
+
method: 'POST',
|
|
156
|
+
headers: loginHeaders,
|
|
157
|
+
body: JSON.stringify(loginData),
|
|
158
|
+
}), 20000, 'login POST');
|
|
159
|
+
}
|
|
160
|
+
catch (e) {
|
|
161
|
+
logs.push('Caught error or timeout in login POST request.');
|
|
162
|
+
return logAndReturn('error', `Timeout or error during login POST request: ${e?.message || e}`);
|
|
163
|
+
}
|
|
164
|
+
logs.push(`Login POST response: status ${loginPostRes.statusCode}`);
|
|
165
|
+
let loginText;
|
|
166
|
+
try {
|
|
167
|
+
loginText = await withTimeout(loginPostRes.body.text(), 10000, 'login POST body.text');
|
|
168
|
+
}
|
|
169
|
+
catch (e) {
|
|
170
|
+
logs.push('Timeout or error reading login POST response body.');
|
|
171
|
+
return logAndReturn('error', `Timeout or error reading login POST response body: ${e?.message || e}`);
|
|
172
|
+
}
|
|
173
|
+
if (loginPostRes.statusCode !== 200) {
|
|
174
|
+
if (loginText.includes('Wrong email or password') || loginText.includes('invalid_grant')) {
|
|
175
|
+
logs.push('Invalid email or password.');
|
|
176
|
+
return logAndReturn('error', 'Invalid email or password.');
|
|
177
|
+
}
|
|
178
|
+
logs.push(`Login failed with status ${loginPostRes.statusCode}`);
|
|
179
|
+
return logAndReturn('error', `Login failed with status ${loginPostRes.statusCode}`);
|
|
180
|
+
}
|
|
181
|
+
const wresultMatch = WRESULT_REGEX.exec(loginText);
|
|
182
|
+
if (!wresultMatch) {
|
|
183
|
+
logs.push('Could not extract wresult from login response.');
|
|
184
|
+
return logAndReturn('error', 'Could not extract wresult from login response.');
|
|
185
|
+
}
|
|
186
|
+
const wresult = wresultMatch[1];
|
|
187
|
+
const wctxMatch = WCTX_REGEX.exec(loginText);
|
|
188
|
+
const wctx = wctxMatch ? wctxMatch[1] : '';
|
|
189
|
+
logs.push('Extracted wresult and wctx from login response.');
|
|
190
|
+
// Step 4: Callback
|
|
191
|
+
logs.push('Step 4: Posting to callback endpoint...');
|
|
192
|
+
const callbackHeaders = {
|
|
193
|
+
'Content-Type': 'application/x-www-form-urlencoded',
|
|
194
|
+
'Origin': AUTH0_BASE_URL,
|
|
195
|
+
'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 18_0 like Mac OS X)',
|
|
196
|
+
};
|
|
197
|
+
const callbackBody = new URLSearchParams({ wa: 'wsignin1.0', wresult });
|
|
198
|
+
if (wctx) {
|
|
199
|
+
callbackBody.append('wctx', wctx);
|
|
200
|
+
}
|
|
201
|
+
let callbackRes;
|
|
202
|
+
try {
|
|
203
|
+
callbackRes = await withTimeout(undiciRequest(AUTH0_CALLBACK_URL, {
|
|
204
|
+
method: 'POST',
|
|
205
|
+
headers: callbackHeaders,
|
|
206
|
+
body: callbackBody.toString(),
|
|
207
|
+
}), 20000, 'callback POST');
|
|
208
|
+
}
|
|
209
|
+
catch (e) {
|
|
210
|
+
logs.push('Caught error or timeout in callback POST request.');
|
|
211
|
+
return logAndReturn('error', `Timeout or error during callback POST request: ${e?.message || e}`);
|
|
212
|
+
}
|
|
213
|
+
logs.push(`Callback response: status ${callbackRes.statusCode}`);
|
|
214
|
+
if (callbackRes.statusCode !== 302) {
|
|
215
|
+
logs.push('Expected redirect from callback.');
|
|
216
|
+
return logAndReturn('error', 'Expected redirect from callback.');
|
|
217
|
+
}
|
|
218
|
+
let location2 = callbackRes.headers.location;
|
|
219
|
+
if (Array.isArray(location2)) {
|
|
220
|
+
location2 = location2[0];
|
|
221
|
+
}
|
|
222
|
+
if (!location2) {
|
|
223
|
+
logs.push('No redirect location from callback.');
|
|
224
|
+
return logAndReturn('error', 'No redirect location from callback.');
|
|
225
|
+
}
|
|
226
|
+
// Step 5: Resume authorization
|
|
227
|
+
logs.push('Step 5: Resuming authorization...');
|
|
228
|
+
let resumeUrl = location2;
|
|
229
|
+
if (Array.isArray(resumeUrl)) {
|
|
230
|
+
resumeUrl = resumeUrl[0];
|
|
231
|
+
}
|
|
232
|
+
if (!resumeUrl.startsWith('http')) {
|
|
233
|
+
resumeUrl = AUTH0_BASE_URL + resumeUrl;
|
|
234
|
+
}
|
|
235
|
+
let resumeRes;
|
|
236
|
+
try {
|
|
237
|
+
resumeRes = await withTimeout(undiciRequest(resumeUrl, {
|
|
238
|
+
method: 'GET',
|
|
239
|
+
headers: { 'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 18_0 like Mac OS X)' },
|
|
240
|
+
}), 20000, 'resume GET');
|
|
241
|
+
}
|
|
242
|
+
catch (e) {
|
|
243
|
+
logs.push('Caught error or timeout in resume GET request.');
|
|
244
|
+
return logAndReturn('error', `Timeout or error during resume GET request: ${e?.message || e}`);
|
|
245
|
+
}
|
|
246
|
+
logs.push(`Resume response: status ${resumeRes.statusCode}`);
|
|
247
|
+
if (resumeRes.statusCode !== 302) {
|
|
248
|
+
logs.push('Expected redirect from resume.');
|
|
249
|
+
return logAndReturn('error', 'Expected redirect from resume.');
|
|
250
|
+
}
|
|
251
|
+
let location3 = resumeRes.headers.location;
|
|
252
|
+
if (Array.isArray(location3)) {
|
|
253
|
+
location3 = location3[0];
|
|
254
|
+
}
|
|
255
|
+
if (!location3) {
|
|
256
|
+
logs.push('No redirect location from resume.');
|
|
257
|
+
return logAndReturn('error', 'No redirect location from resume.');
|
|
258
|
+
}
|
|
259
|
+
const urlObj2 = new URL(location3, AUTH0_BASE_URL);
|
|
260
|
+
const authCode = urlObj2.searchParams.get('code');
|
|
261
|
+
const returnedState = urlObj2.searchParams.get('state');
|
|
262
|
+
if (!authCode) {
|
|
263
|
+
logs.push('No authorization code in resume redirect.');
|
|
264
|
+
return { status: 'error', data: 'No authorization code in resume redirect', logs };
|
|
265
|
+
}
|
|
266
|
+
if (returnedState !== state) {
|
|
267
|
+
logs.push('State mismatch - possible security issue.');
|
|
268
|
+
return { status: 'error', data: 'State mismatch - possible security issue', logs };
|
|
269
|
+
}
|
|
270
|
+
// Step 6: Exchange code for tokens
|
|
271
|
+
logs.push('Step 6: Exchanging authorization code for tokens...');
|
|
272
|
+
const tokenData = {
|
|
273
|
+
client_id: OAUTH_CLIENT_ID,
|
|
274
|
+
code: authCode,
|
|
275
|
+
redirect_uri: REDIRECT_URI,
|
|
276
|
+
code_verifier: codeVerifier,
|
|
277
|
+
grant_type: 'authorization_code',
|
|
278
|
+
};
|
|
279
|
+
const tokenHeaders = {
|
|
280
|
+
'Auth0-Client': AUTH0_CLIENT_APP,
|
|
281
|
+
'Content-Type': 'application/json',
|
|
282
|
+
};
|
|
283
|
+
let tokenRes;
|
|
284
|
+
try {
|
|
285
|
+
tokenRes = await withTimeout(undiciRequest(OAUTH_TOKEN_URL, {
|
|
286
|
+
method: 'POST',
|
|
287
|
+
headers: tokenHeaders,
|
|
288
|
+
body: JSON.stringify(tokenData),
|
|
289
|
+
}), 20000, 'token POST');
|
|
290
|
+
}
|
|
291
|
+
catch (e) {
|
|
292
|
+
logs.push('Caught error or timeout in token POST request.');
|
|
293
|
+
return logAndReturn('error', `Timeout or error during token POST request: ${e?.message || e}`);
|
|
294
|
+
}
|
|
295
|
+
logs.push(`Token exchange response: status ${tokenRes.statusCode}`);
|
|
296
|
+
let tokenText;
|
|
297
|
+
try {
|
|
298
|
+
tokenText = await withTimeout(tokenRes.body.text(), 10000, 'token POST body.text');
|
|
299
|
+
}
|
|
300
|
+
catch (e) {
|
|
301
|
+
logs.push('Timeout or error reading token POST response body.');
|
|
302
|
+
return logAndReturn('error', `Timeout or error reading token POST response body: ${e?.message || e}`);
|
|
303
|
+
}
|
|
304
|
+
if (tokenRes.statusCode !== 200) {
|
|
305
|
+
logs.push(`Token exchange failed: ${tokenRes.statusCode} - ${tokenText}`);
|
|
306
|
+
return logAndReturn('error', `Token exchange failed: ${tokenRes.statusCode} - ${tokenText}`);
|
|
307
|
+
}
|
|
308
|
+
let tokens;
|
|
309
|
+
try {
|
|
310
|
+
tokens = JSON.parse(tokenText);
|
|
311
|
+
}
|
|
312
|
+
catch (e) {
|
|
313
|
+
logs.push('Error parsing token response JSON.');
|
|
314
|
+
return logAndReturn('error', `Error parsing token response JSON: ${e?.message || e}`);
|
|
315
|
+
}
|
|
316
|
+
logs.push('Successfully obtained access and refresh tokens.');
|
|
317
|
+
return { status: 'ok', data: { accessToken: tokens.access_token, refreshToken: tokens.refresh_token }, logs };
|
|
318
|
+
}
|
|
319
|
+
catch (err) {
|
|
320
|
+
logs.push(`Exception: ${(err && typeof err === 'object' && 'message' in err) ? err.message : String(err)}`);
|
|
321
|
+
return { status: 'error', data: (err && typeof err === 'object' && 'message' in err) ? err.message : String(err), logs };
|
|
322
|
+
}
|
|
323
|
+
});
|
|
324
|
+
// OAuth PKCE flow handler
|
|
325
|
+
this.onRequest('startOAuthFlow', async (payload) => {
|
|
326
|
+
try {
|
|
327
|
+
const { consumerKey, consumerSecret, code, codeVerifier } = payload || {};
|
|
328
|
+
if (!consumerKey || !consumerSecret) {
|
|
329
|
+
return { status: 'error', data: 'Missing consumerKey or consumerSecret' };
|
|
330
|
+
}
|
|
331
|
+
// If no code, generate PKCE and return authUrl for UI
|
|
332
|
+
if (!code) {
|
|
333
|
+
const generatedVerifier = crypto.randomBytes(32).toString('base64url');
|
|
334
|
+
const challenge = crypto.createHash('sha256').update(generatedVerifier).digest('base64url');
|
|
335
|
+
const redirectUri = 'urn:ietf:wg:oauth:2.0:oob';
|
|
336
|
+
const authUrl = `https://api.honeywell.com/oauth2/authorize?response_type=code&client_id=${encodeURIComponent(consumerKey)}&redirect_uri=${encodeURIComponent(redirectUri)}&code_challenge=${encodeURIComponent(challenge)}&code_challenge_method=S256&appSelect=1`;
|
|
337
|
+
return { status: 'need_code', data: { authUrl, codeVerifier: generatedVerifier } };
|
|
338
|
+
}
|
|
339
|
+
// Exchange code for tokens
|
|
340
|
+
if (!codeVerifier) {
|
|
341
|
+
return { status: 'error', data: 'Missing PKCE code_verifier' };
|
|
342
|
+
}
|
|
343
|
+
const redirectUri = 'urn:ietf:wg:oauth:2.0:oob';
|
|
344
|
+
const tokenRes = await fetch('https://api.honeywell.com/oauth2/token', {
|
|
345
|
+
method: 'POST',
|
|
346
|
+
headers: {
|
|
347
|
+
'Authorization': `Basic ${Buffer.from(`${consumerKey}:${consumerSecret}`).toString('base64')}`,
|
|
348
|
+
'Accept': 'application/json',
|
|
349
|
+
'Content-Type': 'application/x-www-form-urlencoded',
|
|
350
|
+
},
|
|
351
|
+
body: `grant_type=authorization_code&code=${encodeURIComponent(code)}&redirect_uri=${encodeURIComponent(redirectUri)}&code_verifier=${encodeURIComponent(codeVerifier)}`,
|
|
352
|
+
});
|
|
353
|
+
const tokenData = await tokenRes.json();
|
|
354
|
+
if (tokenData.refresh_token) {
|
|
355
|
+
return { status: 'ok', data: { refreshToken: tokenData.refresh_token, accessToken: tokenData.access_token } };
|
|
356
|
+
}
|
|
357
|
+
else {
|
|
358
|
+
return { status: 'error', data: tokenData };
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
catch (err) {
|
|
362
|
+
return { status: 'error', data: (err && typeof err === 'object' && 'message' in err) ? err.message : String(err) };
|
|
363
|
+
}
|
|
364
|
+
});
|
|
365
|
+
// Device discovery handler
|
|
366
|
+
this.onRequest('discoverDevices', async (payload) => {
|
|
367
|
+
try {
|
|
368
|
+
const { accessToken } = payload || {};
|
|
369
|
+
if (!accessToken) {
|
|
370
|
+
return { status: 'error', data: 'No access token provided' };
|
|
371
|
+
}
|
|
372
|
+
const res = await fetch('https://api.honeywell.com/v2/devices', {
|
|
373
|
+
headers: {
|
|
374
|
+
Authorization: `Bearer ${accessToken}`,
|
|
375
|
+
Accept: 'application/json',
|
|
376
|
+
},
|
|
377
|
+
});
|
|
378
|
+
if (!res.ok) {
|
|
379
|
+
return { status: 'error', data: await res.text() };
|
|
380
|
+
}
|
|
381
|
+
const data = await res.json();
|
|
382
|
+
return { status: 'ok', data };
|
|
383
|
+
}
|
|
384
|
+
catch (err) {
|
|
385
|
+
return { status: 'error', data: (err && typeof err === 'object' && 'message' in err) ? err.message : String(err) };
|
|
386
|
+
}
|
|
387
|
+
});
|
|
388
|
+
// Legacy: getCachedAccessories for older config-ui-x
|
|
389
|
+
this.onRequest('/getCachedAccessories', async () => {
|
|
390
|
+
try {
|
|
391
|
+
const plugin = '@homebridge-plugins/homebridge-firstalert';
|
|
392
|
+
const devicesToReturn = [];
|
|
393
|
+
const accFile = `${this.homebridgeStoragePath}/accessories/cachedAccessories`;
|
|
394
|
+
if (fs.existsSync(accFile)) {
|
|
395
|
+
const cachedAccessoriesData = await fs.promises.readFile(accFile, 'utf8');
|
|
396
|
+
const cachedAccessories = JSON.parse(cachedAccessoriesData);
|
|
397
|
+
cachedAccessories
|
|
398
|
+
.filter((accessory) => accessory.plugin === plugin)
|
|
399
|
+
.forEach((accessory) => devicesToReturn.push(accessory));
|
|
400
|
+
}
|
|
401
|
+
return { status: 'ok', data: devicesToReturn };
|
|
402
|
+
}
|
|
403
|
+
catch (err) {
|
|
404
|
+
return { status: 'error', data: [] };
|
|
405
|
+
}
|
|
406
|
+
});
|
|
407
|
+
this.ready();
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
(() => new PluginUiServer())();
|
|
411
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/homebridge-ui/server.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@homebridge-plugins/homebridge-firstalert",
|
|
3
3
|
"displayName": "FirstAlert",
|
|
4
4
|
"type": "module",
|
|
5
|
-
"version": "0.0.1-beta.
|
|
5
|
+
"version": "0.0.1-beta.5",
|
|
6
6
|
"description": "The FirstAlert plugin allows you to access your FirstAlert device(s) from HomeKit.",
|
|
7
7
|
"author": {
|
|
8
8
|
"name": "donavanbecker",
|
|
@@ -73,7 +73,8 @@
|
|
|
73
73
|
"watch:ui": "npm run ports:free && bash -c 'npx homebridge -I -U -D ~/.homebridge-dev & HB_PID=$!; sleep 6; UIX_STORAGE_PATH=~/.homebridge-dev node ./node_modules/homebridge-config-ui-x/dist/bin/standalone.js & npm run watch:files'",
|
|
74
74
|
"watch:files": "nodemon",
|
|
75
75
|
"plugin-ui": "mkdir -p ./dist/homebridge-ui/public && if [ -d ./src/homebridge-ui/public ]; then rsync -a ./src/homebridge-ui/public/ ./dist/homebridge-ui/public/; fi",
|
|
76
|
-
"build": "
|
|
76
|
+
"build:ui": "tsc --project tsconfig.ui.json",
|
|
77
|
+
"build": "npm run clean && tsc && npm run plugin-ui && npm run build:ui",
|
|
77
78
|
"prepublishOnly": "npm run lint && npm run build && npm run plugin-ui && npm run docs && npm run lint-docs",
|
|
78
79
|
"postpublish": "npm run clean && npm ci",
|
|
79
80
|
"clean": "shx rm -rf ./dist",
|