homebridge-ring 13.2.0-beta.1 → 13.2.0-beta.2
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,5 +1,16 @@
|
|
|
1
1
|
# homebridge-ring
|
|
2
2
|
|
|
3
|
+
## 13.2.0-beta.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [`c6a3ff1`](https://github.com/dgreif/ring/commit/c6a3ff1b131abe9ef5df3faef7e4759b31689f30) Thanks [@dgreif](https://github.com/dgreif)! - Update dependencies
|
|
8
|
+
|
|
9
|
+
- [`6f83b8e`](https://github.com/dgreif/ring/commit/6f83b8e2cd48fc8ca6f101c293d38f4a5c6c42ab) Thanks [@dgreif](https://github.com/dgreif)! - Fix homebridge ui
|
|
10
|
+
|
|
11
|
+
- Updated dependencies [[`c6a3ff1`](https://github.com/dgreif/ring/commit/c6a3ff1b131abe9ef5df3faef7e4759b31689f30)]:
|
|
12
|
+
- ring-client-api@13.2.0-beta.2
|
|
13
|
+
|
|
3
14
|
## 13.2.0-beta.1
|
|
4
15
|
|
|
5
16
|
### Patch Changes
|
|
@@ -1,17 +1,180 @@
|
|
|
1
|
-
<button id="ring-new-token" class="btn btn-link m-0 p-0" style="display: none
|
|
1
|
+
<button id="ring-new-token" class="btn btn-link m-0 p-0" style="display: none">
|
|
2
2
|
<i class="fa fa-redo mr-2"></i>
|
|
3
3
|
Generate New Refresh Token
|
|
4
4
|
</button>
|
|
5
5
|
|
|
6
|
-
<h4
|
|
6
|
+
<h4
|
|
7
|
+
id="ring-link-account-header"
|
|
8
|
+
class="text-center primary-text mb-3"
|
|
9
|
+
style="display: none"
|
|
10
|
+
>
|
|
7
11
|
Link Ring Account
|
|
8
12
|
</h4>
|
|
9
13
|
|
|
10
14
|
<script type="module">
|
|
11
|
-
|
|
12
|
-
|
|
15
|
+
const { homebridge } = window
|
|
16
|
+
const newTokenButton = document.getElementById('ring-new-token')
|
|
17
|
+
const linkAccountHeader = document.getElementById('ring-link-account-header')
|
|
13
18
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
19
|
+
if (!newTokenButton) {
|
|
20
|
+
homebridge.toast.error('no ring-new-token element found!')
|
|
21
|
+
throw new Error('no ring-new-token element found!')
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
if (!linkAccountHeader) {
|
|
25
|
+
homebridge.toast.error('no ring-link-account-header element found!')
|
|
26
|
+
throw new Error('no ring-link-account-header element found!')
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
newTokenButton.addEventListener('click', () => {
|
|
30
|
+
showLoginForm()
|
|
31
|
+
})
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Render the correct form, based on whether we have an existing refresh token
|
|
35
|
+
*/
|
|
36
|
+
async function renderForm() {
|
|
37
|
+
const [config] = await homebridge.getPluginConfig()
|
|
38
|
+
const needToken = !config?.refreshToken
|
|
39
|
+
|
|
40
|
+
homebridge.hideSpinner()
|
|
41
|
+
|
|
42
|
+
if (needToken) {
|
|
43
|
+
showLoginForm()
|
|
44
|
+
} else {
|
|
45
|
+
showStandardForm()
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
renderForm()
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* @param {string} refreshToken
|
|
52
|
+
*/
|
|
53
|
+
async function setRefreshToken(refreshToken) {
|
|
54
|
+
const [config, ...otherConfigs] = await homebridge.getPluginConfig()
|
|
55
|
+
await homebridge.updatePluginConfig([
|
|
56
|
+
{ ...config, refreshToken },
|
|
57
|
+
...otherConfigs,
|
|
58
|
+
])
|
|
59
|
+
homebridge.toast.success('Refresh Token Updated', 'Ring Login Successful')
|
|
60
|
+
showStandardForm()
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function showStandardForm() {
|
|
64
|
+
newTokenButton?.style.setProperty('display', 'block')
|
|
65
|
+
linkAccountHeader?.style.setProperty('display', 'none')
|
|
66
|
+
homebridge.showSchemaForm()
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function showLoginForm() {
|
|
70
|
+
// Hide the standard form
|
|
71
|
+
newTokenButton?.style.setProperty('display', 'none')
|
|
72
|
+
linkAccountHeader?.style.setProperty('display', 'block')
|
|
73
|
+
homebridge.hideSchemaForm()
|
|
74
|
+
|
|
75
|
+
// Create a new login form
|
|
76
|
+
const form = homebridge.createForm(
|
|
77
|
+
{
|
|
78
|
+
schema: {
|
|
79
|
+
type: 'object',
|
|
80
|
+
properties: {
|
|
81
|
+
email: {
|
|
82
|
+
title: 'Email',
|
|
83
|
+
type: 'string',
|
|
84
|
+
'x-schema-form': {
|
|
85
|
+
type: 'email',
|
|
86
|
+
},
|
|
87
|
+
required: true,
|
|
88
|
+
},
|
|
89
|
+
password: {
|
|
90
|
+
title: 'Password',
|
|
91
|
+
type: 'string',
|
|
92
|
+
'x-schema-form': {
|
|
93
|
+
type: 'password',
|
|
94
|
+
},
|
|
95
|
+
required: true,
|
|
96
|
+
},
|
|
97
|
+
},
|
|
98
|
+
},
|
|
99
|
+
},
|
|
100
|
+
{},
|
|
101
|
+
'Log In',
|
|
102
|
+
)
|
|
103
|
+
|
|
104
|
+
form.onSubmit(async ({ email, password }) => {
|
|
105
|
+
homebridge.showSpinner()
|
|
106
|
+
|
|
107
|
+
try {
|
|
108
|
+
/** @type {{ codePrompt: string } | { refreshToken: string }} */
|
|
109
|
+
const response = await homebridge.request('/send-code', {
|
|
110
|
+
email,
|
|
111
|
+
password,
|
|
112
|
+
})
|
|
113
|
+
|
|
114
|
+
if ('refreshToken' in response) {
|
|
115
|
+
// didn't need 2fa, return token without asking for code
|
|
116
|
+
setRefreshToken(response.refreshToken)
|
|
117
|
+
} else {
|
|
118
|
+
// Need a token, so show the token form
|
|
119
|
+
showTokenForm({
|
|
120
|
+
email,
|
|
121
|
+
password,
|
|
122
|
+
codePrompt: response.codePrompt,
|
|
123
|
+
})
|
|
124
|
+
}
|
|
125
|
+
} catch (/** @type {any} */ e) {
|
|
126
|
+
// eslint-disable-next-line no-console
|
|
127
|
+
console.error(e)
|
|
128
|
+
homebridge.toast.error(e.message, 'Ring Login Failed')
|
|
129
|
+
} finally {
|
|
130
|
+
homebridge.hideSpinner()
|
|
131
|
+
}
|
|
132
|
+
})
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* @param {{ email: string, password: string, codePrompt: string }} loginInfo
|
|
137
|
+
*/
|
|
138
|
+
function showTokenForm(loginInfo) {
|
|
139
|
+
const form = homebridge.createForm(
|
|
140
|
+
{
|
|
141
|
+
schema: {
|
|
142
|
+
type: 'object',
|
|
143
|
+
properties: {
|
|
144
|
+
code: {
|
|
145
|
+
title: 'Code',
|
|
146
|
+
type: 'string',
|
|
147
|
+
required: true,
|
|
148
|
+
description: loginInfo.codePrompt,
|
|
149
|
+
},
|
|
150
|
+
},
|
|
151
|
+
},
|
|
152
|
+
},
|
|
153
|
+
{},
|
|
154
|
+
'Link Account',
|
|
155
|
+
'Change Email',
|
|
156
|
+
)
|
|
157
|
+
|
|
158
|
+
form.onSubmit(async ({ code }) => {
|
|
159
|
+
homebridge.showSpinner()
|
|
160
|
+
|
|
161
|
+
try {
|
|
162
|
+
const { refreshToken } = await homebridge.request('/token', {
|
|
163
|
+
email: loginInfo.email,
|
|
164
|
+
password: loginInfo.password,
|
|
165
|
+
code,
|
|
166
|
+
})
|
|
167
|
+
|
|
168
|
+
setRefreshToken(refreshToken)
|
|
169
|
+
} catch (/** @type {any} */ e) {
|
|
170
|
+
// eslint-disable-next-line no-console
|
|
171
|
+
console.error(e)
|
|
172
|
+
homebridge.toast.error(e.message, 'Failed to Link Account')
|
|
173
|
+
} finally {
|
|
174
|
+
homebridge.hideSpinner()
|
|
175
|
+
}
|
|
176
|
+
})
|
|
177
|
+
|
|
178
|
+
form.onCancel(() => showLoginForm())
|
|
179
|
+
}
|
|
17
180
|
</script>
|
package/package.json
CHANGED
|
@@ -1,24 +1,24 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "homebridge-ring",
|
|
3
3
|
"displayName": "Ring",
|
|
4
|
-
"version": "13.2.0-beta.
|
|
4
|
+
"version": "13.2.0-beta.2",
|
|
5
5
|
"description": "Homebridge plugin for Ring doorbells, cameras, security alarm system and smart lighting",
|
|
6
6
|
"main": "lib/index.js",
|
|
7
7
|
"scripts": {
|
|
8
|
-
"build": "rm -rf lib && tsc && cp ./homebridge-ui/public
|
|
8
|
+
"build": "rm -rf lib && tsc && cp -r ./homebridge-ui/public ./lib/homebridge-ui/public/",
|
|
9
9
|
"lint": "eslint . --ext .ts && tsc --noEmit",
|
|
10
10
|
"dev": "concurrently -c yellow,blue --kill-others \"npm:dev:build\" \"npm:dev:run\" ",
|
|
11
11
|
"dev:build": "tsc --watch --preserveWatchOutput",
|
|
12
12
|
"dev:run": "RING_DEBUG=true node --watch ../../node_modules/.bin/homebridge -U ../../.homebridge"
|
|
13
13
|
},
|
|
14
14
|
"dependencies": {
|
|
15
|
-
"@homebridge/camera-utils": "^2.2.7
|
|
15
|
+
"@homebridge/camera-utils": "^2.2.7",
|
|
16
16
|
"@homebridge/plugin-ui-utils": "^1.0.3",
|
|
17
|
-
"ring-client-api": "13.2.0-beta.
|
|
17
|
+
"ring-client-api": "13.2.0-beta.2",
|
|
18
18
|
"werift": "0.20.1"
|
|
19
19
|
},
|
|
20
20
|
"devDependencies": {
|
|
21
|
-
"concurrently": "^9.0
|
|
21
|
+
"concurrently": "^9.1.0",
|
|
22
22
|
"eslint-config-shared": "*",
|
|
23
23
|
"homebridge": "1.8.5",
|
|
24
24
|
"tsconfig": "*",
|
|
@@ -1,139 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const { homebridge } = window;
|
|
4
|
-
const newTokenButton = document.getElementById('ring-new-token');
|
|
5
|
-
const linkAccountHeader = document.getElementById('ring-link-account-header');
|
|
6
|
-
if (!newTokenButton) {
|
|
7
|
-
homebridge.toast.error('no ring-new-token element found!');
|
|
8
|
-
throw new Error('no ring-new-token element found!');
|
|
9
|
-
}
|
|
10
|
-
if (!linkAccountHeader) {
|
|
11
|
-
homebridge.toast.error('no ring-link-account-header element found!');
|
|
12
|
-
throw new Error('no ring-link-account-header element found!');
|
|
13
|
-
}
|
|
14
|
-
newTokenButton.addEventListener('click', () => {
|
|
15
|
-
showLoginForm();
|
|
16
|
-
});
|
|
17
|
-
/**
|
|
18
|
-
* Render the correct form, based on whether we have an existing refresh token
|
|
19
|
-
*/
|
|
20
|
-
async function renderForm() {
|
|
21
|
-
const [config] = await homebridge.getPluginConfig();
|
|
22
|
-
const needToken = !config?.refreshToken;
|
|
23
|
-
homebridge.hideSpinner();
|
|
24
|
-
if (needToken) {
|
|
25
|
-
showLoginForm();
|
|
26
|
-
}
|
|
27
|
-
else {
|
|
28
|
-
showStandardForm();
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
renderForm();
|
|
32
|
-
async function setRefreshToken(refreshToken) {
|
|
33
|
-
const [config, ...otherConfigs] = await homebridge.getPluginConfig();
|
|
34
|
-
await homebridge.updatePluginConfig([
|
|
35
|
-
{ ...config, refreshToken },
|
|
36
|
-
...otherConfigs,
|
|
37
|
-
]);
|
|
38
|
-
homebridge.toast.success('Refresh Token Updated', 'Ring Login Successful');
|
|
39
|
-
showStandardForm();
|
|
40
|
-
}
|
|
41
|
-
function showStandardForm() {
|
|
42
|
-
newTokenButton?.style.setProperty('display', 'block');
|
|
43
|
-
linkAccountHeader?.style.setProperty('display', 'none');
|
|
44
|
-
homebridge.showSchemaForm();
|
|
45
|
-
}
|
|
46
|
-
function showLoginForm() {
|
|
47
|
-
// Hide the standard form
|
|
48
|
-
newTokenButton?.style.setProperty('display', 'none');
|
|
49
|
-
linkAccountHeader?.style.setProperty('display', 'block');
|
|
50
|
-
homebridge.hideSchemaForm();
|
|
51
|
-
// Create a new login form
|
|
52
|
-
const form = homebridge.createForm({
|
|
53
|
-
schema: {
|
|
54
|
-
type: 'object',
|
|
55
|
-
properties: {
|
|
56
|
-
email: {
|
|
57
|
-
title: 'Email',
|
|
58
|
-
type: 'string',
|
|
59
|
-
'x-schema-form': {
|
|
60
|
-
type: 'email',
|
|
61
|
-
},
|
|
62
|
-
required: true,
|
|
63
|
-
},
|
|
64
|
-
password: {
|
|
65
|
-
title: 'Password',
|
|
66
|
-
type: 'string',
|
|
67
|
-
'x-schema-form': {
|
|
68
|
-
type: 'password',
|
|
69
|
-
},
|
|
70
|
-
required: true,
|
|
71
|
-
},
|
|
72
|
-
},
|
|
73
|
-
},
|
|
74
|
-
}, {}, 'Log In');
|
|
75
|
-
form.onSubmit(async ({ email, password }) => {
|
|
76
|
-
homebridge.showSpinner();
|
|
77
|
-
try {
|
|
78
|
-
const response = (await homebridge.request('/send-code', {
|
|
79
|
-
email,
|
|
80
|
-
password,
|
|
81
|
-
}));
|
|
82
|
-
if ('refreshToken' in response) {
|
|
83
|
-
// didn't need 2fa, return token without asking for code
|
|
84
|
-
setRefreshToken(response.refreshToken);
|
|
85
|
-
}
|
|
86
|
-
else {
|
|
87
|
-
// Need a token, so show the token form
|
|
88
|
-
showTokenForm({
|
|
89
|
-
email,
|
|
90
|
-
password,
|
|
91
|
-
codePrompt: response.codePrompt,
|
|
92
|
-
});
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
catch (e) {
|
|
96
|
-
// eslint-disable-next-line no-console
|
|
97
|
-
console.error(e);
|
|
98
|
-
homebridge.toast.error(e.message, 'Ring Login Failed');
|
|
99
|
-
}
|
|
100
|
-
finally {
|
|
101
|
-
homebridge.hideSpinner();
|
|
102
|
-
}
|
|
103
|
-
});
|
|
104
|
-
}
|
|
105
|
-
function showTokenForm(loginInfo) {
|
|
106
|
-
const form = homebridge.createForm({
|
|
107
|
-
schema: {
|
|
108
|
-
type: 'object',
|
|
109
|
-
properties: {
|
|
110
|
-
code: {
|
|
111
|
-
title: 'Code',
|
|
112
|
-
type: 'string',
|
|
113
|
-
required: true,
|
|
114
|
-
description: loginInfo.codePrompt,
|
|
115
|
-
},
|
|
116
|
-
},
|
|
117
|
-
},
|
|
118
|
-
}, {}, 'Link Account', 'Change Email');
|
|
119
|
-
form.onSubmit(async ({ code }) => {
|
|
120
|
-
homebridge.showSpinner();
|
|
121
|
-
try {
|
|
122
|
-
const { refreshToken } = await homebridge.request('/token', {
|
|
123
|
-
email: loginInfo.email,
|
|
124
|
-
password: loginInfo.password,
|
|
125
|
-
code,
|
|
126
|
-
});
|
|
127
|
-
setRefreshToken(refreshToken);
|
|
128
|
-
}
|
|
129
|
-
catch (e) {
|
|
130
|
-
// eslint-disable-next-line no-console
|
|
131
|
-
console.error(e);
|
|
132
|
-
homebridge.toast.error(e.message, 'Failed to Link Account');
|
|
133
|
-
}
|
|
134
|
-
finally {
|
|
135
|
-
homebridge.hideSpinner();
|
|
136
|
-
}
|
|
137
|
-
});
|
|
138
|
-
form.onCancel(() => showLoginForm());
|
|
139
|
-
}
|