homebridge-melcloud-control 4.0.0-beta.332 → 4.0.0-beta.334

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "displayName": "MELCloud Control",
3
3
  "name": "homebridge-melcloud-control",
4
- "version": "4.0.0-beta.332",
4
+ "version": "4.0.0-beta.334",
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/melcloud.js CHANGED
@@ -294,9 +294,13 @@ class MelCloud extends EventEmitter {
294
294
  .on('error', error => this.emit('error', error));
295
295
 
296
296
  const data = await melCloudHomeToken.buildAuthorizeUrl();
297
- const cookies = await melCloudHomeToken.loginToMelCloudHome(data.url);
298
297
 
299
- const accountInfo = { ContextKey: cookies, UseFahrenheit: false };
298
+ const url = data.url;
299
+ const codeVerifier = data.codeVerifier;
300
+ const code = await melCloudHomeToken.loginToMelCloudHome(url);
301
+ const token = await melCloudHomeToken.getTokens(code, codeVerifier);
302
+
303
+ const accountInfo = { ContextKey: token, UseFahrenheit: false };
300
304
  this.contextKey = cookies;
301
305
 
302
306
  return accountInfo
@@ -3,6 +3,7 @@ import crypto from 'crypto';
3
3
  import { wrapper } from 'axios-cookiejar-support';
4
4
  import { CookieJar } from 'tough-cookie';
5
5
  import { JSDOM } from 'jsdom';
6
+ import QueryString from 'querystring';
6
7
  import EventEmitter from 'events';
7
8
 
8
9
  const MOBILE_USER_AGENT = 'MonitorAndControl.App.Mobile/35 CFNetwork/3860.100.1 Darwin/25.0.0';
@@ -84,6 +85,33 @@ class MelCloudHomeToken extends EventEmitter {
84
85
  }
85
86
 
86
87
  async getTokens(code, codeVerifier) {
88
+ try {
89
+ const payload = {
90
+ "client_id": CLIENT_ID,
91
+ "grant_type": 'authorization_code',
92
+ "scope": SCOPE,
93
+ "code": code,
94
+ "redirect_uri": REDIRECT_URI,
95
+ "code_verifier": codeVerifier
96
+ }
97
+
98
+ const postData = QueryString.stringify(payload);
99
+ const headers = { 'Content-Type': 'application/x-www-form-urlencoded' };
100
+ const response = await axios.post(TOKEN_ENDPOINT, postData, headers);
101
+ const accessToken = response.data;
102
+ this.emit('warn', `Token ${tokenResponse.data}`);
103
+
104
+
105
+ //accessToken.issued = new Date().toISOString();
106
+ //this.tokens.oauth = accessToken;
107
+ //await this.functions.saveData(this.tokensFile, this.tokens);
108
+ return accessToken;
109
+ } catch (error) {
110
+ throw new Error(`Access token error: ${error}`);
111
+ }
112
+ }
113
+
114
+ async getTokens1(code, codeVerifier) {
87
115
  try {
88
116
  const tokenResponse = await axios.post(TOKEN_ENDPOINT, new URLSearchParams({
89
117
  grant_type: 'authorization_code',
@@ -132,7 +160,7 @@ class MelCloudHomeToken extends EventEmitter {
132
160
  form.append('cognitoAsfData', '');
133
161
  form.append('_csrf', csrf);
134
162
 
135
- if (this.logWarn) this.emit('warn', `Redirect URL: ${url}`);
163
+ if (this.logWarn) this.emit('warn', `Redirect URL: ${url}`);
136
164
 
137
165
  // Step 3: Wyślij POST z danymi logowania
138
166
  const response = await axios.post(url, form.toString(), {
@@ -152,34 +180,12 @@ class MelCloudHomeToken extends EventEmitter {
152
180
  const redirectUrl = response.headers.location;
153
181
  if (this.logWarn) this.emit('warn', `Redirect URL: ${redirectUrl}`);
154
182
 
155
- // 🔹 wykonaj GET na redirect URL (tam ustawiane są C1/C2)
156
- const finalResp = await axios.get(redirectUrl, {
157
- headers: {
158
- 'User-Agent': MOBILE_USER_AGENT,
159
- },
160
- maxRedirects: 0,
161
- validateStatus: s => [200, 302].includes(s),
162
- });
163
-
164
- if (this.logWarn) this.emit('warn', `Redirect URL: ${finalResp}`);
165
-
166
- const finalCookies = finalResp.headers['set-cookie'] || [];
167
- const c1 = finalCookies.find(c => c.startsWith('__Secure-monitorandcontrolC1='))?.split(';')[0];
168
- const c2 = finalCookies.find(c => c.startsWith('__Secure-monitorandcontrolC2='))?.split(';')[0];
169
-
170
- if (c1 && c2) {
171
- const cookieHeader = ['__Secure-monitorandcontrol=chunks-2', c1, c2].join('; ');
172
- if (this.logWarn) this.emit('warn', `Cookie returned: ${cookieHeader}`);
173
-
174
- return cookieHeader;
175
- }
176
-
177
183
  const match = redirectUrl.match(/[?&]code=([^&]+)/);
178
184
  if (match) {
179
185
  const code = match[1];
186
+ if (this.logWarn) this.emit('warn', `Redirect URL found code: ${code}`);
180
187
  return code;
181
188
  } else {
182
- console.warn('Redirect URL found, but no "code=" param.');
183
189
  if (this.logWarn) this.emit('warn', `Redirect URL found, but no "code=" param: ${redirectUrl}`);
184
190
  return null;
185
191
  }