Skip to content

Fix China mainland auth endpoints and 2FA fallback#285

Open
hackermengzhi wants to merge 1 commit into
timlaing:mainfrom
hackermengzhi:fix/china-mainland-auth-2fa
Open

Fix China mainland auth endpoints and 2FA fallback#285
hackermengzhi wants to merge 1 commit into
timlaing:mainfrom
hackermengzhi:fix/china-mainland-auth-2fa

Conversation

@hackermengzhi

Copy link
Copy Markdown

Summary

This fixes two live-auth issues found while authenticating a China mainland Apple ID through the CLI:

  • Keep IDMS authentication on idmsa.apple.com for China mainland accounts while using China iCloud service endpoints (www.icloud.com.cn / setup.icloud.com.cn). Browser traffic from icloud.com.cn uses this mixed endpoint flow; sending IDMS traffic to idmsa.apple.com.cn can fail with bad username/password.
  • If requesting a fresh SMS 2FA code fails, keep the CLI in the verification prompt loop so the user can enter a code that already appeared on a trusted Apple device.

Tests

  • python3 -m pytest tests/test_base.py::test_china_mainland_uses_global_idmsa_and_cn_icloud_endpoints tests/test_cmdline.py::test_sms_2fa_request_failure_still_prompts_for_existing_device_code tests/test_cmdline.py::test_auth_login_persists_china_mainland_metadata tests/test_cmdline.py::test_persisted_china_mainland_metadata_is_used_for_service_commands
  • python3 -m ruff check pyicloud/base.py pyicloud/cli/context.py tests/test_base.py tests/test_cmdline.py

@coderabbitai

coderabbitai Bot commented Jun 24, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: a2981a23-8723-4033-8681-b1d5fcd118b5

📥 Commits

Reviewing files that changed from the base of the PR and between 259965c and a0ff084.

📒 Files selected for processing (4)
  • pyicloud/base.py
  • pyicloud/cli/context.py
  • tests/test_base.py
  • tests/test_cmdline.py
🚧 Files skipped from review as they are similar to previous changes (2)
  • pyicloud/cli/context.py
  • tests/test_cmdline.py

📝 Walkthrough

Summary by CodeRabbit

  • Bug Fixes

    • Improved sign-in handling when SMS 2FA code requests fail, so the login flow now falls back to an already-shown trusted-device code and continues.
    • Updated endpoint selection for China mainland accounts to use the correct Apple service addresses consistently.
    • Refined authentication headers to always send the expected redirect URI during login flows.
  • Tests

    • Added coverage for China mainland endpoint behaviour.
    • Updated login flow tests to reflect the improved trusted-device 2FA fallback experience.

Walkthrough

The PR updates Apple auth endpoint handling so mainland service setup uses the global IDMS host and the home endpoint redirect URI. It also adds a trusted-device code helper and changes the SMS 2FA failure path to print a message and continue prompting.

Changes

Apple auth endpoint and 2FA flow

Layer / File(s) Summary
Endpoint setup and auth headers
pyicloud/base.py, tests/test_base.py
PyiCloudService now uses the global IDMS endpoint, overrides X-Apple-OAuth-Redirect-URI from _home_endpoint, and the new test checks the mainland endpoint values without calling authentication.
Trusted-device code mode
pyicloud/base.py
PyiCloudService adds use_existing_trusted_device_code() to clear the trusted-device bridge state and mark the active 2FA delivery method as trusted_device.
SMS 2FA failure prompt
pyicloud/cli/context.py, tests/test_cmdline.py
_handle_2fa now prints an SMS request failure message and keeps prompting for a trusted-device code; the CLI test now expects success, the stdout message, and a validate_2fa_code call.

Sequence Diagram(s)

sequenceDiagram
  participant _handle_2fa
  participant api
  participant typer.prompt
  _handle_2fa->>api: request_2fa_code()
  api-->>_handle_2fa: PyiCloudAPIResponseException
  _handle_2fa->>api: use_existing_trusted_device_code()
  _handle_2fa->>typer.prompt: prompt for trusted-device code
  typer.prompt-->>_handle_2fa: code value
  _handle_2fa->>api: validate_2fa_code(code value)
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

A rabbit twitched his nose and grinned,
New auth paths hopped where clues begin.
The code said “try,” the prompt said “go,”
And trusted-device lights now softly glow. 🐰

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarises the main change: China mainland auth endpoints and 2FA fallback.
Description check ✅ Passed The description matches the changeset and explains both authentication fixes and their tests.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
tests/test_cmdline.py (1)

2655-2669: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Exercise the real 2FA validation route here.

This only proves that the prompt continues and that validate_2fa_code() is called on the fake API. It will still pass if the real service keeps routing the entered code to the SMS verifier after request_2fa_code() fails. Please assert the delivery-method state or cover the real PyiCloudService.validate_2fa_code() branch that this fallback depends on.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/test_cmdline.py` around lines 2655 - 2669, The current test only checks
the prompt path on FakeAPI and does not verify the fallback validation branch
when request_2fa_code fails. Update
test_sms_2fa_request_failure_still_prompts_for_existing_device_code to assert
the delivery-method state used by auth login, or add coverage around
PyiCloudService.validate_2fa_code so the real fallback from request_2fa_code to
validating an already-issued code is exercised. Use the auth login flow and
PyiCloudService.validate_2fa_code as the key symbols to locate the relevant
logic.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@pyicloud/cli/context.py`:
- Around line 371-375: The fallback in PyiCloudService._request_sms_2fa_code()
is still leaving the verifier state as SMS, so validate_2fa_code() routes the
next code to the wrong endpoint. Update the exception handling around
api.request_2fa_code() to record a delivery-state override or switch the
verifier before prompting in PyiCloudCLIContext, so the existing trusted-device
code path is used instead of inferring sms from auth_data.

---

Nitpick comments:
In `@tests/test_cmdline.py`:
- Around line 2655-2669: The current test only checks the prompt path on FakeAPI
and does not verify the fallback validation branch when request_2fa_code fails.
Update test_sms_2fa_request_failure_still_prompts_for_existing_device_code to
assert the delivery-method state used by auth login, or add coverage around
PyiCloudService.validate_2fa_code so the real fallback from request_2fa_code to
validating an already-issued code is exercised. Use the auth login flow and
PyiCloudService.validate_2fa_code as the key symbols to locate the relevant
logic.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 7637f0df-178c-4e6f-bbf0-1a7009e51184

📥 Commits

Reviewing files that changed from the base of the PR and between 59e43fc and 259965c.

📒 Files selected for processing (4)
  • pyicloud/base.py
  • pyicloud/cli/context.py
  • tests/test_base.py
  • tests/test_cmdline.py

Comment thread pyicloud/cli/context.py
@hackermengzhi hackermengzhi force-pushed the fix/china-mainland-auth-2fa branch from 259965c to a0ff084 Compare June 24, 2026 22:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant