From 7afc68b5523e0f8ba3d0945f82ec0d445566020b Mon Sep 17 00:00:00 2001 From: BreadDEV <120186812+thebreaddev@users.noreply.github.com> Date: Thu, 11 Jun 2026 18:57:53 +0700 Subject: [PATCH] fix: update app auth --- pkg/appstore/appstore_bag.go | 15 ++++++++++++--- pkg/appstore/appstore_bag_test.go | 27 ++++++++++++++++++++++++++- pkg/appstore/appstore_login.go | 17 ++++++++++++++++- 3 files changed, 54 insertions(+), 5 deletions(-) diff --git a/pkg/appstore/appstore_bag.go b/pkg/appstore/appstore_bag.go index 29108a2f..1300d883 100644 --- a/pkg/appstore/appstore_bag.go +++ b/pkg/appstore/appstore_bag.go @@ -33,21 +33,30 @@ func (t *appstore) Bag(input BagInput) (BagOutput, error) { } return BagOutput{ - AuthEndpoint: res.Data.URLBag.AuthEndpoint, + AuthEndpoint: res.Data.AuthEndpoint(), }, nil } type bagResult struct { - URLBag urlBag `plist:"urlBag,omitempty"` + AuthenticateAccount string `plist:"authenticateAccount,omitempty"` + URLBag urlBag `plist:"urlBag,omitempty"` } type urlBag struct { AuthEndpoint string `plist:"authenticateAccount,omitempty"` } +func (r bagResult) AuthEndpoint() string { + if r.AuthenticateAccount != "" { + return r.AuthenticateAccount + } + + return r.URLBag.AuthEndpoint +} + func (*appstore) bagRequest(guid string) http.Request { return http.Request{ - URL: fmt.Sprintf("https://%s%s?guid=%s", PrivateInitDomain, PrivateInitPath, guid), + URL: fmt.Sprintf("https://%s%s?ix=6&guid=%s", PrivateInitDomain, PrivateInitPath, guid), Method: http.MethodGET, ResponseFormat: http.ResponseFormatXML, Headers: map[string]string{ diff --git a/pkg/appstore/appstore_bag_test.go b/pkg/appstore/appstore_bag_test.go index ae9f1f27..b0f5eec1 100644 --- a/pkg/appstore/appstore_bag_test.go +++ b/pkg/appstore/appstore_bag_test.go @@ -97,7 +97,7 @@ var _ = Describe("AppStore (Bag)", func() { Send(gomock.Any()). Do(func(req http.Request) { Expect(req.Method).To(Equal(http.MethodGET)) - Expect(req.URL).To(Equal("https://init.itunes.apple.com/bag.xml?guid=AABBCCDDEEFF")) + Expect(req.URL).To(Equal("https://init.itunes.apple.com/bag.xml?ix=6&guid=AABBCCDDEEFF")) Expect(req.ResponseFormat).To(Equal(http.ResponseFormatXML)) Expect(req.Headers).To(HaveKeyWithValue("Accept", "application/xml")) }). @@ -118,6 +118,31 @@ var _ = Describe("AppStore (Bag)", func() { }) }) + When("request is successful with authenticateAccount in root", func() { + const testAuthEndpoint = "https://example.com" + + BeforeEach(func() { + mockMachine.EXPECT(). + MacAddress(). + Return("aa:bb:cc:dd:ee:ff", nil) + + mockBagClient.EXPECT(). + Send(gomock.Any()). + Return(http.Result[bagResult]{ + StatusCode: gohttp.StatusOK, + Data: bagResult{ + AuthenticateAccount: testAuthEndpoint, + }, + }, nil) + }) + + It("returns output", func() { + out, err := as.Bag(BagInput{}) + Expect(err).ToNot(HaveOccurred()) + Expect(out.AuthEndpoint).To(Equal(testAuthEndpoint)) + }) + }) + When("request is successful but authenticateAccount is empty", func() { BeforeEach(func() { mockMachine.EXPECT(). diff --git a/pkg/appstore/appstore_login.go b/pkg/appstore/appstore_login.go index 419fdeaa..4697412c 100644 --- a/pkg/appstore/appstore_login.go +++ b/pkg/appstore/appstore_login.go @@ -65,7 +65,7 @@ type loginResult struct { func (t *appstore) login(email, password, authCode, guid, endpoint string) (Account, error) { redirect := "" - + fastEndpoint := strings.Replace(endpoint, "/auth/v1/native", "/auth/v1/native/fast/", 1) var ( err error res http.Result[loginResult] @@ -83,6 +83,13 @@ func (t *appstore) login(email, password, authCode, guid, endpoint string) (Acco } if retry, redirect, err = t.parseLoginResponse(&res, attempt, authCode); err != nil { + if authCode != "" && endpoint != fastEndpoint && missingLoginCredentials(res.Data) { + endpoint = fastEndpoint + redirect = "" + retry = true + err = nil + continue + } return Account{}, err } } @@ -150,6 +157,10 @@ func (t *appstore) parseLoginResponse(res *http.Result[loginResult], attempt int } else { err = NewErrorWithMetadata(errors.New("something went wrong"), res) } + } else if (res.StatusCode == gohttp.StatusOK || res.StatusCode == gohttp.StatusNoContent) && authCode == "" && missingLoginCredentials(res.Data) { + err = ErrAuthCodeRequired + } else if (res.StatusCode == gohttp.StatusOK || res.StatusCode == gohttp.StatusNoContent) && missingLoginCredentials(res.Data) { + err = NewErrorWithMetadata(errors.New("login response is missing password token and directory services id"), res) } else if res.StatusCode != gohttp.StatusOK || res.Data.PasswordToken == "" || res.Data.DirectoryServicesID == "" { err = NewErrorWithMetadata(errors.New("something went wrong"), res) } @@ -157,6 +168,10 @@ func (t *appstore) parseLoginResponse(res *http.Result[loginResult], attempt int return retry, redirect, err } +func missingLoginCredentials(data loginResult) bool { + return data.PasswordToken == "" && data.DirectoryServicesID == "" +} + func (t *appstore) loginRequest(email, password, authCode, guid, endpoint string, attempt int) http.Request { return http.Request{ Method: http.MethodPOST,