n8n-nodes-jygse-vw-weconnect 0.1.5 → 0.1.7

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.
@@ -141,11 +141,11 @@ class VwWeConnect {
141
141
  }
142
142
  }
143
143
  exports.VwWeConnect = VwWeConnect;
144
- // VW OAuth2 Configuration (Updated January 2026)
145
- const VW_CLIENT_ID = 'a24fba63-34b3-4d43-b181-942111e6bda8@apps_vw-dilab_com';
146
- const VW_SCOPE = 'openid profile badge cars dealers birthdate vin';
147
- const VW_REDIRECT_URI = 'weconnect://authenticated';
148
- const VW_RESPONSE_TYPE = 'code id_token token';
144
+ // VW OAuth2 Configuration (Updated January 2026 - from ioBroker.vw-connect)
145
+ const VW_CLIENT_ID = '9496332b-ea03-4091-a224-8c746b885068@apps_vw-dilab_com';
146
+ const VW_SCOPE = 'openid profile mbb email cars birthdate badge address vin';
147
+ const VW_REDIRECT_URI = 'carnet://identity-kit/login';
148
+ const VW_RESPONSE_TYPE = 'id_token token code';
149
149
  // Generate PKCE code verifier and challenge
150
150
  function generateCodeVerifier() {
151
151
  const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~';
@@ -271,26 +271,66 @@ async function vwLogin(context, email, password) {
271
271
  maxInitialRedirects--;
272
272
  }
273
273
  // Try to extract state token from the final HTML if not found in URL
274
+ // Auth0 embeds the state in various ways
275
+ // Method 1: Hidden form field
274
276
  if (!stateToken) {
275
277
  const stateHtmlMatch = htmlContent.match(/name="state"\s+value="([^"]+)"/);
276
278
  if (stateHtmlMatch) {
277
279
  stateToken = stateHtmlMatch[1];
278
280
  }
279
281
  }
280
- // Try to find state in form action URL
282
+ // Method 2: Form action URL
281
283
  if (!stateToken) {
282
284
  const formActionMatch = htmlContent.match(/action="[^"]*\?state=([^"&]+)/);
283
285
  if (formActionMatch) {
284
286
  stateToken = decodeURIComponent(formActionMatch[1]);
285
287
  }
286
288
  }
287
- // Try to extract state from any URL in the page
289
+ // Method 3: JavaScript variable or config object
290
+ if (!stateToken) {
291
+ const jsStateMatch = htmlContent.match(/"state"\s*:\s*"([^"]+)"/);
292
+ if (jsStateMatch) {
293
+ stateToken = jsStateMatch[1];
294
+ }
295
+ }
296
+ // Method 4: data-state attribute
297
+ if (!stateToken) {
298
+ const dataStateMatch = htmlContent.match(/data-state="([^"]+)"/);
299
+ if (dataStateMatch) {
300
+ stateToken = dataStateMatch[1];
301
+ }
302
+ }
303
+ // Method 5: Auth0 config in script tag
304
+ if (!stateToken) {
305
+ const auth0ConfigMatch = htmlContent.match(/config\s*=\s*\{[^}]*state[^}]*\}/);
306
+ if (auth0ConfigMatch) {
307
+ const configStateMatch = auth0ConfigMatch[0].match(/state['"]\s*:\s*['"]([^'"]+)['"]/);
308
+ if (configStateMatch) {
309
+ stateToken = configStateMatch[1];
310
+ }
311
+ }
312
+ }
313
+ // Method 6: URL in any href or src with state parameter
314
+ if (!stateToken) {
315
+ const hrefStateMatch = htmlContent.match(/(?:href|src|action)="[^"]*[?&]state=([^"&]+)/);
316
+ if (hrefStateMatch) {
317
+ stateToken = decodeURIComponent(hrefStateMatch[1]);
318
+ }
319
+ }
320
+ // Method 7: Any state= pattern in HTML (last resort)
288
321
  if (!stateToken) {
289
322
  const anyStateMatch = htmlContent.match(/state=([a-zA-Z0-9_.-]+)/);
290
323
  if (anyStateMatch) {
291
324
  stateToken = anyStateMatch[1];
292
325
  }
293
326
  }
327
+ // Method 8: Extract from window.__AUTH0_STATE or similar
328
+ if (!stateToken) {
329
+ const windowStateMatch = htmlContent.match(/__(?:AUTH0_)?STATE__?\s*=\s*['"]([^'"]+)['"]/i);
330
+ if (windowStateMatch) {
331
+ stateToken = windowStateMatch[1];
332
+ }
333
+ }
294
334
  // Try legacy CSRF-based flow first
295
335
  const csrfMatch = htmlContent.match(/name="_csrf"\s+value="([^"]+)"/);
296
336
  const relayStateMatch = htmlContent.match(/name="relayState"\s+value="([^"]+)"/);
@@ -392,7 +432,11 @@ async function vwLogin(context, email, password) {
392
432
  }
393
433
  }
394
434
  if (!stateToken) {
395
- throw new Error(`Could not extract state token from Auth0 login page. Response preview: ${htmlContent.substring(0, 500)}`);
435
+ // Show more of the HTML to help debug
436
+ const htmlPreview = htmlContent.substring(0, 2000);
437
+ const formMatch = htmlContent.match(/<form[^>]*>[\s\S]*?<\/form>/i);
438
+ const formPreview = formMatch ? formMatch[0].substring(0, 500) : 'No form found';
439
+ throw new Error(`Could not extract state token. Form: ${formPreview} | HTML preview: ${htmlPreview}`);
396
440
  }
397
441
  // Submit credentials to Auth0 /u/login endpoint
398
442
  const loginResponse = await context.helpers.httpRequest({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "n8n-nodes-jygse-vw-weconnect",
3
- "version": "0.1.5",
3
+ "version": "0.1.7",
4
4
  "description": "n8n community node for VW We Connect - Control your Volkswagen T6.1 and other VW vehicles",
5
5
  "keywords": [
6
6
  "n8n-community-node-package",