n8n-nodes-jygse-vw-weconnect 0.1.16 → 0.2.1

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,17 +141,15 @@ class VwWeConnect {
141
141
  }
142
142
  }
143
143
  exports.VwWeConnect = VwWeConnect;
144
- // VW OAuth2 Configuration (Updated January 2026 - from WeConnect-python)
144
+ // VW OAuth2 Configuration (Updated January 2026 - from ioBroker.vw-connect)
145
145
  const VW_CLIENT_ID = 'a24fba63-34b3-4d43-b181-942111e6bda8@apps_vw-dilab_com';
146
- const VW_SCOPE = 'openid profile badge cars dealers vin';
146
+ const VW_SCOPE = 'openid profile badge cars dealers birthdate vin';
147
147
  const VW_REDIRECT_URI = 'weconnect://authenticated';
148
148
  const VW_RESPONSE_TYPE = 'code id_token token';
149
- // WeConnect App User-Agent and headers (critical for authentication)
150
- // Using exact version from WeConnect-python v0.60.9
151
- const VW_USER_AGENT = 'Volkswagen/3.51.1-android/14';
149
+ // WeConnect App headers (from ioBroker.vw-connect v0.7.15)
150
+ const VW_USER_AGENT = 'Mozilla/5.0 (Linux; Android 14; SM-G960F) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Mobile Safari/537.36';
152
151
  const VW_APP_PACKAGE = 'com.volkswagen.weconnect';
153
- const VW_ACCEPT_LANGUAGE = 'de-de';
154
- const VW_NEWRELIC_ID = 'VgAEWV9QDRAEXFlRAAYPUA==';
152
+ const VW_ACCEPT_LANGUAGE = 'en-US,en;q=0.9';
155
153
  function generateTraceId() {
156
154
  // Generate UUID v4 format
157
155
  return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
@@ -177,37 +175,39 @@ async function generateCodeChallenge(verifier) {
177
175
  }
178
176
  async function vwLogin(context, email, password) {
179
177
  try {
180
- const traceId = generateTraceId();
181
178
  const nonce = generateNonce();
182
- // API headers matching WeConnect-python v0.60.11 exactly
183
- const apiHeaders = {
179
+ const state = generateTraceId(); // Use UUID as state
180
+ const traceId = generateTraceId(); // For weconnect-trace-id header
181
+ const codeVerifier = generateCodeVerifier();
182
+ // Browser-like headers (from ioBroker.vw-connect v0.7.15)
183
+ const browserHeaders = {
184
184
  'User-Agent': VW_USER_AGENT,
185
- 'Accept': '*/*',
185
+ 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8',
186
186
  'Accept-Language': VW_ACCEPT_LANGUAGE,
187
- 'Content-Type': 'application/json',
188
- 'content-version': '1',
189
- 'Cache-Control': 'no-cache',
190
- 'Pragma': 'no-cache',
191
- 'x-newrelic-id': VW_NEWRELIC_ID,
192
- 'x-android-package-name': VW_APP_PACKAGE,
193
- 'weconnect-trace-id': traceId,
187
+ 'Accept-Encoding': 'gzip, deflate, br',
188
+ 'x-requested-with': VW_APP_PACKAGE,
189
+ 'upgrade-insecure-requests': '1',
194
190
  };
195
- // Step 1: Get authorization page via CARIAD BFF
196
- // WeConnect-python only sends redirect_uri and nonce to this endpoint
197
- const authorizeUrl = 'https://emea.bff.cariad.digital/user-login/v1/authorize';
191
+ // Step 1: Go directly to identity.vwgroup.io (like ioBroker adapter)
192
+ const authorizeUrl = 'https://identity.vwgroup.io/oidc/v1/authorize';
198
193
  const authorizeParams = new URLSearchParams({
194
+ client_id: VW_CLIENT_ID,
195
+ scope: VW_SCOPE,
196
+ response_type: VW_RESPONSE_TYPE,
199
197
  redirect_uri: VW_REDIRECT_URI,
200
198
  nonce: nonce,
199
+ state: state,
201
200
  });
202
- // Use WeConnect-python API headers for the initial CARIAD BFF request
201
+ // Use browser-like headers for initial request
202
+ // Let n8n follow redirects automatically to reach the login page
203
203
  const authorizeResponse = await context.helpers.httpRequest({
204
204
  method: 'GET',
205
205
  url: `${authorizeUrl}?${authorizeParams.toString()}`,
206
- headers: apiHeaders,
206
+ headers: browserHeaders,
207
207
  encoding: 'text',
208
208
  returnFullResponse: true,
209
209
  ignoreHttpStatusErrors: true,
210
- skipAutoFollowRedirects: true,
210
+ // Don't skip redirects - let it follow to the login page
211
211
  });
212
212
  // Extract response body and check for redirect
213
213
  let htmlContent;
@@ -243,17 +243,8 @@ async function vwLogin(context, email, password) {
243
243
  }
244
244
  // Debug: If we got an error page (status 400/500 or "Oops" in content), throw with details
245
245
  if (httpStatusCode >= 400 || htmlContent.includes('Oops!, something went wrong')) {
246
- // Include all response headers for debugging
247
- let headersInfo = 'none';
248
- if (authorizeResponse && typeof authorizeResponse === 'object') {
249
- const respObj = authorizeResponse;
250
- const respHeaders = respObj.headers;
251
- if (respHeaders) {
252
- headersInfo = Object.keys(respHeaders).join(', ');
253
- }
254
- }
255
246
  const preview = htmlContent.substring(0, 600);
256
- throw new Error(`CARIAD BFF Error (HTTP ${httpStatusCode}). Response headers: [${headersInfo}]. URL: ${authorizeUrl}?${authorizeParams.toString()}. Body preview: ${preview}`);
247
+ throw new Error(`VW Identity Error (HTTP ${httpStatusCode}). URL: ${authorizeUrl}. Body: ${preview}`);
257
248
  }
258
249
  // Follow redirects manually to capture the state parameter
259
250
  let maxInitialRedirects = 5;
@@ -272,7 +263,7 @@ async function vwLogin(context, email, password) {
272
263
  const followResponse = await context.helpers.httpRequest({
273
264
  method: 'GET',
274
265
  url: followUrl,
275
- headers: apiHeaders,
266
+ headers: browserHeaders,
276
267
  encoding: 'text',
277
268
  returnFullResponse: true,
278
269
  ignoreHttpStatusErrors: true,
@@ -555,7 +546,7 @@ async function vwLogin(context, email, password) {
555
546
  const followResponse = await context.helpers.httpRequest({
556
547
  method: 'GET',
557
548
  url: redirectUrl.startsWith('http') ? redirectUrl : `https://identity.vwgroup.io${redirectUrl}`,
558
- headers: apiHeaders,
549
+ headers: browserHeaders,
559
550
  encoding: 'text',
560
551
  returnFullResponse: true,
561
552
  ignoreHttpStatusErrors: true,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "n8n-nodes-jygse-vw-weconnect",
3
- "version": "0.1.16",
3
+ "version": "0.2.1",
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",