homebridge-melcloud-control 4.0.0-beta.341 → 4.0.0-beta.342
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/package.json +1 -1
- package/src/melcloudhometoken.js +49 -5
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"displayName": "MELCloud Control",
|
|
3
3
|
"name": "homebridge-melcloud-control",
|
|
4
|
-
"version": "4.0.0-beta.
|
|
4
|
+
"version": "4.0.0-beta.342",
|
|
5
5
|
"description": "Homebridge plugin to control Mitsubishi Air Conditioner, Heat Pump and Energy Recovery Ventilation.",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"author": "grzegorz914",
|
package/src/melcloudhometoken.js
CHANGED
|
@@ -84,25 +84,69 @@ class MelCloudHomeToken extends EventEmitter {
|
|
|
84
84
|
}
|
|
85
85
|
}
|
|
86
86
|
|
|
87
|
+
async axiosRequestWithRedirects(url, options = {}, body, redirectCount = 0) {
|
|
88
|
+
if (redirectCount > 10) {
|
|
89
|
+
throw new Error('Too many redirects');
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
try {
|
|
93
|
+
const method = (options.method || 'GET').toUpperCase();
|
|
94
|
+
const headers = options.headers || {};
|
|
95
|
+
|
|
96
|
+
const response = await axios({
|
|
97
|
+
url,
|
|
98
|
+
method,
|
|
99
|
+
headers,
|
|
100
|
+
data: body,
|
|
101
|
+
maxRedirects: 0, // wyłączamy automatyczne redirecty
|
|
102
|
+
validateStatus: status => status >= 200 && status < 400,
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
// Ręczne follow dla 301/302
|
|
106
|
+
if ([301, 302].includes(response.status)) {
|
|
107
|
+
const location = response.headers.location;
|
|
108
|
+
if (!location) throw new Error('Redirect status without Location header');
|
|
109
|
+
|
|
110
|
+
const redirectUrl = location.startsWith('http') ? location : new URL(location, url).toString();
|
|
111
|
+
|
|
112
|
+
// Przy POST zachowujemy body i headers
|
|
113
|
+
return axiosRequestWithRedirects(redirectUrl, options, body, redirectCount + 1);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// Zwracamy odpowiedź jako string
|
|
117
|
+
if (typeof response.data === 'string') {
|
|
118
|
+
return response.data;
|
|
119
|
+
} else {
|
|
120
|
+
return JSON.stringify(response.data);
|
|
121
|
+
}
|
|
122
|
+
} catch (err) {
|
|
123
|
+
throw new Error(`Axios request failed: ${err.message || err}`);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
|
|
87
128
|
async getTokens(code, codeVerifier) {
|
|
88
129
|
try {
|
|
130
|
+
|
|
89
131
|
const tokenData = new URLSearchParams({
|
|
90
132
|
grant_type: 'authorization_code',
|
|
91
133
|
code: code,
|
|
92
134
|
redirect_uri: REDIRECT_URI,
|
|
93
135
|
client_id: CLIENT_ID,
|
|
94
136
|
code_verifier: codeVerifier,
|
|
95
|
-
});
|
|
137
|
+
}).toString();
|
|
96
138
|
|
|
97
|
-
const
|
|
139
|
+
const response = await axiosRequestWithRedirects(TOKEN_ENDPOINT, {
|
|
140
|
+
method: 'POST',
|
|
98
141
|
headers: {
|
|
99
142
|
'Content-Type': 'application/x-www-form-urlencoded',
|
|
100
143
|
'Authorization': 'Basic aG9tZW1vYmlsZTo=',
|
|
101
144
|
},
|
|
102
|
-
});
|
|
145
|
+
}, tokenData);
|
|
146
|
+
|
|
103
147
|
|
|
104
|
-
const tokens =
|
|
105
|
-
this.emit('warn', `Token ${JSON.stringify(
|
|
148
|
+
const tokens = response;
|
|
149
|
+
this.emit('warn', `Token ${JSON.stringify(response)}`);
|
|
106
150
|
return tokens;
|
|
107
151
|
} catch (error) {
|
|
108
152
|
throw new Error(`Failed to obtain OAuth token: ${error}`);
|