FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

Fix social signup popup callback handling by DonOmalVindula · Pull Request #488 · asgardeo/javascript · GitHub

Fix social signup popup callback handling - #488

Merged
DonOmalVindula merged 3 commits into
asgardeo:mainfrom
DonOmalVindula:fix/social-signup-popup-callback
May 5, 2026
Merged

Fix social signup popup callback handling#488
DonOmalVindula merged 3 commits into
asgardeo:mainfrom
DonOmalVindula:fix/social-signup-popup-callback

Conversation

DonOmalVindula commented May 5, 2026
edited by coderabbitai Bot
Loading

Copy link
Copy Markdown
Contributor

Summary

  • When social signup (Google/GitHub) opens a popup for federated authentication, the Callback component now detects the popup context (window.opener) and sends OAuth parameters back to the parent window via postMessage instead of attempting sessionStorage-based routing (which fails in popup context)
  • Prevents a race condition in BaseSignUp where both the postMessage handler and the popup URL monitor could process the same callback, causing duplicate requests with an invalid challenge token
  • Applies the same popup detection fix to the Vue Callback component

Context

The embedded SignUp component uses a popup window for social auth flows. After the user authenticates with Google/GitHub, the IDP redirects the popup to /callback?code=...&state=.... Previously, the Callback component would throw "Missing OAuth state parameter" or "Invalid OAuth state" because initiateOAuthRedirect (which stores state in sessionStorage) is never called for popup-based flows.

Test plan

  • Test Google social signup via popup flow
  • Test GitHub social signup via popup flow
  • Verify full-page redirect flows (SignIn) still work unchanged
  • Verify Vue Callback handles popup context correctly

Fixes thunder-id/thunderid#2368

Summary by CodeRabbit

Release Notes

  • Bug Fixes
    • Improved OAuth callback handling for popup-based authentication flows
    • Fixed duplicate callback processing during popup authentication
    • Enhanced communication between popup windows and parent application during OAuth sign-up and sign-in flows

When social signup (Google/GitHub) opens a popup for authentication,
the Callback component failed because it couldn't find OAuth state in
sessionStorage (state was never stored for popup-based flows).

This adds popup detection to the Callback component: when running inside
a popup (window.opener exists), it sends OAuth parameters back to the
parent window via postMessage instead of attempting sessionStorage-based
routing. The parent's messageHandler receives the code and continues
the flow.

Also prevents a race condition where both the postMessage handler and
the popup URL monitor could process the same callback, causing duplicate
requests with an invalid challenge token.

Fixes thunder-id/thunderid#2368

coderabbitai Bot commented May 5, 2026
edited
Loading

Copy link
Copy Markdown

Warning

Rate limit exceeded

@DonOmalVindula has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 59 seconds before requesting another review.

To keep reviews running without waiting, you can enable usage-based add-on for your organization. This allows additional reviews beyond the hourly cap. Account admins can enable it under billing.

⌛ 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: 010e24f4-1813-47ab-82e7-6c90bcd1c71c

📥 Commits

Reviewing files that changed from the base of the PR and between 2e3e9c4 and 92396a1.

📒 Files selected for processing (3)
  • .changeset/fix-social-signup-popup-callback.md
  • packages/react/src/components/auth/Callback/Callback.tsx
  • packages/vue/src/components/auth/Callback.ts
📝 Walkthrough

Walkthrough

This PR adds popup-aware OAuth callback handling to React and Vue components. When an OAuth callback occurs in a popup window, parameters are now forwarded to the parent window via postMessage instead of being processed locally, with state-flag management to prevent reprocessing.

Changes

Popup-Based OAuth Callback Flow

Layer / File(s) Summary
Callback Popup Detection
packages/react/src/components/auth/Callback/Callback.tsx, packages/vue/src/components/auth/Callback.ts
Callback components detect popup context via window.opener and extract OAuth parameters (code, state, nonce, error, errorDescription).
Message Passing to Parent
packages/react/src/components/auth/Callback/Callback.tsx, packages/vue/src/components/auth/Callback.ts
When a popup is detected, OAuth parameters are forwarded to the opener window via postMessage with origin scope, then processing exits early to bypass local state validation and redirect logic.
Callback Reprocessing Prevention
packages/react/src/components/presentation/auth/SignUp/v2/BaseSignUp.tsx
Parent signup component sets hasProcessedCallback = true immediately after extracting callback data from the popup message, preventing the polling interval from re-triggering callback logic.

Sequence Diagram

sequenceDiagram
    participant User
    participant SignUp as SignUp Component
    participant Popup as OAuth Popup
    participant OAuthProvider as OAuth Provider
    participant CallbackComp as Callback Component

    User->>SignUp: Click social login button
    SignUp->>Popup: window.open(callbackUrl)
    User->>OAuthProvider: Authenticate
    OAuthProvider->>CallbackComp: Redirect with code + state
    Note over CallbackComp: window.opener exists
    CallbackComp->>SignUp: postMessage({code, state, ...})
    Note over SignUp: Receive message in handler<br/>Set hasProcessedCallback = true<br/>Process OAuth params
    SignUp->>SignUp: onSubmit / onComplete
    SignUp->>User: Complete signup flow
Loading

Estimated Code Review Effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Poem

🐰 A popup sends its secrets home,
No more lost in OAuth foam!
Messages pass, flags are set,
Signup flows work perfectly yet. 🎉

🚥 Pre-merge checks | ✅ 5 ✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Fix social signup popup callback handling' clearly and concisely summarizes the main change: fixing the OAuth callback handling specifically for popup-based social signup flows.
Description check ✅ Passed The PR description includes a clear summary of changes, context explaining the popup vs sessionStorage issue, and a test plan checklist. It covers the purpose and related issue #2368.
Linked Issues check ✅ Passed The PR addresses the core objective from #2368 by implementing popup detection and postMessage-based parameter passing to ensure social signup flows complete correctly in popup contexts, preventing the redirect loop to gate/signin.
Out of Scope Changes check ✅ Passed All changes are directly scoped to fixing popup callback handling: React Callback detects popup context and posts OAuth parameters, BaseSignUp prevents race conditions, and Vue Callback receives the same fix. No unrelated changes detected.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

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

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

Tip

💬 Introducing Slack Agent: The best way for teams to turn conversations into code.

Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get started


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.

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.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/react/src/components/presentation/auth/SignUp/v2/BaseSignUp.tsx (1)

561-596: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Race condition remains: messageHandler lacks a hasProcessedCallback guard before calling onSubmit.

The new hasProcessedCallback = true assignment (line 564) prevents the popupMonitor from duplicating the request when the message event fires first. However, the reverse race is unguarded:

  1. popupMonitor fires while the popup is already at the callback URL (same-origin, so popup.location.href is readable) but before the postMessage has been processed.
  2. Interval sets hasProcessedCallback = true and enters await onSubmit(payload), yielding to the event loop.
  3. The queued message event fires next; messageHandler sees code && state, skips no check, and issues a second onSubmit call with an already-consumed challengeToken.

The window where this race can occur is bounded by the time between the popup navigating to the callback URL and the parent processing the postMessage — roughly the component mount latency (~50–200 ms) — against the 1-second interval tick, giving an estimated hit rate of ~5–20% of flows.

🛡️ Proposed fix — add the reciprocal guard to messageHandler
      const {code, state} = event.data;

      if (code && state) {
+       if (hasProcessedCallback) {
+         return;
+       }
        hasProcessedCallback = true;

        const payload: EmbeddedFlowExecuteRequestPayload = {
🤖 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 `@packages/react/src/components/presentation/auth/SignUp/v2/BaseSignUp.tsx`
around lines 561 - 596, messageHandler currently processes the postMessage
callback without checking hasProcessedCallback, causing a potential double-call
to onSubmit when popupMonitor has already started handling the same callback;
add a guard at the start of messageHandler to return early if
hasProcessedCallback is true (the same flag set by popupMonitor), and only set
hasProcessedCallback = true immediately before invoking onSubmit in
messageHandler (mirroring popupMonitor) so both paths coordinate and prevent
duplicate onSubmit(payload) calls (refer to messageHandler, popupMonitor,
hasProcessedCallback, and onSubmit).
🧹 Nitpick comments (1)
packages/react/src/components/presentation/auth/SignUp/v2/BaseSignUp.tsx (1)

561-596: ⚡ Quick win

OAuth error responses from the popup are silently dropped by messageHandler.

When the IDP returns an error (e.g., user denies the consent), the Callback component forwards { code: null, state: null, error: 'access_denied', errorDescription: '…' } via postMessage. The messageHandler only acts when code && state — so the error payload is ignored entirely. The fallback popupMonitor interval does detect error= in the popup URL and closes the popup (line ~630–635), but it calls only logger.error with no handleError/onError propagation, leaving the user with no feedback.

Consider extending the messageHandler to handle the error case:

✨ Suggested extension to handle error postMessages
      const {code, state} = event.data;

+     if (event.data.error) {
+       handleError(new Error(event.data.errorDescription || event.data.error));
+       onError?.(new Error(event.data.errorDescription || event.data.error));
+       popup.close();
+       cleanup();
+       return;
+     }

      if (code && state) {
🤖 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 `@packages/react/src/components/presentation/auth/SignUp/v2/BaseSignUp.tsx`
around lines 561 - 596, The message handler currently only processes messages
when both code and state are present, so error payloads are ignored; update the
block that reads const {code, state} = event.data to also detect error and
errorDescription (e.g., const {error, errorDescription} = event.data) and in
that branch call handleError(new Error(errorDescription || error)), invoke
onError?.(new Error(...)), then ensure popup.close() and cleanup() are called
(similar to the success/catch paths). Also extend the popupMonitor fallback
branch that detects error= in the popup URL to call handleError/onError (with a
constructed Error including the error query string) before logging and closing
the popup so error events are propagated consistently.
🤖 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.

Outside diff comments:
In `@packages/react/src/components/presentation/auth/SignUp/v2/BaseSignUp.tsx`:
- Around line 561-596: messageHandler currently processes the postMessage
callback without checking hasProcessedCallback, causing a potential double-call
to onSubmit when popupMonitor has already started handling the same callback;
add a guard at the start of messageHandler to return early if
hasProcessedCallback is true (the same flag set by popupMonitor), and only set
hasProcessedCallback = true immediately before invoking onSubmit in
messageHandler (mirroring popupMonitor) so both paths coordinate and prevent
duplicate onSubmit(payload) calls (refer to messageHandler, popupMonitor,
hasProcessedCallback, and onSubmit).

---

Nitpick comments:
In `@packages/react/src/components/presentation/auth/SignUp/v2/BaseSignUp.tsx`:
- Around line 561-596: The message handler currently only processes messages
when both code and state are present, so error payloads are ignored; update the
block that reads const {code, state} = event.data to also detect error and
errorDescription (e.g., const {error, errorDescription} = event.data) and in
that branch call handleError(new Error(errorDescription || error)), invoke
onError?.(new Error(...)), then ensure popup.close() and cleanup() are called
(similar to the success/catch paths). Also extend the popupMonitor fallback
branch that detects error= in the popup URL to call handleError/onError (with a
constructed Error including the error query string) before logging and closing
the popup so error events are propagated consistently.

ℹ️ Review info ⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 5813aa9c-710f-4296-bfb6-25c50e0d3f45

📥 Commits

Reviewing files that changed from the base of the PR and between faf4ab0 and 2e3e9c4.

📒 Files selected for processing (3)
  • packages/react/src/components/auth/Callback/Callback.tsx
  • packages/react/src/components/presentation/auth/SignUp/v2/BaseSignUp.tsx
  • packages/vue/src/components/auth/Callback.ts

brionmario previously approved these changes May 5, 2026

Copy link
Copy Markdown

🦋 Changeset detected

The changes in this PR will be included in the next version bump.

Not sure what this means? Click here to learn what changesets are.

DonOmalVindula merged commit 776b501 into asgardeo:main May 5, 2026
10 of 13 checks passed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
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.

Social signup doesn't work with Gate/ SDK

3 participants


Back | FazBrowse Home | New Git URL