@jgrimard/homebridge-vivint 2.0.0 → 2.0.2-beta.0
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/README.md
CHANGED
|
@@ -4,6 +4,9 @@
|
|
|
4
4
|
|
|
5
5
|
# @jgrimard/homebridge-vivint
|
|
6
6
|
|
|
7
|
+
[](https://www.npmjs.com/package/@jgrimard/homebridge-vivint)
|
|
8
|
+
[](https://www.npmjs.com/package/@jgrimard/homebridge-vivint)
|
|
9
|
+
|
|
7
10
|
Homebridge plugin for [Vivint Smart Home](https://www.vivint.com). This is a fork of
|
|
8
11
|
[@balansse/homebridge-vivint](https://github.com/balansse/homebridge-vivint), rewritten in TypeScript
|
|
9
12
|
on the official [Homebridge plugin template](https://github.com/homebridge/homebridge-plugin-template)
|
|
@@ -47,6 +47,17 @@
|
|
|
47
47
|
const $ = (id) => document.getElementById(id);
|
|
48
48
|
const show = (el, visible) => { el.style.display = visible ? '' : 'none'; };
|
|
49
49
|
|
|
50
|
+
// homebridge.request() has no timeout: if the plugin's UI server process
|
|
51
|
+
// dies, the promise never settles and the spinner runs forever. Cap it so
|
|
52
|
+
// the user gets an actionable error instead.
|
|
53
|
+
const request = (path, body) => Promise.race([
|
|
54
|
+
homebridge.request(path, body),
|
|
55
|
+
new Promise((resolve, reject) => setTimeout(
|
|
56
|
+
() => reject(new Error('The plugin UI server did not respond within 45 seconds. Check the Homebridge log for errors mentioning homebridge-vivint, then close and reopen this settings window to try again.')),
|
|
57
|
+
45000,
|
|
58
|
+
)),
|
|
59
|
+
]);
|
|
60
|
+
|
|
50
61
|
let pluginConfig = await homebridge.getPluginConfig();
|
|
51
62
|
if (!pluginConfig.length) {
|
|
52
63
|
pluginConfig = [{ platform: 'Vivint', name: 'Vivint' }];
|
|
@@ -87,7 +98,7 @@
|
|
|
87
98
|
button.disabled = true;
|
|
88
99
|
homebridge.showSpinner();
|
|
89
100
|
try {
|
|
90
|
-
const response = await
|
|
101
|
+
const response = await request('/login', {
|
|
91
102
|
username: $('email').value,
|
|
92
103
|
password: $('password').value,
|
|
93
104
|
});
|
|
@@ -113,7 +124,7 @@
|
|
|
113
124
|
button.disabled = true;
|
|
114
125
|
homebridge.showSpinner();
|
|
115
126
|
try {
|
|
116
|
-
const response = await
|
|
127
|
+
const response = await request('/verify-code', { code: $('mfaCode').value });
|
|
117
128
|
await saveToken(response.refreshToken);
|
|
118
129
|
} catch (error) {
|
|
119
130
|
homebridge.toast.error(error.message || 'Verification failed.', 'Error');
|
|
@@ -8,6 +8,14 @@ import { HomebridgePluginUiServer, RequestError } from '@homebridge/plugin-ui-ut
|
|
|
8
8
|
* This file is intentionally self-contained: it runs as a separate process
|
|
9
9
|
* spawned by the Homebridge UI and does not load the plugin itself.
|
|
10
10
|
*/
|
|
11
|
+
// Diagnostics: these land in the Homebridge log prefixed with the plugin
|
|
12
|
+
// name. Never log tokens, cookies, or credentials here.
|
|
13
|
+
process.on('uncaughtException', (error) => {
|
|
14
|
+
console.error('Vivint UI server uncaught exception:', error);
|
|
15
|
+
});
|
|
16
|
+
process.on('unhandledRejection', (reason) => {
|
|
17
|
+
console.error('Vivint UI server unhandled rejection:', reason);
|
|
18
|
+
});
|
|
11
19
|
const VIVINT_LOGIN_URL = 'https://www.vivintsky.com/api/login';
|
|
12
20
|
const VIVINT_AUTHUSER_URL = 'https://www.vivintsky.com/api/authuser';
|
|
13
21
|
const VIVINT_MFA_URL = 'https://www.vivintsky.com/platform-user-api/v0/platformusers/2fa/validate';
|
|
@@ -17,11 +25,16 @@ function extractSessionCookie(response) {
|
|
|
17
25
|
return setCookies.find(cookie => cookie.startsWith('s='))?.split(';')[0];
|
|
18
26
|
}
|
|
19
27
|
async function vivintFetch(url, init) {
|
|
28
|
+
const step = new URL(url).pathname;
|
|
20
29
|
try {
|
|
21
|
-
|
|
30
|
+
console.log(`Vivint UI: requesting ${step} ...`);
|
|
31
|
+
const response = await fetch(url, { ...init, signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS) });
|
|
32
|
+
console.log(`Vivint UI: ${step} responded with HTTP ${response.status}`);
|
|
33
|
+
return response;
|
|
22
34
|
}
|
|
23
35
|
catch (error) {
|
|
24
36
|
const reason = error instanceof Error ? error.message : String(error);
|
|
37
|
+
console.error(`Vivint UI: ${step} failed: ${reason}`);
|
|
25
38
|
throw new RequestError(`Could not reach Vivint (${reason}). Check your internet connection and try again.`, {});
|
|
26
39
|
}
|
|
27
40
|
}
|
|
@@ -79,6 +92,7 @@ class VivintUiServer extends HomebridgePluginUiServer {
|
|
|
79
92
|
this.pendingToken = rotatedCookie;
|
|
80
93
|
}
|
|
81
94
|
if (authResponse.status === 401) {
|
|
95
|
+
console.log('Vivint UI: sign-in ok, MFA verification required');
|
|
82
96
|
return { requiresMfa: true };
|
|
83
97
|
}
|
|
84
98
|
if (!authResponse.ok) {
|
|
@@ -111,6 +125,7 @@ class VivintUiServer extends HomebridgePluginUiServer {
|
|
|
111
125
|
if (rotatedCookie) {
|
|
112
126
|
this.pendingToken = rotatedCookie;
|
|
113
127
|
}
|
|
128
|
+
console.log('Vivint UI: MFA verification succeeded');
|
|
114
129
|
const token = this.pendingToken;
|
|
115
130
|
this.pendingToken = '';
|
|
116
131
|
return { refreshToken: token };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../homebridge-ui/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAErF;;;;;;;;GAQG;AAEH,MAAM,gBAAgB,GAAG,qCAAqC,CAAC;AAC/D,MAAM,mBAAmB,GAAG,wCAAwC,CAAC;AACrE,MAAM,cAAc,GAAG,2EAA2E,CAAC;AACnG,MAAM,kBAAkB,GAAG,MAAM,CAAC;AAElC,SAAS,oBAAoB,CAAC,QAAkB;IAC9C,MAAM,UAAU,GAAG,QAAQ,CAAC,OAAO,CAAC,YAAY,EAAE,EAAE,IAAI,EAAE,CAAC;IAC3D,OAAO,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;AAC3E,CAAC;AAED,KAAK,UAAU,WAAW,CAAC,GAAW,EAAE,IAAiB;IACvD,IAAI,CAAC;QACH,OAAO,MAAM,KAAK,CAAC,GAAG,EAAE,EAAE,GAAG,IAAI,EAAE,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,kBAAkB,CAAC,EAAE,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../homebridge-ui/server.ts"],"names":[],"mappings":"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"}
|
package/dist/settings.js
CHANGED
|
@@ -2,11 +2,15 @@
|
|
|
2
2
|
* The platform name users put in config.json ("platform": "Vivint").
|
|
3
3
|
*/
|
|
4
4
|
export const PLATFORM_NAME = 'Vivint';
|
|
5
|
+
import { readFileSync } from 'node:fs';
|
|
5
6
|
/**
|
|
6
|
-
* Plugin identifier used when registering accessories.
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
7
|
+
* Plugin identifier used when registering accessories. Read from package.json
|
|
8
|
+
* so it always matches the name this package is actually installed under
|
|
9
|
+
* (scoped @jgrimard fork or unscoped upstream). Registering under any other
|
|
10
|
+
* name makes Homebridge warn "no loaded plugin could be found for the name".
|
|
11
|
+
* Cached accessories from @balansse/homebridge-vivint still carry over: on
|
|
12
|
+
* restore, Homebridge resolves an unknown plugin name via the active dynamic
|
|
13
|
+
* platform (PLATFORM_NAME) and rewrites the cache.
|
|
10
14
|
*/
|
|
11
|
-
export const PLUGIN_NAME = '
|
|
15
|
+
export const PLUGIN_NAME = JSON.parse(readFileSync(new URL('../package.json', import.meta.url), 'utf-8')).name;
|
|
12
16
|
//# sourceMappingURL=settings.js.map
|
package/dist/settings.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"settings.js","sourceRoot":"","sources":["../src/settings.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,QAAQ,CAAC;AAEtC
|
|
1
|
+
{"version":3,"file":"settings.js","sourceRoot":"","sources":["../src/settings.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,QAAQ,CAAC;AAEtC,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAEvC;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,WAAW,GAAW,IAAI,CAAC,KAAK,CAC3C,YAAY,CAAC,IAAI,GAAG,CAAC,iBAAiB,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC,CACnE,CAAC,IAAI,CAAC"}
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@jgrimard/homebridge-vivint",
|
|
3
3
|
"displayName": "Homebridge Vivint",
|
|
4
4
|
"type": "module",
|
|
5
|
-
"version": "2.0.0",
|
|
5
|
+
"version": "2.0.2-beta.0",
|
|
6
6
|
"description": "Homebridge plugin for Vivint Smart Home security systems and devices.",
|
|
7
7
|
"license": "Apache-2.0",
|
|
8
8
|
"author": "Jason Grimard",
|