n8n-nodes-jygse-vw-weconnect 0.1.7 → 0.1.9
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 - from
|
|
145
|
-
const VW_CLIENT_ID = '
|
|
146
|
-
const VW_SCOPE = 'openid profile
|
|
147
|
-
const VW_REDIRECT_URI = '
|
|
148
|
-
const VW_RESPONSE_TYPE = 'id_token token
|
|
144
|
+
// VW OAuth2 Configuration (Updated January 2026 - from WeConnect-python)
|
|
145
|
+
const VW_CLIENT_ID = 'a24fba63-34b3-4d43-b181-942111e6bda8@apps_vw-dilab_com';
|
|
146
|
+
const VW_SCOPE = 'openid profile badge cars dealers vin';
|
|
147
|
+
const VW_REDIRECT_URI = 'weconnect://authenticated';
|
|
148
|
+
const VW_RESPONSE_TYPE = 'code id_token token';
|
|
149
149
|
// Generate PKCE code verifier and challenge
|
|
150
150
|
function generateCodeVerifier() {
|
|
151
151
|
const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~';
|
|
@@ -167,8 +167,8 @@ async function vwLogin(context, email, password) {
|
|
|
167
167
|
const codeVerifier = generateCodeVerifier();
|
|
168
168
|
const codeChallenge = await generateCodeChallenge(codeVerifier);
|
|
169
169
|
const stateParam = generateNonce();
|
|
170
|
-
// Step 1: Get authorization page
|
|
171
|
-
const authorizeUrl = 'https://
|
|
170
|
+
// Step 1: Get authorization page via CARIAD BFF (WeConnect-python approach)
|
|
171
|
+
const authorizeUrl = 'https://emea.bff.cariad.digital/user-login/v1/authorize';
|
|
172
172
|
const authorizeParams = new URLSearchParams({
|
|
173
173
|
client_id: VW_CLIENT_ID,
|
|
174
174
|
scope: VW_SCOPE,
|
|
@@ -397,6 +397,7 @@ async function vwLogin(context, email, password) {
|
|
|
397
397
|
encoding: 'text',
|
|
398
398
|
returnFullResponse: true,
|
|
399
399
|
ignoreHttpStatusErrors: true,
|
|
400
|
+
skipAutoFollowRedirects: true,
|
|
400
401
|
});
|
|
401
402
|
if (typeof authResponse === 'string') {
|
|
402
403
|
authHtml = authResponse;
|
|
@@ -458,6 +459,7 @@ async function vwLogin(context, email, password) {
|
|
|
458
459
|
encoding: 'text',
|
|
459
460
|
returnFullResponse: true,
|
|
460
461
|
ignoreHttpStatusErrors: true,
|
|
462
|
+
skipAutoFollowRedirects: true,
|
|
461
463
|
});
|
|
462
464
|
if (typeof loginResponse === 'string') {
|
|
463
465
|
authHtml = loginResponse;
|
|
@@ -486,28 +488,36 @@ async function vwLogin(context, email, password) {
|
|
|
486
488
|
let idToken = '';
|
|
487
489
|
let accessToken = '';
|
|
488
490
|
let maxRedirects = 10;
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
if (codeMatch) {
|
|
491
|
+
// First check if we already have tokens in the current redirectUrl
|
|
492
|
+
const extractTokens = (url) => {
|
|
493
|
+
if (url.includes('code=')) {
|
|
494
|
+
const codeMatch = url.match(/code=([^&#]+)/);
|
|
495
|
+
if (codeMatch)
|
|
495
496
|
authCode = codeMatch[1];
|
|
496
|
-
}
|
|
497
497
|
}
|
|
498
|
-
if (
|
|
499
|
-
const idTokenMatch =
|
|
500
|
-
if (idTokenMatch)
|
|
498
|
+
if (url.includes('id_token=')) {
|
|
499
|
+
const idTokenMatch = url.match(/id_token=([^&#]+)/);
|
|
500
|
+
if (idTokenMatch)
|
|
501
501
|
idToken = idTokenMatch[1];
|
|
502
|
-
}
|
|
503
502
|
}
|
|
504
|
-
if (
|
|
505
|
-
const accessTokenMatch =
|
|
506
|
-
if (accessTokenMatch)
|
|
503
|
+
if (url.includes('access_token=')) {
|
|
504
|
+
const accessTokenMatch = url.match(/access_token=([^&#]+)/);
|
|
505
|
+
if (accessTokenMatch)
|
|
507
506
|
accessToken = accessTokenMatch[1];
|
|
508
|
-
}
|
|
509
507
|
}
|
|
510
|
-
|
|
508
|
+
};
|
|
509
|
+
// Check initial redirect URL for tokens
|
|
510
|
+
if (redirectUrl) {
|
|
511
|
+
extractTokens(redirectUrl);
|
|
512
|
+
}
|
|
513
|
+
while (maxRedirects > 0 && redirectUrl && !authCode) {
|
|
514
|
+
// Check if this is the final redirect to carnet:// scheme
|
|
515
|
+
if (redirectUrl.startsWith('carnet://') || redirectUrl.startsWith('weconnect://')) {
|
|
516
|
+
extractTokens(redirectUrl);
|
|
517
|
+
break;
|
|
518
|
+
}
|
|
519
|
+
// Skip non-http redirects
|
|
520
|
+
if (!redirectUrl.startsWith('http') && !redirectUrl.startsWith('/')) {
|
|
511
521
|
break;
|
|
512
522
|
}
|
|
513
523
|
const followResponse = await context.helpers.httpRequest({
|
|
@@ -519,15 +529,27 @@ async function vwLogin(context, email, password) {
|
|
|
519
529
|
encoding: 'text',
|
|
520
530
|
returnFullResponse: true,
|
|
521
531
|
ignoreHttpStatusErrors: true,
|
|
532
|
+
skipAutoFollowRedirects: true,
|
|
522
533
|
});
|
|
523
534
|
if (typeof followResponse === 'object' && followResponse !== null) {
|
|
524
535
|
const respObj = followResponse;
|
|
525
536
|
const respHeaders = respObj.headers;
|
|
526
|
-
|
|
527
|
-
|
|
537
|
+
const newLocation = respHeaders ? (respHeaders.location || respHeaders.Location) : '';
|
|
538
|
+
if (newLocation) {
|
|
539
|
+
redirectUrl = newLocation;
|
|
540
|
+
extractTokens(redirectUrl);
|
|
528
541
|
}
|
|
529
542
|
else {
|
|
530
|
-
|
|
543
|
+
// No more redirects, check response body for meta refresh or JS redirect
|
|
544
|
+
const body = respObj.body || '';
|
|
545
|
+
const metaRefreshMatch = body.match(/URL=([^"'\s>]+)/i);
|
|
546
|
+
if (metaRefreshMatch) {
|
|
547
|
+
redirectUrl = metaRefreshMatch[1];
|
|
548
|
+
extractTokens(redirectUrl);
|
|
549
|
+
}
|
|
550
|
+
else {
|
|
551
|
+
redirectUrl = '';
|
|
552
|
+
}
|
|
531
553
|
}
|
|
532
554
|
}
|
|
533
555
|
else {
|
|
@@ -536,7 +558,7 @@ async function vwLogin(context, email, password) {
|
|
|
536
558
|
maxRedirects--;
|
|
537
559
|
}
|
|
538
560
|
if (!authCode) {
|
|
539
|
-
throw new Error(
|
|
561
|
+
throw new Error(`Could not obtain authorization code. Last redirect: ${redirectUrl || 'none'}. Please check your credentials.`);
|
|
540
562
|
}
|
|
541
563
|
// Step 4: Exchange auth code for tokens
|
|
542
564
|
// Try the new CARIAD login endpoint first
|
package/package.json
CHANGED