homebridge-yoto 0.0.5 → 0.0.6
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/lib/auth.js +35 -18
- package/lib/constants.js +5 -4
- package/package.json +1 -1
package/lib/auth.js
CHANGED
|
@@ -36,22 +36,34 @@ export class YotoAuth {
|
|
|
36
36
|
*/
|
|
37
37
|
async initiateDeviceFlow () {
|
|
38
38
|
this.log.info(LOG_PREFIX.AUTH, 'Initiating device authorization flow...')
|
|
39
|
+
this.log.debug(LOG_PREFIX.AUTH, `Client ID: ${this.clientId}`)
|
|
40
|
+
this.log.debug(LOG_PREFIX.AUTH, `Endpoint: ${YOTO_OAUTH_DEVICE_CODE_URL}`)
|
|
41
|
+
this.log.debug(LOG_PREFIX.AUTH, `Scope: ${OAUTH_SCOPE}`)
|
|
42
|
+
this.log.debug(LOG_PREFIX.AUTH, `Audience: ${OAUTH_AUDIENCE}`)
|
|
39
43
|
|
|
40
44
|
try {
|
|
45
|
+
const params = new URLSearchParams({
|
|
46
|
+
client_id: this.clientId,
|
|
47
|
+
scope: OAUTH_SCOPE,
|
|
48
|
+
audience: OAUTH_AUDIENCE
|
|
49
|
+
})
|
|
50
|
+
this.log.debug(LOG_PREFIX.AUTH, 'Request body:', params.toString())
|
|
51
|
+
|
|
41
52
|
const response = await fetch(YOTO_OAUTH_DEVICE_CODE_URL, {
|
|
42
53
|
method: 'POST',
|
|
43
54
|
headers: {
|
|
44
|
-
'Content-Type': 'application/
|
|
55
|
+
'Content-Type': 'application/x-www-form-urlencoded'
|
|
45
56
|
},
|
|
46
|
-
body:
|
|
47
|
-
client_id: this.clientId,
|
|
48
|
-
scope: OAUTH_SCOPE,
|
|
49
|
-
audience: OAUTH_AUDIENCE
|
|
50
|
-
})
|
|
57
|
+
body: params
|
|
51
58
|
})
|
|
52
59
|
|
|
60
|
+
this.log.debug(LOG_PREFIX.AUTH, `Response status: ${response.status}`)
|
|
61
|
+
this.log.debug(LOG_PREFIX.AUTH, 'Response headers:', Object.fromEntries(response.headers.entries()))
|
|
62
|
+
|
|
53
63
|
if (!response.ok) {
|
|
54
64
|
const errorText = await response.text()
|
|
65
|
+
this.log.error(LOG_PREFIX.AUTH, `Device code request failed with status ${response.status}`)
|
|
66
|
+
this.log.error(LOG_PREFIX.AUTH, `Error response: ${errorText}`)
|
|
55
67
|
throw new Error(`Device code request failed: ${response.status} ${errorText}`)
|
|
56
68
|
}
|
|
57
69
|
|
|
@@ -89,16 +101,19 @@ export class YotoAuth {
|
|
|
89
101
|
|
|
90
102
|
while (Date.now() - startTime < timeout) {
|
|
91
103
|
try {
|
|
104
|
+
const params = new URLSearchParams({
|
|
105
|
+
grant_type: 'urn:ietf:params:oauth:grant-type:device_code',
|
|
106
|
+
device_code: deviceCode,
|
|
107
|
+
client_id: this.clientId,
|
|
108
|
+
audience: OAUTH_AUDIENCE
|
|
109
|
+
})
|
|
110
|
+
|
|
92
111
|
const response = await fetch(YOTO_OAUTH_TOKEN_URL, {
|
|
93
112
|
method: 'POST',
|
|
94
113
|
headers: {
|
|
95
|
-
'Content-Type': 'application/
|
|
114
|
+
'Content-Type': 'application/x-www-form-urlencoded'
|
|
96
115
|
},
|
|
97
|
-
body:
|
|
98
|
-
grant_type: 'urn:ietf:params:oauth:grant-type:device_code',
|
|
99
|
-
device_code: deviceCode,
|
|
100
|
-
client_id: this.clientId
|
|
101
|
-
})
|
|
116
|
+
body: params
|
|
102
117
|
})
|
|
103
118
|
|
|
104
119
|
if (response.ok) {
|
|
@@ -153,16 +168,18 @@ export class YotoAuth {
|
|
|
153
168
|
this.log.debug(LOG_PREFIX.AUTH, 'Refreshing access token...')
|
|
154
169
|
|
|
155
170
|
try {
|
|
171
|
+
const params = new URLSearchParams({
|
|
172
|
+
grant_type: 'refresh_token',
|
|
173
|
+
refresh_token: refreshToken,
|
|
174
|
+
client_id: this.clientId
|
|
175
|
+
})
|
|
176
|
+
|
|
156
177
|
const response = await fetch(YOTO_OAUTH_TOKEN_URL, {
|
|
157
178
|
method: 'POST',
|
|
158
179
|
headers: {
|
|
159
|
-
'Content-Type': 'application/
|
|
180
|
+
'Content-Type': 'application/x-www-form-urlencoded'
|
|
160
181
|
},
|
|
161
|
-
body:
|
|
162
|
-
grant_type: 'refresh_token',
|
|
163
|
-
refresh_token: refreshToken,
|
|
164
|
-
client_id: this.clientId
|
|
165
|
-
})
|
|
182
|
+
body: params
|
|
166
183
|
})
|
|
167
184
|
|
|
168
185
|
if (!response.ok) {
|
package/lib/constants.js
CHANGED
|
@@ -12,9 +12,10 @@ export const PLUGIN_NAME = 'homebridge-yoto'
|
|
|
12
12
|
* Yoto API endpoints
|
|
13
13
|
*/
|
|
14
14
|
export const YOTO_API_BASE_URL = 'https://api.yotoplay.com'
|
|
15
|
-
export const
|
|
16
|
-
export const
|
|
17
|
-
export const
|
|
15
|
+
export const YOTO_OAUTH_BASE_URL = 'https://login.yotoplay.com'
|
|
16
|
+
export const YOTO_OAUTH_AUTHORIZE_URL = `${YOTO_OAUTH_BASE_URL}/authorize`
|
|
17
|
+
export const YOTO_OAUTH_TOKEN_URL = `${YOTO_OAUTH_BASE_URL}/oauth/token`
|
|
18
|
+
export const YOTO_OAUTH_DEVICE_CODE_URL = `${YOTO_OAUTH_BASE_URL}/oauth/device/code`
|
|
18
19
|
|
|
19
20
|
/**
|
|
20
21
|
* MQTT configuration
|
|
@@ -45,7 +46,7 @@ export const MQTT_TOPIC_COMMAND_REBOOT = '/device/{deviceId}/command/reboot'
|
|
|
45
46
|
*/
|
|
46
47
|
export const OAUTH_CLIENT_ID = 'Y4HJ8BFqRQ24GQoLzgOzZ2KSqWmFG8LI'
|
|
47
48
|
export const OAUTH_AUDIENCE = 'https://api.yotoplay.com'
|
|
48
|
-
export const OAUTH_SCOPE = 'profile offline_access
|
|
49
|
+
export const OAUTH_SCOPE = 'profile offline_access'
|
|
49
50
|
export const OAUTH_POLLING_INTERVAL = 5000 // milliseconds
|
|
50
51
|
export const OAUTH_DEVICE_CODE_TIMEOUT = 300000 // 5 minutes
|
|
51
52
|
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "homebridge-yoto",
|
|
3
3
|
"description": "Control your Yoto players through Apple HomeKit with real-time MQTT updates",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.6",
|
|
5
5
|
"author": "Bret Comnes <bcomnes@gmail.com> (https://bret.io)",
|
|
6
6
|
"bugs": {
|
|
7
7
|
"url": "https://github.com/bcomnes/homebridge-yoto/issues"
|