Audi: rotate qmauth and add assertion headers for IDK token exchange (#30292)

This commit is contained in:
andig 2026-05-28 14:13:21 +02:00 • committed by GitHub
parent 4f943650b2
commit 8ea620d368
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -42,8 +42,9 @@ func New(log *util.Logger, q url.Values) *Service {
// https://github.com/arjenvrh/audi_connect_ha/issues/133
const (
qmSecret = "e47866378ef0658ce75d71007a809f34616b9635e2ec228245784c1f63e88d06"
qmClientId = "c95f4fd2"
qmSecret = "1ab69925ac179aaa4e83abe671a9476d176418b85bd706f1436ca15be647989c"
qmClientId = "01da27b0"
userAgent = "Android/4.31.0 (Build 800341641.root project 'myaudi_android'.ext.buildTime) Android/13"
)
func qmauth(ts int64) string {
@ -57,6 +58,21 @@ func qmauthNow() string {
return "v1:" + qmClientId + ":" + qmauth(time.Now().Unix()/100)
}
// tokenHeaders returns the assertion header set the IDK token endpoint
// validates for both authorization_code and refresh_token grants.
func tokenHeaders() map[string]string {
return map[string]string{
"Content-Type": request.FormContent,
"Accept": request.JSONContent,
"Accept-Charset": "utf-8",
"User-Agent": userAgent,
"x-qmauth": qmauthNow(),
"x-platform": "android",
"x-android-package-name": "de.myaudi.mobile.assistant",
"x-assertion": "0",
}
}
// Exchange exchanges an VAG identity token for an IDK token
func (v *Service) Exchange(q url.Values) (*vag.Token, error) {
if err := urlvalues.Require(q, "code", "code_verifier"); err != nil {
@ -74,11 +90,7 @@ func (v *Service) Exchange(q url.Values) (*vag.Token, error) {
var res vag.Token
req, err := request.New(http.MethodPost, Config.TokenURL, strings.NewReader(data.Encode()), map[string]string{
"Content-Type": request.FormContent,
"Accept": request.JSONContent,
"x-qmauth": qmauthNow(),
})
req, err := request.New(http.MethodPost, Config.TokenURL, strings.NewReader(data.Encode()), tokenHeaders())
if err == nil {
err = v.DoJSON(req, &res)
}
@ -98,11 +110,7 @@ func (v *Service) Refresh(token *vag.Token) (*vag.Token, error) {
var res vag.Token
req, err := request.New(http.MethodPost, Config.TokenURL, strings.NewReader(data.Encode()), map[string]string{
"Content-Type": request.FormContent,
"Accept": request.JSONContent,
"x-qmauth": qmauthNow(),
})
req, err := request.New(http.MethodPost, Config.TokenURL, strings.NewReader(data.Encode()), tokenHeaders())
if err == nil {
err = v.DoJSON(req, &res)
}