homebridge-melcloud-control 4.0.0-beta.340 → 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 CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "displayName": "MELCloud Control",
3
3
  "name": "homebridge-melcloud-control",
4
- "version": "4.0.0-beta.340",
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",
@@ -84,28 +84,72 @@ 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 tokenResponse = await axios.post(TOKEN_ENDPOINT, tokenData.toString(), {
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 = tokenResponse.data;
105
- this.emit('warn', `Token ${JSON.stringify(tokens)}`);
148
+ const tokens = response;
149
+ this.emit('warn', `Token ${JSON.stringify(response)}`);
106
150
  return tokens;
107
151
  } catch (error) {
108
- throw new Error(`Failed to obtain OAuth token: ${error.response?.data || error}`);
152
+ throw new Error(`Failed to obtain OAuth token: ${error}`);
109
153
  }
110
154
  }
111
155