From 0adafef3036543c6929534cd9ae76d5b933382f5 Mon Sep 17 00:00:00 2001 From: Cole Leavitt Date: Tue, 9 Sep 2025 14:26:17 -0700 Subject: [PATCH 1/2] fix: appstore - add 'FailureTypeInvalidAuthCode' constant --- pkg/appstore/constants.go | 1 + 1 file changed, 1 insertion(+) diff --git a/pkg/appstore/constants.go b/pkg/appstore/constants.go index d33eb454..c0c6e263 100644 --- a/pkg/appstore/constants.go +++ b/pkg/appstore/constants.go @@ -5,6 +5,7 @@ const ( FailureTypePasswordTokenExpired = "2034" FailureTypeLicenseNotFound = "9610" FailureTypeTemporarilyUnavailable = "2059" + FailureTypeInvalidAuthCode = "5005" CustomerMessageBadLogin = "MZFinance.BadLogin.Configurator_message" CustomerMessageAccountDisabled = "Your account is disabled." From 0905cc6f7e2f07da5e51691289002744b582f6d0 Mon Sep 17 00:00:00 2001 From: Cole Leavitt Date: Tue, 9 Sep 2025 14:28:13 -0700 Subject: [PATCH 2/2] fix: appstore - implement InvalidAuthCode and InvalidCredentials --- pkg/appstore/appstore_login.go | 9 +++++- pkg/appstore/appstore_login_test.go | 44 ++++++++++++++++++++++++++++- 2 files changed, 51 insertions(+), 2 deletions(-) diff --git a/pkg/appstore/appstore_login.go b/pkg/appstore/appstore_login.go index d9b37f0d..566430f8 100644 --- a/pkg/appstore/appstore_login.go +++ b/pkg/appstore/appstore_login.go @@ -14,6 +14,7 @@ import ( var ( ErrAuthCodeRequired = errors.New("auth code is required") + ErrInvalidAuthCode = errors.New("invalid or expired 2FA code") ) type LoginInput struct { @@ -133,6 +134,12 @@ func (t *appstore) parseLoginResponse(res *http.Result[loginResult], attempt int } } else if attempt == 1 && res.Data.FailureType == FailureTypeInvalidCredentials { retry = true + } else if res.Data.FailureType == FailureTypeInvalidAuthCode { + err = ErrInvalidAuthCode + } else if res.Data.FailureType == FailureTypeInvalidCredentials && authCode != "" { + err = ErrInvalidAuthCode + } else if res.Data.FailureType == "" && authCode != "" && res.Data.CustomerMessage == CustomerMessageBadLogin { + err = ErrInvalidAuthCode } else if res.Data.FailureType == "" && authCode == "" && res.Data.CustomerMessage == CustomerMessageBadLogin { err = ErrAuthCodeRequired } else if res.Data.FailureType == "" && res.Data.CustomerMessage == CustomerMessageAccountDisabled { @@ -141,7 +148,7 @@ func (t *appstore) parseLoginResponse(res *http.Result[loginResult], attempt int if res.Data.CustomerMessage != "" { err = NewErrorWithMetadata(errors.New(res.Data.CustomerMessage), res) } else { - err = NewErrorWithMetadata(errors.New("something went wrong"), res) + err = NewErrorWithMetadata(fmt.Errorf("something went wrong (failureType: %s)", res.Data.FailureType), res) } } else if res.StatusCode != gohttp.StatusOK || res.Data.PasswordToken == "" || res.Data.DirectoryServicesID == "" { err = NewErrorWithMetadata(errors.New("something went wrong"), res) diff --git a/pkg/appstore/appstore_login_test.go b/pkg/appstore/appstore_login_test.go index 3acf0427..81be7fb9 100644 --- a/pkg/appstore/appstore_login_test.go +++ b/pkg/appstore/appstore_login_test.go @@ -104,6 +104,26 @@ var _ = Describe("AppStore (Login)", func() { }) }) + When("store API returns 5005 failure type (invalid auth code)", func() { + BeforeEach(func() { + mockClient.EXPECT(). + Send(gomock.Any()). + Return(http.Result[loginResult]{ + Data: loginResult{ + FailureType: FailureTypeInvalidAuthCode, + }, + }, nil) + }) + + It("returns ErrInvalidAuthCode error", func() { + _, err := as.Login(LoginInput{ + Password: testPassword, + AuthCode: "123456", + }) + Expect(err).To(Equal(ErrInvalidAuthCode)) + }) + }) + When("store API returns error", func() { BeforeEach(func() { mockClient.EXPECT(). @@ -115,11 +135,12 @@ var _ = Describe("AppStore (Login)", func() { }, nil) }) - It("returns error", func() { + It("returns error with failure type", func() { _, err := as.Login(LoginInput{ Password: testPassword, }) Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(ContainSubstring("something went wrong (failureType: random-error)")) }) }) @@ -163,6 +184,27 @@ var _ = Describe("AppStore (Login)", func() { }) }) + When("store API returns invalid auth code with auth code provided", func() { + BeforeEach(func() { + mockClient.EXPECT(). + Send(gomock.Any()). + Return(http.Result[loginResult]{ + Data: loginResult{ + FailureType: "", + CustomerMessage: CustomerMessageBadLogin, + }, + }, nil) + }) + + It("returns ErrInvalidAuthCode error", func() { + _, err := as.Login(LoginInput{ + Password: testPassword, + AuthCode: "wrongcode", + }) + Expect(err).To(Equal(ErrInvalidAuthCode)) + }) + }) + When("store API redirects", func() { const ( testRedirectLocation = "https://" + PrivateAppStoreAPIDomain + PrivateAppStoreAPIPathAuthenticate + "?PRH=31&Pod=31"