Skip to content

Refactor: Align Vertex Social Auth with Platform & Improve URL Resilience (vertex app)#3613

Merged
Baalmart merged 9 commits into
stagingfrom
fix-login-vertex
Jun 11, 2026
Merged

Refactor: Align Vertex Social Auth with Platform & Improve URL Resilience (vertex app)#3613
Baalmart merged 9 commits into
stagingfrom
fix-login-vertex

Conversation

@Codebmk

@Codebmk Codebmk commented Jun 10, 2026

Copy link
Copy Markdown
Member

📋 Description

This PR addresses several fragility issues within the vertex social authentication and API routing layers by aligning its implementation with the proven patterns currently used in the platform repository.

Previously, vertex relied on a single environment variable (NEXT_PUBLIC_API_URL) without fallback mechanisms, causing runtime crashes or silent component failures if misconfigured during CI/CD. Additionally, the OAuth handoff was susceptible to "phantom login" loops if a user navigated back to an old callback URL.

This refactor makes the authentication flow and API routing highly resilient, fail-open, and secure.

🚀 Key Changes

1. Resilient API Routing & Multi-Fallback logic (api-routing.ts)

  • Replaced the fragile getApiBaseUrl with resolveApiOrigin and resolveVersionedApiPath.
  • Added multi-variable fallback scanning (API_BASE_URL, NEXT_PUBLIC_API_BASE_URL, NEXT_PUBLIC_API_URL, NEXT_PUBLIC_BASE_URL).
  • Implemented automatic suffix stripping (e.g., /api/v2) to prevent duplicate URL paths even if DevOps configures the environment variable differently.

2. Sign-Out Safety Flag to Prevent Phantom Logins (oauth-session.ts, authProvider.tsx, useLogout.ts)

  • Added the OAUTH_SIGNED_OUT_FLAG pattern.
  • When a user signs out, this flag is set to skip the OAuth token bootstrap on the login page, preventing redirect loops if the user hits the browser back button.
  • The flag is explicitly cleared only when the user intentionally clicks a social login button.

3. Google Account Picker Fix (social-auth-section.tsx)

  • Explicitly appended prompt=select_account to Google OAuth requests so the provider forces the account selection screen rather than silently logging into the active browser session.

4. Fail-Open Social Auth Buttons (social-auth-section.tsx)

  • Removed the silent render guard (if (!process.env.NEXT_PUBLIC_API_URL) return null;).
  • Social auth buttons will now always render. If the environment is completely misconfigured, the buttons gracefully catch the URL resolution error and display the standard error banner instead of mysteriously vanishing from the UI.

🧪 How to Test

  1. API URL Resilience: Temporarily rename your NEXT_PUBLIC_API_URL to NEXT_PUBLIC_API_BASE_URL in your .env file and verify that the application still boots and communicates with the backend successfully.
  2. Social Login Flow: Click "Sign in with Google" and verify that it prompts you to select an account.
  3. Sign-Out Safety: Log out of the application. Once on the login page, manually append an old OAuth token hash to the URL (#token=...). Refresh the page. Verify that the app does not automatically log you back in.
  4. Fail-Open UI: Remove all API URL variables from your .env file and restart the dev server. Verify that the social login buttons still render on the page, and clicking them displays a red error banner rather than crashing the app.

🔗 Related Context

  • Addressed tech debt highlighted in the "Vertex vs Platform Code Differences" architectural review by Martin.
  • Note: This PR handles frontend resilience. A separate DevOps adjustment is still required to ensure CI/CD injects the Next.js variables during the docker build phase.

Summary by CodeRabbit

  • New Features

    • Resilient API routing with multi-environment fallback and normalized versioned paths.
    • Google sign-in now forces account selection on each sign-in.
  • Bug Fixes

    • Prevents phantom OAuth bootstrapping after sign-out/back navigation via a signed-out flag.
    • Replaces silent social-auth suppression with visible bannered errors and safer sign-out synchronization.

Codebmk added 2 commits June 10, 2026 05:45
Introduce a localStorage-based OAuth signed-out flag to avoid bootstrapping backend OAuth flows after an explicit logout: set the flag on logout, clear it when initiating social sign-in or after successful token handoff, and skip backend OAuth bootstrap if the flag is present. Add Google-specific OAuth prompt (select_account). Refactor API URL utilities: add resolveApiOrigin, resolveVersionedApiPath, stripApiSuffix and related helpers to normalize origins/paths, support multiple env vars, and centralize version resolution; remove getApiBaseUrl and update vertex.config to use resolveApiOrigin. Also remove the client-side guard that hid the social auth section when NEXT_PUBLIC_API_URL was missing.
@Codebmk Codebmk self-assigned this Jun 10, 2026
@coderabbitai

coderabbitai Bot commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Review limit reached

@Codebmk, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 47 minutes and 38 seconds. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After more reviews become available, 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 include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: a19f5969-5575-4f93-9c84-99a7c9aac935

📥 Commits

Reviewing files that changed from the base of the PR and between bd67908 and 3e25dea.

📒 Files selected for processing (1)
  • src/vertex/app/changelog.md
📝 Walkthrough

Walkthrough

Adds a localStorage-backed OAuth "signed out" flag with helpers, integrates it into logout, social-auth initiation, and token handoff to avoid phantom bootstrap; enforces Google prompt=select_account; centralizes API origin/versioned-path resolution and updates config usage.

Changes

OAuth Sign-Out & API Routing Resilience

Layer / File(s) Summary
OAuth Signed-Out Flag Infrastructure
src/vertex/core/auth/oauth-session.ts
Introduces OAUTH_SIGNED_OUT_FLAG and window-guarded helpers: shouldSkipBackendOAuthBootstrap(), setBackendOAuthSignedOutFlag(), clearBackendOAuthSignedOutFlag().
AuthProvider Token Handoff Guards
src/vertex/core/auth/authProvider.tsx
Adds hasInitiatedBootstrapRef, imports token-handoff helpers, skips or clears signed-out flag during TokenHandoffHandler bootstrap based on shouldSkipBackendOAuthBootstrap().
SocialAuth UI: prompt & render guard removal
src/vertex/components/features/auth/social-auth-section.tsx
Adds prompt=select_account for Google OAuth, clears signed-out flag after selecting provider, and removes prior NEXT_PUBLIC_API_URL early-return so social auth always renders.
Logout: set signed-out flag
src/vertex/core/hooks/useLogout.ts
Calls setBackendOAuthSignedOutFlag() after persistor.purge() and before signOut during logout.
Centralized API Routing Resolution
src/vertex/lib/api-routing.ts
Adds resolveApiOrigin() and resolveVersionedApiPath(), normalization helpers, and updates buildServerApiUrl()/buildBrowserApiUrl() to use them (preserves absolute URLs).
Env/constants & config wiring
src/vertex/lib/envConstants.ts, src/vertex/vertex.config.ts
Removes getApiBaseUrl()/stripTrailingSlash from envConstants; updates vertex.config.ts to use resolveApiOrigin() for api.baseUrl and api.publicMeasurementsBaseUrl.
Changelog entry
src/vertex/app/changelog.md
Adds Version 2.0.3 release notes describing routing and social-auth fixes and lists modified files.

Sequence Diagram(s)

sequenceDiagram
  participant User as User
  participant useLogout as useLogout Hook
  participant LocalStorage as OAuth Flag Storage
  participant SocialAuth as SocialAuthSection
  participant NextAuth as NextAuth (signIn/signOut)
  participant TokenHandler as TokenHandoffHandler (AuthProvider)

  User->>useLogout: trigger logout
  useLogout->>useLogout: persistor.purge()
  useLogout->>LocalStorage: setBackendOAuthSignedOutFlag()
  useLogout->>NextAuth: signOut()

  Note over User,SocialAuth: Later: user initiates social sign-in
  User->>SocialAuth: click Google sign-in
  SocialAuth->>SocialAuth: add prompt=select_account
  SocialAuth->>LocalStorage: clearBackendOAuthSignedOutFlag()
  SocialAuth->>NextAuth: signIn()

  NextAuth->>TokenHandler: deliver OAuth token handoff
  TokenHandler->>LocalStorage: shouldSkipBackendOAuthBootstrap()
  alt flag set
    TokenHandler->>TokenHandler: skip bootstrap, unblock UI
  else flag not set
    TokenHandler->>LocalStorage: clearBackendOAuthSignedOutFlag()
    TokenHandler->>NextAuth: proceed with sign-in/update
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested labels

vertex

Suggested reviewers

  • Baalmart
  • OchiengPaul442

Poem

🔐 A flag in storage marks the end,
so logouts don't return to bend.
Google asks which account to pick—select,
routes resolve, versions interject.
v2.0.3 ships steady, small, and kind.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.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 accurately summarizes the main changes: refactoring social auth to align with platform patterns and improving URL resilience through API routing changes.
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-login-vertex

Warning

Review ran into problems

🔥 Problems

Errors were encountered while retrieving linked issues.

Errors (1)
  • JIRA integration encountered authorization issues. Please disconnect and reconnect the integration in the CodeRabbit UI.

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.

@github-actions

Copy link
Copy Markdown
Contributor

New azure docs changes available for preview here

@github-actions

Copy link
Copy Markdown
Contributor

New azure vertex changes available for preview here

@coderabbitai coderabbitai Bot left a comment

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.

Actionable comments posted: 1

🧹 Nitpick comments (2)
src/vertex/core/hooks/useLogout.ts (1)

69-69: 💤 Low value

Consider setting the signed-out flag before purging persisted state.

The current order works correctly, but the platform repo (context snippet, src/platform/.../useLogout.ts:54-123) sets setBackendOAuthSignedOutFlag() before calling persistor.purge(). Setting the flag earlier ensures the logged-out state is captured even if the purge operation throws or fails.

Suggested reordering
  queryClient.clear();
+ setBackendOAuthSignedOutFlag();
  await persistor.purge();

- setBackendOAuthSignedOutFlag();
  await signOut({ redirect: false });
🤖 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 `@src/vertex/core/hooks/useLogout.ts` at line 69, Move the call to
setBackendOAuthSignedOutFlag() to before the persisted-state purge so the
backend OAuth "signed out" marker is set even if persistor.purge() throws; in
useLogout (and surrounding logout flow) call setBackendOAuthSignedOutFlag()
prior to invoking persistor.purge() (or similar purge/clear functions) and then
proceed with the purge and subsequent cleanup steps.
src/vertex/lib/api-routing.ts (1)

63-65: ⚡ Quick win

Error message doesn't reflect all checked environment variables.

The error message mentions only NEXT_PUBLIC_API_URL and API_BASE_URL, but the function actually checks four variables (lines 55-58). Update the message to list all options or use a generic message.

💬 Suggested improvement
    throw new Error(
-      'API base URL is not defined. Set NEXT_PUBLIC_API_URL or API_BASE_URL in environment variables.'
+      'API base URL is not defined. Set one of: API_BASE_URL, NEXT_PUBLIC_API_BASE_URL, NEXT_PUBLIC_API_URL, or NEXT_PUBLIC_BASE_URL in environment variables.'
    );
🤖 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 `@src/vertex/lib/api-routing.ts` around lines 63 - 65, The thrown Error in the
API base URL lookup (in the function that constructs/returns the API base URL —
locate the throw in api-routing.ts near the code that checks environment
variables) lists only NEXT_PUBLIC_API_URL and API_BASE_URL but the code actually
checks four env vars; update the Error message to either enumerate all four
environment variable names checked (so the message matches the variables tested)
or replace it with a concise generic message like "API base URL is not defined.
Set one of the expected environment variables." Ensure you change the string
used in the throw statement (the existing throw new Error(...)) so it accurately
reflects the variables checked.
🤖 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 `@src/vertex/core/auth/authProvider.tsx`:
- Around line 626-631: The current early return when
shouldSkipBackendOAuthBootstrap() is true causes valid OAuth tokens in the URL
to be ignored; fix by first calling consumeOAuthTokenHandoffFromUrl() and
storing its result, then only check shouldSkipBackendOAuthBootstrap() as a
fallback when no token was consumed; ensure isHandlingOAuthRef.current and
shouldUnblock logic remain correct (clear the signed-out flag only when a token
was found and processed), and keep the existing behavior of skipping backend
bootstrap only if no token exists.

---

Nitpick comments:
In `@src/vertex/core/hooks/useLogout.ts`:
- Line 69: Move the call to setBackendOAuthSignedOutFlag() to before the
persisted-state purge so the backend OAuth "signed out" marker is set even if
persistor.purge() throws; in useLogout (and surrounding logout flow) call
setBackendOAuthSignedOutFlag() prior to invoking persistor.purge() (or similar
purge/clear functions) and then proceed with the purge and subsequent cleanup
steps.

In `@src/vertex/lib/api-routing.ts`:
- Around line 63-65: The thrown Error in the API base URL lookup (in the
function that constructs/returns the API base URL — locate the throw in
api-routing.ts near the code that checks environment variables) lists only
NEXT_PUBLIC_API_URL and API_BASE_URL but the code actually checks four env vars;
update the Error message to either enumerate all four environment variable names
checked (so the message matches the variables tested) or replace it with a
concise generic message like "API base URL is not defined. Set one of the
expected environment variables." Ensure you change the string used in the throw
statement (the existing throw new Error(...)) so it accurately reflects the
variables checked.
🪄 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: e5f07336-8f23-4824-8061-6e55b30402da

📥 Commits

Reviewing files that changed from the base of the PR and between 5494779 and de3f297.

📒 Files selected for processing (8)
  • src/vertex/app/changelog.md
  • src/vertex/components/features/auth/social-auth-section.tsx
  • src/vertex/core/auth/authProvider.tsx
  • src/vertex/core/auth/oauth-session.ts
  • src/vertex/core/hooks/useLogout.ts
  • src/vertex/lib/api-routing.ts
  • src/vertex/lib/envConstants.ts
  • src/vertex/vertex.config.ts

Comment thread src/vertex/core/auth/authProvider.tsx Outdated
@github-actions

Copy link
Copy Markdown
Contributor

New azure docs changes available for preview here

@github-actions

Copy link
Copy Markdown
Contributor

New azure vertex changes available for preview here

Copilot AI left a comment

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.

Pull request overview

Refactors the Vertex app’s API URL resolution and social OAuth flow to better tolerate environment-variable differences and to reduce problematic OAuth callback behavior (e.g., back-button “phantom login” scenarios).

Changes:

  • Replaced single-var API base URL logic with resolveApiOrigin() + resolveVersionedApiPath() (multi-env fallback + /api/v2 suffix stripping).
  • Added an OAuth signed-out localStorage flag and wired it into logout + auth bootstrap handling.
  • Updated social auth initiation (Google account picker prompt + remove “hide buttons if env missing” guard) and documented the release in the Vertex changelog.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
src/vertex/vertex.config.ts Switches Vertex config API base URL derivation to resolveApiOrigin().
src/vertex/lib/envConstants.ts Removes getApiBaseUrl() from Vertex env constants.
src/vertex/lib/api-routing.ts Introduces resilient origin/path resolution, versioned routing helpers, and updated server/browser URL builders.
src/vertex/core/hooks/useLogout.ts Sets the OAuth signed-out flag during logout to help prevent unwanted OAuth bootstraps.
src/vertex/core/auth/oauth-session.ts Adds signed-out flag helpers and uses buildServerApiUrl for OAuth initiation URL building.
src/vertex/core/auth/authProvider.tsx Incorporates signed-out skip logic into the OAuth token handoff handler.
src/vertex/components/features/auth/social-auth-section.tsx Adds prompt=select_account for Google and clears signed-out flag on intentional social login.
src/vertex/app/changelog.md Documents the 2.0.2 release notes for the routing/auth changes.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/vertex/core/auth/authProvider.tsx
Comment on lines +61 to +65
const normalizedOrigin = stripApiSuffix(configuredBaseUrl);
if (!normalizedOrigin) {
throw new Error(
'API base URL is not defined. Set NEXT_PUBLIC_API_URL or API_BASE_URL in environment variables.'
);
@Codebmk Codebmk closed this Jun 11, 2026
@Codebmk Codebmk reopened this Jun 11, 2026
@github-actions

Copy link
Copy Markdown
Contributor

New azure website changes available for preview here

@github-actions

Copy link
Copy Markdown
Contributor

New azure docs changes available for preview here

@github-actions

Copy link
Copy Markdown
Contributor

New azure analytics_platform changes available for preview here

@github-actions

Copy link
Copy Markdown
Contributor

New azure vertex changes available for preview here

Codebmk added 3 commits June 11, 2026 05:00
Add hasInitiatedBootstrapRef and an early-return in the useEffect to ensure the bootstrap sequence is initiated only once. This prevents the bootstrap logic from running multiple times (for example under React Strict Mode or repeated mounts) by tracking and setting a ref before starting the async bootstrap.
@github-actions

Copy link
Copy Markdown
Contributor

New azure vertex changes available for preview here

@coderabbitai coderabbitai Bot left a comment

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.

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 `@src/vertex/app/changelog.md`:
- Line 8: Update the release dates in src/vertex/app/changelog.md to accurately
reflect when each version is/will be released: check the headings or entries for
"Version 2.0.3" and "Version 2.0.2" and change the "Released:" date for Version
2.0.3 (currently "June 10, 2026") to the actual merge/release date (e.g., "June
11, 2026" or later) if this PR will land after June 10, 2026, or confirm both
entries intentionally share the same date; ensure the two version entries’ dates
are consistent with release intent before committing the change.
🪄 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: e5e0f946-da91-42e8-87b0-4663e9108a83

📥 Commits

Reviewing files that changed from the base of the PR and between de3f297 and bd67908.

📒 Files selected for processing (4)
  • src/vertex/app/changelog.md
  • src/vertex/core/auth/authProvider.tsx
  • src/vertex/core/hooks/useLogout.ts
  • src/vertex/lib/api-routing.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/vertex/lib/api-routing.ts

Comment thread src/vertex/app/changelog.md Outdated
@Baalmart
Baalmart merged commit f014b3b into staging Jun 11, 2026
27 of 28 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants