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