Skip to content

Fix login failures caused by Apple's native auth endpoint migration#505

Closed
BarMalka wants to merge 2 commits into
majd:mainfrom
BarMalka:fix/native-auth-endpoint
Closed

Fix login failures caused by Apple's native auth endpoint migration#505
BarMalka wants to merge 2 commits into
majd:mainfrom
BarMalka:fix/native-auth-endpoint

Conversation

@BarMalka

@BarMalka BarMalka commented Jun 30, 2026

Copy link
Copy Markdown

Summary

This PR proposes a fix for recent authentication failures reported in #480 and #485.

Apple appears to have migrated App Store login away from the legacy buy.itunes.apple.com/.../authenticate endpoint toward a native auth service at https://auth.itunes.apple.com/auth/v1/native/fast/. When ipatool still targets the old endpoint (or an outdated value from Bag), Apple can return HTML/JSON instead of a plist, which surfaces as misleading errors such as:

failed to unmarshal xml: plist: error parsing text property list: missing = in dictionary at line 0 character 6

This change:

  • Normalizes authenticateAccount from Bag responses (including the root-level field) to the native /fast/ endpoint, with a safe fallback when Apple omits it
  • Retries login with a discovered native endpoint when a non-plist response contains one (via a structured ResponseDecodeError)
  • Handles AMD-Action::SP with a clearer message when Apple requires browser-based sign-in (2FA or Apple ID review)
  • Removes stale zero-byte cookie-jar lock files that can block startup after an interrupted process

Test plan

  • go test ./...
  • go vet ./...
  • ipatool auth login against an account that previously failed with the plist unmarshal error — verified via live integration test and CLI with test credentials; login now reaches Apple's native auth endpoint and returns a valid plist response (auth code is required / 2FA prompt) instead of failed to unmarshal xml
  • Verify Bag returns the normalized native auth endpoint when authenticateAccount is present or missing — live Bag fetch from init.itunes.apple.com currently omits authenticateAccount; fallback normalization returns https://auth.itunes.apple.com/auth/v1/native/fast/ (see TestLiveBagReturnsNativeAuthEndpoint)
  • Verify accounts requiring browser sign-in receive the new actionable error message — covered by unit test (store API requires browser sign-in); live reproduction requires an account in Apple ID review / browser-only sign-in state

Live verification commands

go test -tags=integration -v ./pkg/appstore/ -run TestLive
./ipatool --non-interactive auth login -e test@example.com -p 'not-a-real-password'

Fixes #480
Fixes #485

Normalize authenticateAccount from Bag responses, discover alternate endpoints from malformed login responses, handle browser sign-in redirects, and remove stale zero-byte cookie-jar lock files.

Co-authored-by: Cursor <cursoragent@cursor.com>
@BarMalka

Copy link
Copy Markdown
Author

I am not a Go developer but I ran this locally it looks stable to me and the authentication issue is resolved.
Used Cursor to fix the issue.

Exercise Bag and Login against Apple's production endpoints to confirm the normalized auth URL is used and login no longer fails with plist decode errors.

Co-authored-by: Cursor <cursoragent@cursor.com>
@BarMalka

Copy link
Copy Markdown
Author

Test plan verification

Completed the remaining manual test plan items:

Bag endpoint (live)

  • Fetched https://init.itunes.apple.com/bag.xml — Apple currently does not include authenticateAccount in the response
  • Bag() correctly falls back to https://auth.itunes.apple.com/auth/v1/native/fast/
  • TestLiveBagReturnsNativeAuthEndpoint

Login endpoint (live)

  • TestLiveLoginUsesNativeAuthEndpoint ✅ — invalid credentials no longer trigger failed to unmarshal xml; Apple returns a valid plist (auth code is required)
  • CLI: ./ipatool --non-interactive auth login -e test@example.com -p 'not-a-real-password' ✅ — returns 2FA code is required instead of plist parse error
  • Interactive CLI also prompts for 2FA code (confirming a real auth response was parsed)

Browser sign-in error

  • Unit test ✅ (-ginkgo.focus "browser sign-in") — AMD-Action::SP returns account requires browser sign-in (2FA or Apple ID review required)
  • Could not live-reproduce without an account in browser-only sign-in / Apple ID review state

Added pkg/appstore/appstore_live_test.go (//go:build integration) so these checks can be re-run with:

go test -tags=integration -v ./pkg/appstore/ -run TestLive

@majd

majd commented Jul 5, 2026

Copy link
Copy Markdown
Owner

Closing in favor of a simpler fix in #507

@majd majd closed this Jul 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants