Add /portal/sso/embed step to fix intermittent 401s#209
Conversation
The iOS app visits /portal/sso/embed after login (and MFA if applicable) before calling preauthorized. This sets the Cloudflare load balancer cookie (__cflb) that pins subsequent requests to the same backend. Without it, preauthorized can hit a different backend that doesn't have the session, causing intermittent 401 errors. Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
|
Caution Review failedThe pull request is closed. ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
WalkthroughAdds a pre-token GET to the SSO embed endpoint to establish Cloudflare LB session and copies cookies from a provided parent session; also bumps package version and prevents telemetry during test imports. Changes
Sequence Diagram(s)sequenceDiagram
participant Client as Client (garth)
participant Parent as Parent Session
participant CF as Cloudflare LB
participant SSO as SSO Embed (`sso/portal/sso/embed`)
participant OAuth as OAuth endpoints
Client->>Parent: (optional) copy cookies
Note right of Client: GarminOAuth1Session.__init__
Client->>SSO: GET sso/portal/sso/embed
SSO->>CF: set LB cookie (response)
CF->>Client: LB cookie set in response
Client->>OAuth: proceed to obtain OAuth1/OAuth2 tokens
OAuth-->>Client: tokens
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Suggested reviewers
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
📝 Coding Plan
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. Comment |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #209 +/- ##
=======================================
Coverage 99.97% 99.97%
=======================================
Files 68 68
Lines 3555 3558 +3
=======================================
+ Hits 3554 3557 +3
Misses 1 1
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
|
tried this PR and for me it still fails, not sure how usefull the session id is: Garth session: 0a7123f8f34646c2 |
The module-level Client() in http.py runs at import time and configures logfire when telemetry is enabled (the new default). Logfire's background token verification requests interfere with VCR cassette matching. Setting the env var before import prevents this. Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/garth/sso.py`:
- Around line 221-223: The Cloudflare LB cookie set by the embed request on
client.sess isn't propagated to the OAuth1 session; update
GarminOAuth1Session.__init__ to copy cookies from the parent/session that
performed client.get("sso", "/portal/sso/embed") into the OAuth1 session's
cookie jar (e.g., clone or update self.cookies from the provided parent/session
object) so subsequent OAuth1 requests use the same LB cookie for backend
pinning.
🪄 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: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: b3392c8a-1587-4c12-8fd1-742b6ab75f51
⛔ Files ignored due to path filters (6)
tests/cassettes/test_login_command.yamlis excluded by!tests/**/cassettes/**tests/cassettes/test_login_return_on_mfa.yamlis excluded by!tests/**/cassettes/**tests/cassettes/test_login_success.yamlis excluded by!tests/**/cassettes/**tests/cassettes/test_login_success_mfa.yamlis excluded by!tests/**/cassettes/**tests/cassettes/test_login_success_mfa_async.yamlis excluded by!tests/**/cassettes/**tests/cassettes/test_resume_login.yamlis excluded by!tests/**/cassettes/**
📒 Files selected for processing (2)
src/garth/sso.pysrc/garth/version.py
The /portal/sso/embed step sets the Cloudflare LB cookie on client.sess, but GarminOAuth1Session wasn't copying cookies from the parent session. The preauthorized call would hit a different backend without the session context. Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
|
@semicolon-spec try now |
Yes, still failing (Garth session: 5c5d62a9179c483f) |
|
still failing, Garth session: 397ea6f140c14c2d |
Summary
Add the missing
/portal/sso/embedstep to the SSO login flow, matching what the iOS Garmin Connect app does. This sets the Cloudflare load balancer cookie (__cflb) that pins subsequent requests to the same backend server.Without this step, the
preauthorizedcall can hit a different backend that doesn't have the SSO session, causing intermittent 401 "Client app validation failed" errors. Telemetry data confirmed that non-MFA sessions had a much higher failure rate (15/48 = 31%) compared to MFA sessions (3/340 = <1%).Thanks to @NiklasCa for reporting and providing session IDs that helped diagnose this.
Test plan
🤖 Generated with Claude Code
Summary by CodeRabbit
Bug Fixes
Tests
Chores