From 52562d918608771e867685ffc6c2077f6add19c0 Mon Sep 17 00:00:00 2001 From: andig Date: Wed, 17 Jun 2026 13:10:17 +0200 Subject: [PATCH] EU Data Act: skip optional marketing consent page after login (#30956) --- vehicle/vag/vwidentity/endpoint.go | 6 +++--- vehicle/vw/eudataact/api.go | 16 +++++++++++++++- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/vehicle/vag/vwidentity/endpoint.go b/vehicle/vag/vwidentity/endpoint.go index b95e3f849..9dc390e7f 100644 --- a/vehicle/vag/vwidentity/endpoint.go +++ b/vehicle/vag/vwidentity/endpoint.go @@ -194,11 +194,11 @@ func (v *Service) loginLegacy(vars FormVars, user, password string) (url.Values, return parseAuthLocation(parsed) } -// marketingConsentCallback returns the OIDC callback url embedded in an +// MarketingConsentCallback returns the OIDC callback url embedded in an // optional VW/Audi marketing consent page. VW periodically interjects this // page (path .../consent/marketing/...) after an otherwise successful login. // It returns a nil url if u is not a marketing consent page. -func marketingConsentCallback(u *url.URL) (*url.URL, error) { +func MarketingConsentCallback(u *url.URL) (*url.URL, error) { if u == nil || !strings.Contains(u.Path, "/consent/marketing/") { return nil, nil } @@ -227,7 +227,7 @@ func (v *Service) skipMarketingConsent(resp *http.Response) (*url.URL, bool, err return nil, false, nil } - cb, err := marketingConsentCallback(resp.Request.URL) + cb, err := MarketingConsentCallback(resp.Request.URL) if err != nil { return nil, true, err } diff --git a/vehicle/vw/eudataact/api.go b/vehicle/vw/eudataact/api.go index 9bd799ff7..c363d6f0c 100644 --- a/vehicle/vw/eudataact/api.go +++ b/vehicle/vw/eudataact/api.go @@ -188,9 +188,23 @@ func (v *API) login() error { return errors.New(resp.Status) } + final := resp.Request.URL + + // VW periodically interjects an optional marketing consent page after an + // otherwise successful login. Skip it without consenting (#29760). + if cb, err := vwidentity.MarketingConsentCallback(final); err != nil { + return err + } else if cb != nil { + resp, err = v.Get(cb.String()) + if err != nil { + return err + } + resp.Body.Close() + final = resp.Request.URL + } + // a successful login lands on the portal; a remaining signin/consent url means // the user has not completed the one-time browser consent and vehicle linking - final := resp.Request.URL if strings.Contains(final.Path, "signin-service") || strings.Contains(final.Path, "/consent") || strings.Contains(final.Path, "/error") { return api.UrlError( fmt.Sprintf("login did not complete- open the portal and confirm consent: %s", final),