homebridge-melcloud-control 4.0.0-beta.307 → 4.0.0-beta.309

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.307",
4
+ "version": "4.0.0-beta.309",
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
@@ -284,14 +284,27 @@ class MelCloud extends EventEmitter {
284
284
  async connectToMelCloudHome() {
285
285
  let browser;
286
286
  try {
287
+
288
+ const melCloudHomeToken = new MelCloudHomeToken({
289
+ user: this.user,
290
+ passwd: this.passwd,
291
+ logWarn: this.logWarn,
292
+ logError: this.logError,
293
+ })
294
+ .on('success', message => this.emit('success', message))
295
+ .on('warn', warn => this.emit('warn', warn))
296
+ .on('error', error => this.emit('error', error));
297
+
298
+ const data = await melCloudHomeToken.buildAuthorizeUrl();
299
+ const code = await melCloudHomeToken.loginToMelCloudHome(data.url);
300
+
301
+ return false
302
+
287
303
  browser = await puppeteer.launch({
288
304
  headless: true,
289
305
  args: ['--no-sandbox', '--disable-setuid-sandbox']
290
306
  });
291
307
 
292
- const melCloudHomeToken = new MelCloudHomeToken();
293
- const data = await melCloudHomeToken.buildAuthorizeUrl();
294
-
295
308
  const page = await browser.newPage();
296
309
  await page.goto(data.url, { waitUntil: 'networkidle2' });
297
310
 
@@ -301,7 +314,7 @@ class MelCloud extends EventEmitter {
301
314
  const button1 = await page.$('input[type="submit"]');
302
315
  await Promise.all([button1.click(), page.waitForNavigation({ waitUntil: 'networkidle2', timeout: 10000 })]);
303
316
  const html = await page.content();
304
- const code = await melCloudHomeToken.extractCodeFromHtml(html);
317
+ const code1 = await melCloudHomeToken.extractCodeFromHtml(html);
305
318
  this.emit('warn', code);
306
319
 
307
320
  // 5. Wymień code na access_token
@@ -321,7 +334,6 @@ class MelCloud extends EventEmitter {
321
334
  }
322
335
  }
323
336
 
324
-
325
337
  async connectToMelCloudHome1(refresh = false) {
326
338
  if (this.logDebug) this.emit('debug', `Connecting to MELCloud Home`);
327
339
 
@@ -2,6 +2,7 @@ import axios from 'axios';
2
2
  import crypto from 'crypto';
3
3
  import { wrapper } from 'axios-cookiejar-support';
4
4
  import { CookieJar } from 'tough-cookie';
5
+ import EventEmitter from 'events';
5
6
 
6
7
  const MOBILE_USER_AGENT = 'MonitorAndControl.App.Mobile/35 CFNetwork/3860.100.1 Darwin/25.0.0';
7
8
  const CLIENT_ID = 'homemobile';
@@ -10,8 +11,14 @@ const SCOPE = 'openid profile email offline_access IdentityServerApi';
10
11
  const TOKEN_ENDPOINT = 'https://auth.melcloudhome.com/connect/token';
11
12
  const AUTHORIZE_ENDPOINT = 'https://auth.melcloudhome.com/connect/authorize';
12
13
 
13
- class MelCloudHomeToken {
14
- constructor() {
14
+ class MelCloudHomeToken extends EventEmitter {
15
+ constructor(config) {
16
+ super();
17
+ this.user = config.user;
18
+ this.passwd = config.passwd;
19
+ this.serialNumber = config.serialNumber;
20
+ this.logWarn = config.logWarn;
21
+ this.logError = config.logError;
15
22
  const jar = new CookieJar();
16
23
  this.client = wrapper(axios.create({ jar, withCredentials: true }));
17
24
  this.client.defaults.headers['User-Agent'] = MOBILE_USER_AGENT;
@@ -90,8 +97,7 @@ class MelCloudHomeToken {
90
97
  url: TOKEN_ENDPOINT,
91
98
  headers: {
92
99
  'Content-Type': 'application/x-www-form-urlencoded',
93
- 'Content-Length': data.toString().length,
94
- 'Authorization': 'Basic aG9tZW1vYmlsZTo='
100
+ 'Content-Length': data.toString().length
95
101
  },
96
102
  data: data
97
103
  });
@@ -107,7 +113,6 @@ class MelCloudHomeToken {
107
113
  }
108
114
  }
109
115
 
110
-
111
116
  async buildAuthorizeUrl() {
112
117
  try {
113
118
  const pkce = this.generatePKCE();
@@ -120,8 +125,8 @@ class MelCloudHomeToken {
120
125
  authUrl.searchParams.set('code_challenge', pkce.challenge);
121
126
  authUrl.searchParams.set('code_challenge_method', 'S256');
122
127
  authUrl.searchParams.set('state', state);
123
- const loginPage = await this.getLoginPage(authUrl.toString());
124
128
 
129
+ const loginPage = await this.getLoginPage(authUrl.toString());
125
130
  const data = { codeVerifier: pkce.verifier, url: loginPage.url }
126
131
  return data;
127
132
  } catch (error) {
@@ -129,6 +134,41 @@ class MelCloudHomeToken {
129
134
  throw error;
130
135
  }
131
136
  }
137
+
138
+ async loginToMelCloudHome(url) {
139
+ try {
140
+ const form = new URLSearchParams();
141
+ form.append('user[email]', this.user);
142
+ form.append('user[password]', this.passwd);
143
+
144
+ const response = await axios({
145
+ method: 'POST',
146
+ baseURL: url,
147
+ headers: {
148
+ 'Content-Type': 'application/x-www-form-urlencoded'
149
+ },
150
+ data: form,
151
+ timeout: 10000
152
+ });
153
+
154
+ this.emit('warn', `No cookie returned from login. Response headers: ${JSON.stringify(response)}`);
155
+
156
+ if (response.status !== 200) {
157
+ if (this.logError) this.emit('error', `Login failed with status code: ${response.status}`);
158
+ return null;
159
+ }
160
+
161
+ const cookie = response.headers['set-cookie'];
162
+ if (!cookie) {
163
+ if (this.logWarn) this.emit('warn', `No cookie returned from login. Response headers: ${JSON.stringify(response.headers)}`);
164
+ return null;
165
+ }
166
+
167
+ return cookie;
168
+ } catch (error) {
169
+ throw new Error(`Login to Enlighten error: ${error}`);
170
+ }
171
+ }
132
172
  }
133
173
 
134
174
  export default MelCloudHomeToken;