Skip to content

Fix/mobile oauth redirect#60

Merged
Summiedev merged 14 commits into
devfrom
fix/mobile-oauth-redirect
May 21, 2026
Merged

Fix/mobile oauth redirect#60
Summiedev merged 14 commits into
devfrom
fix/mobile-oauth-redirect

Conversation

@ALADETAN-IFE
Copy link
Copy Markdown
Collaborator

@ALADETAN-IFE ALADETAN-IFE commented May 20, 2026

Description

This PR fixes the Google OAuth mobile authentication flow for the Clinsight mobile app.

The backend previously handled authentication using a web-only OAuth flow and ignored the provided mobile redirect_uri / return_url. As a result, after Google authentication, the callback returned backend JSON responses instead of redirecting back to the mobile app deep link.

This update adds support for mobile OAuth redirects by properly handling the mobile return URL and redirecting authenticated users back to the app using the configured deep link scheme.

Related Issue (Link to issue ticket)

Motivation and Context

The mobile app could not complete openAuthSessionAsync because the backend callback endpoint returned JSON instead of redirecting to the mobile deep link with authentication tokens.

This change ensures the OAuth flow works correctly for mobile authentication by redirecting users back to:

clinsight://auth/google?access_token=...

after successful authentication.

How Has This Been Tested?- Ran linting and formatting checks using:

uv run ruff check . --fix

Screenshots (if appropriate - Postman, etc):

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)

Checklist:

  • My code follows the code style of this project.
  • My change requires a change to the documentation.
  • I have updated the documentation accordingly.
  • I have read the CONTRIBUTING document.
  • I have added tests to cover my changes.
  • All new and existing tests passed.

Summary by CodeRabbit

  • New Features

    • Google OAuth now accepts an optional return/redirect URL to allow custom post-login navigation.
    • OAuth callback handling respects an allowed return URL when provided, falling back to the default otherwise.
  • Bug Fixes / Security

    • Return URLs are validated and normalized to prevent unsafe or malformed redirects.
  • Tests

    • Added tests covering return-url validation and redirect URL merging with existing query parameters.

Review Change Stack

Lftobs and others added 9 commits May 15, 2026 16:30
Enhance pre-commit checks and add contact_messages to schema
Implement email update functionality with verification process
Refine deployment triggers and health checks for staging and production
Fix health check URL for staging deployment
Add Brevo API transport with Gmail SMTP fallback for email
Fix environment variable handling and set defaults for Brevo API
Implement guest session management, audit logging, and WebSocket chat
Copilot AI review requested due to automatic review settings May 20, 2026 22:24
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 20, 2026

Warning

Rate limit exceeded

@ALADETAN-IFE has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 50 minutes and 42 seconds before requesting another review.

You’ve run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: f15ccc0a-5b1f-4ae9-a598-3ec5bef45521

📥 Commits

Reviewing files that changed from the base of the PR and between 5b88a66 and b9dd2aa.

📒 Files selected for processing (2)
  • app/api/v1/endpoints/auth.py
  • app/services/oauth_state.py
📝 Walkthrough

Walkthrough

This PR extends the OAuth login flow to support optional custom redirect URLs. Clients supply a return_url query parameter to /auth/google, which is encoded in the signed OAuth state JWT, then decoded and used as the redirect target after authentication completes.

Changes

OAuth State Custom Redirect URL Support

Layer / File(s) Summary
OAuth State contract, imports & helpers
app/services/oauth_state.py
Adds urllib.parse import; extends OAuthStatePayload with optional return_url; adds private helpers to validate and normalize allowed return_url targets; updates create_oauth_state signature.
OAuth State encoding and decoding
app/services/oauth_state.py
create_oauth_state embeds a validated/normalized return_url into the JWT payload when present; decode_oauth_state returns return_url=None for blank input and extracts/caps return_url from decoded payload.
Google OAuth endpoints integration
app/api/v1/endpoints/auth.py
google_login accepts return_url query parameter and forwards it to create_oauth_state; google_callback selects oauth_ctx.return_url (if present) or the configured default, then constructs the final redirect URL with build_redirect_url and the issued access_token.
Tests and fixtures
tests/conftest.py, tests/test_oauth_state.py
Test DB URL updated in tests/conftest.py. tests/test_oauth_state.py adds tests verifying allowed return_url is preserved/normalized and that build_redirect_url merges existing query params and appends access_token; test imports expanded to access oauth state helpers.

Sequence Diagram

sequenceDiagram
  participant Client
  participant google_login
  participant create_oauth_state
  participant JWTToken as OAuth State (JWT)
  participant GoogleOAuth as Google OAuth
  participant google_callback
  participant decode_oauth_state
  participant FrontendURL as Redirect Target

  Client->>google_login: GET /auth/google?return_url=mobile://deep-link
  google_login->>create_oauth_state: create_oauth_state(return_url)
  create_oauth_state->>JWTToken: encode return_url in JWT
  JWTToken-->>google_login: state param
  google_login-->>GoogleOAuth: redirect to Google with state
  GoogleOAuth->>google_callback: callback with state & authorization_code
  google_callback->>decode_oauth_state: decode_oauth_state(state)
  decode_oauth_state-->>google_callback: OAuthStatePayload(return_url)
  alt return_url present
    google_callback->>FrontendURL: redirect to return_url?access_token=...
  else return_url absent
    google_callback->>FrontendURL: redirect to default URL?access_token=...
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 40.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Fix/mobile oauth redirect' directly addresses the main change: enabling mobile OAuth redirects by supporting the return_url parameter in OAuth state handling and modifying callback logic to respect mobile deep links.
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
  • Commit unit tests in branch fix/mobile-oauth-redirect

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 and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 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 `@app/api/v1/endpoints/auth.py`:
- Around line 419-420: The redirect assembly currently concatenates a query
string using base_redirect and urlencode (seen in base_redirect,
oauth_ctx.return_url, settings.FRONTEND_AUTH_CALLBACK_URL, app_access_token, and
redirect_url), which breaks if base_redirect already contains query params;
instead parse base_redirect with a URL parser (e.g., urllib.parse.urlparse /
parse_qs / urlencode), merge or update its query parameters to include
access_token, rebuild the URL with urlunparse, and assign that to redirect_url
so existing params are preserved and the access_token is appended safely.

In `@app/services/oauth_state.py`:
- Around line 53-54: The current code unconditionally stores client-supplied
return_url into payload["return_url"], enabling open-redirect/token
exfiltration; change this to validate the sanitized return_url against a trusted
whitelist before storing. Parse return_url (e.g., urllib.parse.urlparse), ensure
scheme is http/https, and verify host/netloc (or full origin) is in a configured
TRUSTED_REDIRECTS/ALLOWED_CALLBACKS set or matches allowed patterns; only then
assign payload["return_url"] = validated_return_url[:500], otherwise omit it or
set a safe default. Apply this check where return_url is handled (the variable
named return_url and payload map in oauth_state.py).
🪄 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: ASSERTIVE

Plan: Pro

Run ID: e3652cae-e2f9-4914-9def-de4f163edb83

📥 Commits

Reviewing files that changed from the base of the PR and between e2ce5a3 and 3213615.

📒 Files selected for processing (2)
  • app/api/v1/endpoints/auth.py
  • app/services/oauth_state.py

Comment thread app/api/v1/endpoints/auth.py Outdated
Comment thread app/services/oauth_state.py Outdated
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 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 `@tests/conftest.py`:
- Line 4: Replace the developer-specific hardcoded DATABASE_URL in
tests/conftest.py (the os.environ.setdefault("DATABASE_URL", ... ) call) with a
non-personal, generic test default or remove the default to require CI/dev
injection; for example use an in-memory SQLite URL or a clearly generic Postgres
placeholder (e.g. "postgresql+asyncpg://user:pass@localhost:5432/testdb") so
tests don't rely on personal credentials and CI must supply the real
DATABASE_URL.
🪄 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: ASSERTIVE

Plan: Pro

Run ID: 1acf6b46-8a70-4dd3-993d-09c3c0696e1c

📥 Commits

Reviewing files that changed from the base of the PR and between 3213615 and 5b88a66.

📒 Files selected for processing (4)
  • app/api/v1/endpoints/auth.py
  • app/services/oauth_state.py
  • tests/conftest.py
  • tests/test_oauth_state.py

Comment thread tests/conftest.py Outdated
@Summiedev Summiedev self-requested a review May 21, 2026 08:24
@Summiedev Summiedev merged commit 95ca230 into dev May 21, 2026
8 checks passed
@Summiedev Summiedev deleted the fix/mobile-oauth-redirect branch May 21, 2026 08:44
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.

5 participants