Skip to content

fix(oauth2): idempotent OAuth2 completion and resilient listener#40292

Open
betodealmeida wants to merge 1 commit into
masterfrom
fix-oauth-followup
Open

fix(oauth2): idempotent OAuth2 completion and resilient listener#40292
betodealmeida wants to merge 1 commit into
masterfrom
fix-oauth-followup

Conversation

@betodealmeida
Copy link
Copy Markdown
Member

SUMMARY

The OAuth2 callback page always emitted both BroadcastChannel and localStorage signals when BroadcastChannel was supported, so a single completion re-triggered reRunQuery / triggerQuery / onRefresh twice in the original tab. This PR makes the sender's storage path a true fallback (only when BroadcastChannel is unavailable or its construction throws), and guard the receiver against duplicate dispatches as a safety net.

Additionally, it wraps channel/storage operations in try/catch so restricted contexts can't abort the flow, and stabilize the listener's effect by reading volatile selector values (chartList, query, etc.) from a ref so chartList changes don't churn the channel and open a race window.

BEFORE/AFTER SCREENSHOTS OR ANIMATED GIF

TESTING INSTRUCTIONS

ADDITIONAL INFORMATION

  • Has associated issue:
  • Required feature flags:
  • Changes UI
  • Includes DB Migration (follow approval process in SIP-59)
    • Migration is atomic, supports rollback & is backwards-compatible
    • Confirm DB migration upgrade and downgrade tested
    • Runtime estimates and downtime expectations provided
  • Introduces new feature or API
  • Removes existing feature or API

@betodealmeida betodealmeida changed the title fix(oauth2): make OAuth2 completion idempotent and listener resilient fix(oauth2): idempotent OAuth2 completion and resilient listener May 20, 2026
@betodealmeida betodealmeida marked this pull request as ready for review May 20, 2026 13:18
@dosubot dosubot Bot added authentication:sso Single Sign On change:frontend Requires changing the frontend labels May 20, 2026
@codecov
Copy link
Copy Markdown

codecov Bot commented May 20, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 64.14%. Comparing base (6e8b3bf) to head (3331146).
⚠️ Report is 11 commits behind head on master.

Additional details and impacted files
@@           Coverage Diff           @@
##           master   #40292   +/-   ##
=======================================
  Coverage   64.13%   64.14%           
=======================================
  Files        2591     2591           
  Lines      138367   138373    +6     
  Branches    32094    32092    -2     
=======================================
+ Hits        88746    88754    +8     
+ Misses      48091    48089    -2     
  Partials     1530     1530           
Flag Coverage Δ
hive 39.41% <ø> (ø)
javascript 67.04% <100.00%> (+<0.01%) ⬆️
mysql 59.08% <ø> (ø)
postgres 59.16% <ø> (ø)
presto 41.10% <ø> (ø)
python 60.59% <ø> (ø)
sqlite 58.80% <ø> (ø)
unit 100.00% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@richardfogaca richardfogaca self-requested a review May 20, 2026 13:50
@richardfogaca richardfogaca self-assigned this May 20, 2026
// fall through to the localStorage fallback below
}
}
if (!broadcasted) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Richard's agent here: the receiver-side handled guard and the BroadcastChannel construction try/catch both make sense to me.

One thing I’d double-check: could we still write the localStorage signal even when BroadcastChannel.postMessage() succeeds? A successful postMessage() only tells us the callback page sent the message; it does not guarantee the original tab had its listener attached at that exact moment. The storage event gives us a second delivery path for that race.

Since the receiver now dedupes with handled, sending both signals should not reintroduce duplicate reruns. I think we can keep the try/catch around both mechanisms, but avoid making storage conditional on broadcasted, e.g.:

try {
  const channel = new BroadcastChannel('oauth');
  channel.postMessage(message);
  channel.close();
} catch (e) {}

try {
  localStorage.setItem('oauth2_auth_complete', JSON.stringify(message));
  localStorage.removeItem('oauth2_auth_complete');
} catch (e) {}

@bito-code-review
Copy link
Copy Markdown
Contributor

This question isn’t related to the pull request. I can only help with questions about the PR’s code or comments.

@sadpandajoe sadpandajoe added the review:checkpoint Last PR reviewed during the daily review standup label May 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

authentication:sso Single Sign On change:frontend Requires changing the frontend preset-io review:checkpoint Last PR reviewed during the daily review standup size/L

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants