n8n-nodes-jygse-vw-weconnect 0.1.10 → 0.1.11
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.
|
@@ -147,8 +147,10 @@ const VW_SCOPE = 'openid profile badge cars dealers vin';
|
|
|
147
147
|
const VW_REDIRECT_URI = 'weconnect://authenticated';
|
|
148
148
|
const VW_RESPONSE_TYPE = 'code id_token token';
|
|
149
149
|
// WeConnect App User-Agent and headers (critical for authentication)
|
|
150
|
-
|
|
150
|
+
// Using exact version from WeConnect-python
|
|
151
|
+
const VW_USER_AGENT = 'Volkswagen/3.51.1-android/14';
|
|
151
152
|
const VW_APP_PACKAGE = 'com.volkswagen.weconnect';
|
|
153
|
+
const VW_ACCEPT_LANGUAGE = 'de-de';
|
|
152
154
|
function generateTraceId() {
|
|
153
155
|
// Generate UUID v4 format
|
|
154
156
|
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
|
|
@@ -174,32 +176,28 @@ async function generateCodeChallenge(verifier) {
|
|
|
174
176
|
}
|
|
175
177
|
async function vwLogin(context, email, password) {
|
|
176
178
|
try {
|
|
177
|
-
|
|
178
|
-
const
|
|
179
|
-
|
|
180
|
-
const
|
|
181
|
-
|
|
179
|
+
const traceId = generateTraceId();
|
|
180
|
+
const nonce = generateNonce();
|
|
181
|
+
// Common headers used for all requests (matching WeConnect-python exactly)
|
|
182
|
+
const commonHeaders = {
|
|
183
|
+
'User-Agent': VW_USER_AGENT,
|
|
184
|
+
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
|
|
185
|
+
'Accept-Language': VW_ACCEPT_LANGUAGE,
|
|
186
|
+
'Cache-Control': 'no-cache',
|
|
187
|
+
'x-android-package-name': VW_APP_PACKAGE,
|
|
188
|
+
'weconnect-trace-id': traceId,
|
|
189
|
+
};
|
|
190
|
+
// Step 1: Get authorization page via CARIAD BFF
|
|
191
|
+
// WeConnect-python only sends redirect_uri and nonce to this endpoint
|
|
182
192
|
const authorizeUrl = 'https://emea.bff.cariad.digital/user-login/v1/authorize';
|
|
183
193
|
const authorizeParams = new URLSearchParams({
|
|
184
|
-
client_id: VW_CLIENT_ID,
|
|
185
|
-
scope: VW_SCOPE,
|
|
186
|
-
response_type: VW_RESPONSE_TYPE,
|
|
187
194
|
redirect_uri: VW_REDIRECT_URI,
|
|
188
|
-
nonce:
|
|
189
|
-
state: stateParam,
|
|
190
|
-
code_challenge: codeChallenge,
|
|
191
|
-
code_challenge_method: 'plain',
|
|
195
|
+
nonce: nonce,
|
|
192
196
|
});
|
|
193
|
-
const traceId = generateTraceId();
|
|
194
197
|
const authorizeResponse = await context.helpers.httpRequest({
|
|
195
198
|
method: 'GET',
|
|
196
199
|
url: `${authorizeUrl}?${authorizeParams.toString()}`,
|
|
197
|
-
headers:
|
|
198
|
-
'User-Agent': VW_USER_AGENT,
|
|
199
|
-
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
|
|
200
|
-
'x-android-package-name': VW_APP_PACKAGE,
|
|
201
|
-
'weconnect-trace-id': traceId,
|
|
202
|
-
},
|
|
200
|
+
headers: commonHeaders,
|
|
203
201
|
encoding: 'text',
|
|
204
202
|
returnFullResponse: true,
|
|
205
203
|
ignoreHttpStatusErrors: true,
|
|
@@ -252,10 +250,7 @@ async function vwLogin(context, email, password) {
|
|
|
252
250
|
const followResponse = await context.helpers.httpRequest({
|
|
253
251
|
method: 'GET',
|
|
254
252
|
url: followUrl,
|
|
255
|
-
headers:
|
|
256
|
-
'User-Agent': VW_USER_AGENT,
|
|
257
|
-
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
|
|
258
|
-
},
|
|
253
|
+
headers: commonHeaders,
|
|
259
254
|
encoding: 'text',
|
|
260
255
|
returnFullResponse: true,
|
|
261
256
|
ignoreHttpStatusErrors: true,
|
|
@@ -458,8 +453,7 @@ async function vwLogin(context, email, password) {
|
|
|
458
453
|
method: 'POST',
|
|
459
454
|
url: `https://identity.vwgroup.io/u/login?state=${encodeURIComponent(stateToken)}`,
|
|
460
455
|
headers: {
|
|
461
|
-
|
|
462
|
-
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
|
|
456
|
+
...commonHeaders,
|
|
463
457
|
'Content-Type': 'application/x-www-form-urlencoded',
|
|
464
458
|
'Origin': 'https://identity.vwgroup.io',
|
|
465
459
|
'Referer': `https://identity.vwgroup.io/u/login?state=${encodeURIComponent(stateToken)}`,
|
|
@@ -537,9 +531,7 @@ async function vwLogin(context, email, password) {
|
|
|
537
531
|
const followResponse = await context.helpers.httpRequest({
|
|
538
532
|
method: 'GET',
|
|
539
533
|
url: redirectUrl.startsWith('http') ? redirectUrl : `https://identity.vwgroup.io${redirectUrl}`,
|
|
540
|
-
headers:
|
|
541
|
-
'User-Agent': VW_USER_AGENT,
|
|
542
|
-
},
|
|
534
|
+
headers: commonHeaders,
|
|
543
535
|
encoding: 'text',
|
|
544
536
|
returnFullResponse: true,
|
|
545
537
|
ignoreHttpStatusErrors: true,
|
|
@@ -572,10 +564,10 @@ async function vwLogin(context, email, password) {
|
|
|
572
564
|
maxRedirects--;
|
|
573
565
|
}
|
|
574
566
|
if (!authCode) {
|
|
575
|
-
throw new Error(`Could not obtain authorization code. Last redirect: ${redirectUrl || 'none'}.
|
|
567
|
+
throw new Error(`Could not obtain authorization code. Last redirect: ${redirectUrl || 'none'}. Auth HTML preview: ${authHtml.substring(0, 500)}`);
|
|
576
568
|
}
|
|
577
|
-
// Step 4: Exchange auth code for tokens
|
|
578
|
-
//
|
|
569
|
+
// Step 4: Exchange auth code for tokens via CARIAD login endpoint
|
|
570
|
+
// The state parameter should come from the authorize response, not our generated one
|
|
579
571
|
let tokenResponse;
|
|
580
572
|
try {
|
|
581
573
|
const cariadResponse = await context.helpers.httpRequest({
|
|
@@ -584,16 +576,18 @@ async function vwLogin(context, email, password) {
|
|
|
584
576
|
headers: {
|
|
585
577
|
'User-Agent': VW_USER_AGENT,
|
|
586
578
|
'Accept': 'application/json',
|
|
579
|
+
'Accept-Language': VW_ACCEPT_LANGUAGE,
|
|
587
580
|
'Content-Type': 'application/json',
|
|
581
|
+
'x-android-package-name': VW_APP_PACKAGE,
|
|
582
|
+
'weconnect-trace-id': traceId,
|
|
588
583
|
},
|
|
589
584
|
body: {
|
|
590
|
-
state:
|
|
585
|
+
state: stateToken,
|
|
591
586
|
id_token: idToken,
|
|
592
587
|
redirect_uri: VW_REDIRECT_URI,
|
|
593
588
|
region: 'emea',
|
|
594
589
|
access_token: accessToken,
|
|
595
590
|
authorizationCode: authCode,
|
|
596
|
-
code_verifier: codeVerifier,
|
|
597
591
|
},
|
|
598
592
|
});
|
|
599
593
|
tokenResponse = cariadResponse;
|
|
@@ -606,6 +600,7 @@ async function vwLogin(context, email, password) {
|
|
|
606
600
|
headers: {
|
|
607
601
|
'User-Agent': VW_USER_AGENT,
|
|
608
602
|
'Accept': 'application/json',
|
|
603
|
+
'Accept-Language': VW_ACCEPT_LANGUAGE,
|
|
609
604
|
'Content-Type': 'application/json',
|
|
610
605
|
'X-Client-Id': VW_CLIENT_ID,
|
|
611
606
|
},
|
|
@@ -613,7 +608,6 @@ async function vwLogin(context, email, password) {
|
|
|
613
608
|
auth_code: authCode,
|
|
614
609
|
id_token: idToken || '',
|
|
615
610
|
brand: 'vw',
|
|
616
|
-
code_verifier: codeVerifier,
|
|
617
611
|
},
|
|
618
612
|
});
|
|
619
613
|
}
|
package/package.json
CHANGED