fix: update auth endpoint + stale lock file cleanup#486
Conversation
Apple's authentication service moved the endpoint from buy.itunes.apple.com/WebObjects/MZFinance.woa/wa/authenticate to auth.itunes.apple.com/auth/v1/native/fast, and simultaneously moved the `authenticateAccount` key in the Bag XML from inside the `urlBag` dict to the root level. Changes: - bagResult: add root-level `authenticateAccount` plist field so the Bag() function reads it before falling back to urlBag (backward compat) - Bag(): append /fast suffix when the resolved endpoint uses the new auth.itunes.apple.com domain, matching what the Bag XML signals via `auth/v1/native: ["fast"]` - constants: add PrivateAuthDomain / PrivateAuthPathNative for the new endpoint - loginRequest: use the new auth endpoint as the hardcoded fallback (replaces the implicit empty-string which caused "something went wrong" when Bag lookup returned nothing) Without this fix every login attempt returns HTTP 200 with an empty body in ~1 ms, which the code surfaces as "something went wrong".
The juju/persistent-cookiejar library (via juju/go4/lock) creates a lock file at <cookies>.lock, writing the owner PID as JSON. If a process is killed between file creation (O_TRUNC) and the PID write, a 0-byte file remains. On the next startup the library skips PID-based stale detection (only runs when fi.Size() > 0) and falls back to os.OpenFile with O_EXCL, which fails because the file already exists. The result is "cannot load cookies: file locked for too long; giving up" on every subsequent invocation until the file is manually removed. Fix: in newCookieJar(), stat the lock path before opening the jar and remove the file if it is zero bytes. Zero-byte lock files are always stale because a live process always writes its PID immediately after creating the file.
|
pulled these changes into a local clone and tested against my Apple ID. The auth endpoint fix is clearly working now, the request actually reaches Apple's auth server instead of returning the old empty-body "something went wrong" error. I did hit a rate limit on the 2FA step though: To be clear, this 429 is coming from Apple's side (mzauth|global|all), not from anything in the patch. Before these changes the login never got far enough to even talk to the new endpoint, so reaching the point where Apple rate-limits us is actually a good sign that the new auth.itunes.apple.com/auth/v1/native/fast path is being used correctly. I'd been retrying logins a fair bit while testing, which probably tripped the limit. I'll wait it out and retry to confirm a clean end-to-end login. Thanks for putting this together. |
|
also getting the "Rate limit has been exceeded" error, even on a fresh account that hasn't been logged into for... weeks. |
With a residential proxy IP or my real residential IP, I have successfully logged in and downloaded IPA. No 429 error. With the following command you can test if your IP is being restricted or rate limited by Apple: If you get the following response and a 429 error, your IP is rate limited. Otherwise the response body will be empty (with 404 status code). |
|
thx u bro |
Problem
Apple recently changed their authentication infrastructure in a way that breaks ipatool login for all accounts:
The
authenticateAccountkey moved in Bag XML — it used to live inside theurlBagdict; it now appears at the root level of the plist. ipatool'sbagResultstruct only looked insideurlBag, soBag()always returned an empty endpoint.New auth domain — the endpoint itself changed from
buy.itunes.apple.com/WebObjects/MZFinance.woa/wa/authenticatetoauth.itunes.apple.com/auth/v1/native. The Bag XML signals that the/fastsub-path should be used viaauth/v1/native: ["fast"].Missing fallback — when
Bag()returned an empty string,loginRequestpassed it as-is to the HTTP client, which panicked. There was no hardcoded fallback for the new domain.Symptom: every login returns HTTP 200 with an empty body in ~1 ms, which surfaces as
"something went wrong".juju/persistent-cookiejarusesjuju/go4/lockto serialize cookie file access. If a process is killed between lock file creation (O_TRUNC) and PID write, a 0-byte.lockfile remains. The library only does PID-based stale detection whenfi.Size() > 0; a 0-byte file causes every subsequent startup to fail with"file locked for too long; giving up"until the file is manually deleted.Changes
pkg/appstore/appstore_bag.goAuthEndpoint stringfield at the root level ofbagResult(plist keyauthenticateAccount) so the new Bag layout is parsed correctly. TheurlBagpath is kept as a fallback for backward compatibility./fastto any endpoint URL onauth.itunes.apple.com(matching the Bag'sauth/v1/native: ["fast"]hint).pkg/appstore/appstore_login.goutil.IfEmpty(endpoint, fallback)inloginRequestso that ifBag()fails or returns empty, the newauth.itunes.apple.com/auth/v1/native/fastendpoint is used instead of an empty string.pkg/appstore/constants.goPrivateAuthDomain(auth.itunes.apple.com) andPrivateAuthPathNative(/auth/v1/native/fast) constants.cmd/common.gonewCookieJar(), stat the lock path before opening the jar and remove it if it is zero bytes. A live process always writes its PID immediately after creating the lock file, so a 0-byte lock is always stale.Testing
Verified against a live Apple ID after the infrastructure change — all accounts authenticate successfully and
purchased=true success=trueis returned for downloads.Summary by cubic
Fixes login by updating to Apple’s new auth endpoint and adding a safe fallback, and prevents startup failures by cleaning stale cookie lock files.
authenticateAccountfrom the Bag root, fall back tourlBag, append/fastforauth.itunes.apple.com, and default tohttps://auth.itunes.apple.com/auth/v1/native/fastwhen Bag is empty.<cookies>.lockfiles to avoid “file locked for too long” errors fromjuju/persistent-cookiejarandjuju/go4/lock.Written for commit 5eeda95. Summary will update on new commits.