Skip to content

UN-2776 [FIX] Fixed GDrive connector showing always authenticated in workflow settings#1508

Merged
kirtimanmishrazipstack merged 8 commits into
mainfrom
UN-2776-gdrive-always-authenticated-inside-workflow
Sep 1, 2025
Merged

UN-2776 [FIX] Fixed GDrive connector showing always authenticated in workflow settings#1508
kirtimanmishrazipstack merged 8 commits into
mainfrom
UN-2776-gdrive-always-authenticated-inside-workflow

Conversation

@kirtimanmishrazipstack
Copy link
Copy Markdown
Contributor

@kirtimanmishrazipstack kirtimanmishrazipstack commented Aug 28, 2025

What

  • Fix GDrive connector showing always authenticated in workflow settings

Why

  • While gdrive oauth is successful, we are storing oauth-cachekey cookie to local storage
  • Although we have a centralized connector, but still we didn't segregate the oauth-cachekey based on workflow-id and connector type
  • Due to this if we have an existing gdrive connector which is authenticated, selecting a new connector would also make it authenticated accross workflows and between source and destination

How

  • Deleting cache from local-storage, and redis cache (already happeing)

Frontend change:

For new connector:

  • We should show Signin when user tries to do oauth.

For existing connector:

  • We should show reauthenticate when user tries to do oauth.

For both connectors:

  • When we receive the cache key, using it we can do test-connection and submit
  • Once submitted or modal is closed, we would remove from local storage and cache.

Backend change:

  • Handle the scenario when user tries to submit connector with same name. Backend throws server error. But we have deleted cache.
  • Although there is successful test-connection, still we need to reauthenticate again. This is a bug.
  • Handled this deleting the oauth cache key only when connector is added/updated.

Can this PR break any existing features. If yes, please list possible items. If no, please explain why. (PS: Admins do not merge the PR without this section filled)

Database Migrations

  • N/A

Env Config

  • N/A

Relevant Docs

Related Issues or PRs

Dependencies Versions

Notes on Testing

Screenshots

Checklist

I have read and understood the Contribution Guidelines.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Aug 28, 2025

Summary by CodeRabbit

  • New Features

    • OAuth button now shows “Reauthenticate” for existing connectors; otherwise “Authenticate with Google”.
    • Per-connector OAuth status handling improves accuracy across connectors.
  • Bug Fixes

    • Cleans up OAuth cache and local storage after successful create/update to prevent stale authentication states.
    • More explicit error shown when OAuth is required before continuing.
  • Chores

    • Improved event tracking and URL handling integration for OAuth flows.
  • Refactor

    • Streamlined OAuth state management and status propagation between components.

Walkthrough

Adds per-connector OAuth status and cache scoping on the frontend, passes an isExistingConnector flag to OAuth UI, and clears connector-scoped OAuth keys on unmount and after successful submit; backend now cleans cached OAuth credentials after create/update and tightens missing-OAuth error handling.

Changes

Cohort / File(s) Summary of changes
Configure DS flow
frontend/src/components/input-output/configure-ds/ConfigureDs.jsx
Derives isExistingConnector from editItemId and OAuth metadata and passes it to OAuthDs. Cleans connector-scoped localStorage keys (oauth-cachekey-${selectedSourceId}, oauth-status-${selectedSourceId}) on unmount and clears them after successful OAuth-enabled submit. Adds usePostHogEvents and useRequestUrl imports.
OAuth DS components
frontend/src/components/oauth-ds/oauth-ds/OAuthDs.jsx, frontend/src/components/oauth-ds/google/GoogleOAuthButton.jsx
OAuthDs: adds isExistingConnector prop, uses per-connector oauthStatusKey = oauth-status-${selectedSourceId} for init, storage events, and parent setStatus; integrates useExceptionHandler; passes dynamic buttonText to Google button; updates effects and PropTypes. GoogleOAuthButton: adds optional buttonText prop (default "Authenticate with Google"); displays "Authenticated" on success, otherwise uses buttonText; updates PropTypes.
Backend OAuth cache handling
backend/connector_v2/views.py
_get_connector_metadata improved error handling/log messages for missing OAuth key. Added _cleanup_oauth_cache(connector_id: str) to delete cached OAuth creds (get_oauth_creds_from_cache(..., delete_key=True)) with guarded logging. perform_create and perform_update invoke cleanup after successful operations.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant User
  participant ConfigureDs
  participant OAuthDs
  participant GoogleBtn as GoogleOAuthButton
  participant Browser as localStorage/sessionStorage
  participant Google as OAuth Provider
  participant Backend as Backend API
  participant Cache as OAuth Cache

  User->>ConfigureDs: Open connector (selectedSourceId)
  ConfigureDs->>OAuthDs: Render with isExistingConnector, selectedSourceId
  OAuthDs->>Browser: Read oauth-status-${id}
  Note over OAuthDs,Browser: Subscribes to storage events for oauth-status-${id}

  User->>GoogleBtn: Click OAuth
  GoogleBtn->>OAuthDs: handleOAuth()
  OAuthDs->>Browser: sessionStorage set oauth-current-connector = ${id}
  OAuthDs->>Google: Open OAuth authorize window

  Google-->>Backend: OAuth callback with code
  Backend->>Cache: Store creds under oauth-cachekey-${id}
  Backend-->>Browser: Update localStorage oauth-status-${id} = success
  Note over Browser,OAuthDs: storage event updates status in component and parent

  User->>ConfigureDs: Submit connector (create/update)
  ConfigureDs->>Backend: POST/PUT with oauth_key
  Backend->>Cache: Read creds (delete_key=False)
  Backend-->>ConfigureDs: 2xx response
  Backend->>Cache: Cleanup creds (delete_key=True)
  ConfigureDs->>Browser: Remove oauth-cachekey-${id}, oauth-status-${id}

  opt Unmount
    ConfigureDs->>Browser: Cleanup oauth keys for ${id}
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes


📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Cache: Disabled due to Reviews > Disable Cache setting

Knowledge Base: Disabled due to Reviews > Disable Knowledge Base setting

📥 Commits

Reviewing files that changed from the base of the PR and between e236044 and 41ac536.

📒 Files selected for processing (2)
  • frontend/src/components/oauth-ds/google/GoogleOAuthButton.jsx (2 hunks)
  • frontend/src/components/oauth-ds/oauth-ds/OAuthDs.jsx (4 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • frontend/src/components/oauth-ds/oauth-ds/OAuthDs.jsx
  • frontend/src/components/oauth-ds/google/GoogleOAuthButton.jsx
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build
✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch UN-2776-gdrive-always-authenticated-inside-workflow

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
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore or @coderabbit ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Comment thread frontend/src/components/input-output/configure-ds/ConfigureDs.jsx Outdated
@kirtimanmishrazipstack kirtimanmishrazipstack changed the title UN-2776 [FIX] Fixed Google Drive connector showing always authenticated in workflow settings UN-2776 [FIX] Fixed GDrive connector showing always authenticated in workflow settings Aug 28, 2025
Copy link
Copy Markdown
Contributor

@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

Caution

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

⚠️ Outside diff range comments (1)
frontend/src/components/oauth-ds/oauth-status/OAuthStatus.jsx (1)

14-22: Use localStorage (not sessionStorage) for cross-window context; popup cannot read parent sessionStorage

sessionStorage is scoped per-tab/window and isn’t available to the OAuth popup. As a result, OAuthStatus will often find null currentConnector and never persist the status. Switch to localStorage for the "oauth-current-connector" handshake so the popup can read and clear it. Also fix the comment to avoid confusion.

-  // Set status for the workflow-connector that initiated OAuth (stored in sessionStorage for callback)
-  const currentConnector = sessionStorage.getItem("oauth-current-connector");
+  // Set status for the workflow-connector that initiated OAuth (stored in localStorage for cross-window callback)
+  const currentConnector = localStorage.getItem("oauth-current-connector");
   if (currentConnector) {
-    // currentConnector now contains workflowId-connectorType-sourceId format
+    // currentConnector contains workflowId-connectorType-sourceId format
     const statusKey = `oauth-status-${currentConnector}`;
     localStorage.setItem(statusKey, status);
-    // Clear the session storage after use
-    sessionStorage.removeItem("oauth-current-connector");
+    // Clear the local storage after use
+    localStorage.removeItem("oauth-current-connector");
   }
🧹 Nitpick comments (2)
frontend/src/components/oauth-ds/oauth-ds/OAuthDs.jsx (2)

31-39: Filter storage events by key to avoid unnecessary reads

Listen only to oauthStatusKey changes; use the event payload instead of rereading localStorage.

-  useEffect(() => {
-    const handleStorageChange = () => {
-      // Listen for changes to our specific workflow-connector combination only
-      const updatedOAuthStatus = localStorage.getItem(oauthStatusKey);
+  useEffect(() => {
+    const handleStorageChange = (e) => {
+      // Listen only for our specific workflow-connector status key
+      if (e.key !== oauthStatusKey) return;
+      const updatedOAuthStatus = e.newValue;
       if (updatedOAuthStatus) {
         setOAuthStatus(updatedOAuthStatus);
         setStatus(updatedOAuthStatus);
       }
     };

115-122: Constrain connectorType PropType to known values

This tightens the contract and prevents silent key drift.

   selectedSourceId: PropTypes.string.isRequired,
-  workflowId: PropTypes.string.isRequired,
-  connectorType: PropTypes.string.isRequired,
+  workflowId: PropTypes.string.isRequired,
+  connectorType: PropTypes.oneOf(["source", "destination"]).isRequired,
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Cache: Disabled due to Reviews > Disable Cache setting

Knowledge Base: Disabled due to Reviews > Disable Knowledge Base setting

📥 Commits

Reviewing files that changed from the base of the PR and between 201d144 and f14fb5d.

📒 Files selected for processing (3)
  • frontend/src/components/input-output/configure-ds/ConfigureDs.jsx (4 hunks)
  • frontend/src/components/oauth-ds/oauth-ds/OAuthDs.jsx (3 hunks)
  • frontend/src/components/oauth-ds/oauth-status/OAuthStatus.jsx (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build
🔇 Additional comments (5)
frontend/src/components/oauth-ds/oauth-ds/OAuthDs.jsx (2)

22-25: Good scoping of OAuth keys to workflow + connector type + sourceId

This should resolve cross-connector contamination in a workflow.


49-54: LGTM on initial status bootstrapping

Reading the workflow/connector-scoped status on mount matches the new key strategy.

frontend/src/components/input-output/configure-ds/ConfigureDs.jsx (3)

53-57: Per-workflow/per-connector keys: good

Key structure matches OAuthDs and should prevent cross-connector contamination.


361-371: Passing workflowId and connectorType down is correct

This aligns ConfigureDs with the new OAuthDs interface.


41-41: Confirm whether projectId should be aliased to workflowId
The workflow store only exposes projectId; ensure this aligns with your intended workflow scoping or introduce a dedicated workflowId to avoid state collisions.

Comment thread frontend/src/components/oauth-ds/oauth-ds/OAuthDs.jsx
Comment thread frontend/src/components/oauth-ds/oauth-ds/OAuthDs.jsx
@kirtimanmishrazipstack kirtimanmishrazipstack marked this pull request as draft August 29, 2025 05:31
@kirtimanmishrazipstack kirtimanmishrazipstack marked this pull request as ready for review August 29, 2025 15:17
Copy link
Copy Markdown
Contributor

@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: 3

Caution

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

⚠️ Outside diff range comments (1)
frontend/src/components/input-output/configure-ds/ConfigureDs.jsx (1)

193-199: Bug: oauth-key attached only to connector_metadata.

Adapter OAuth tests will miss the key. Use the correct metadata bucket based on isConnector.

-    if (oAuthProvider?.length > 0) {
-      body["connector_metadata"] = {
-        ...body["connector_metadata"],
-        ...{ "oauth-key": cacheKey },
-      };
-    }
+    if (oAuthProvider?.length > 0) {
+      const metaKey = isConnector ? "connector_metadata" : "adapter_metadata";
+      body[metaKey] = {
+        ...body[metaKey],
+        "oauth-key": cacheKey,
+      };
+    }
♻️ Duplicate comments (1)
frontend/src/components/input-output/configure-ds/ConfigureDs.jsx (1)

54-58: Key scope outside workflows: verify selectedSourceId is always present.

If selectedSourceId is empty when adding from outside a workflow, localStorage keys become shared (e.g., oauth-cachekey-undefined). Provide a fallback scope.

-  const isExistingConnector = Boolean(editItemId || hasOAuthCredentials);
+  const isExistingConnector = Boolean(editItemId || hasOAuthCredentials);
+  // Ensure per-connector key scoping even when selectedSourceId is absent
+  const keyScope =
+    selectedSourceId ||
+    `${(type || 'unknown').toLowerCase()}-${oAuthProvider || 'oauth'}`;
+  const oauthCacheKey = `oauth-cachekey-${keyScope}`;
+  const oauthStatusKey = `oauth-status-${keyScope}`;

Run to check call sites pass a non-empty selectedSourceId in non-workflow flows:

#!/bin/bash
# Inspect ConfigureDs usages and props passed for selectedSourceId
rg -nP -C2 '<ConfigureDs\b' --type=js --type=jsx --type=ts --type=tsx
🧹 Nitpick comments (5)
frontend/src/components/oauth-ds/google/GoogleOAuthButton.jsx (3)

8-8: Fix label typo: "Sign in" (with space) for consistency.

Default should read "Sign in" per UX copy elsewhere and PR description.

-const GoogleOAuthButton = ({ handleOAuth, status, buttonText = "Signin" }) => {
+const GoogleOAuthButton = ({ handleOAuth, status, buttonText = "Sign in" }) => {

10-16: Remove derived state; compute label inline.

Avoiding useState/useEffect here simplifies and prevents stale text.

-  const [text, setText] = useState("");
-  useEffect(() => {
-    if (status === "success") {
-      setText("Authenticated");
-      return;
-    }
-    setText(buttonText);
-  }, [status, buttonText]);
+  const text = status === "success" ? "Authenticated" : buttonText;

Additionally, if desired, disable the button when authenticated:

-      <GoogleLoginButton onClick={handleOAuth}>
+      <GoogleLoginButton onClick={handleOAuth} disabled={status === "success"}>

30-30: Optional: tighten PropTypes for status.

If statuses are finite, consider oneOf([...]) to catch regressions.

-GoogleOAuthButton.propTypes = {
-  handleOAuth: PropTypes.func.isRequired,
-  status: PropTypes.string,
-  buttonText: PropTypes.string,
-};
+GoogleOAuthButton.propTypes = {
+  handleOAuth: PropTypes.func.isRequired,
+  status: PropTypes.string, // e.g., one of: '', 'success', 'error', 'pending'
+  buttonText: PropTypes.string,
+};
frontend/src/components/input-output/configure-ds/ConfigureDs.jsx (1)

352-358: Avoid mutating session adapters array.

Mutating store-derived arrays can cause subtle state bugs; create a new array.

-    const adaptersList = sessionDetails?.adapters;
-    if (adaptersList && !adaptersList.includes(adapterType)) {
-      adaptersList.push(adapterType);
-      const adaptersListInSession = { adapters: adaptersList };
-      updateSessionDetails(adaptersListInSession);
-    }
+    const current = Array.isArray(sessionDetails?.adapters)
+      ? sessionDetails.adapters
+      : [];
+    if (!current.includes(adapterType)) {
+      updateSessionDetails({ adapters: [...current, adapterType] });
+    }
backend/connector_v2/views.py (1)

89-89: Reduce log duplication.

“Fetching oauth data …” (Line 83) and “Using OAuth cache key …” communicate similar info. Keep one (ideally the latter) or lower the first to debug.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Cache: Disabled due to Reviews > Disable Cache setting

Knowledge Base: Disabled due to Reviews > Disable Knowledge Base setting

📥 Commits

Reviewing files that changed from the base of the PR and between f14fb5d and 712bc5b.

📒 Files selected for processing (4)
  • backend/connector_v2/views.py (3 hunks)
  • frontend/src/components/input-output/configure-ds/ConfigureDs.jsx (5 hunks)
  • frontend/src/components/oauth-ds/google/GoogleOAuthButton.jsx (2 hunks)
  • frontend/src/components/oauth-ds/oauth-ds/OAuthDs.jsx (4 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • frontend/src/components/oauth-ds/oauth-ds/OAuthDs.jsx
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build
🔇 Additional comments (6)
frontend/src/components/input-output/configure-ds/ConfigureDs.jsx (3)

7-9: LGTM: imports added for analytics and URL util.


336-339: LGTM: clearing OAuth keys after successful submit.

Matches the PR objective; prevents leakage across connectors.


369-370: Confirm downstream usage of isExistingConnector for button label.

Ensure OAuthDs maps isExistingConnector → buttonText ("Reauthenticate" vs "Sign in") and propagates it to GoogleOAuthButton.

backend/connector_v2/views.py (3)

136-138: LGTM: cleanup runs only after a successful update.

Assuming _cleanup_oauth_cache is hardened as above, this won’t impact the happy path even if the cache is already cleared.


155-157: LGTM: cleanup runs only after a successful create.

Matches the front-end flow; ensures single-use cache keys.


85-89: Use provider-agnostic error text in MissingParamException

Apply this diff in backend/connector_v2/views.py (lines 85–89):

-            if not oauth_key:
-                raise MissingParamException(
-                    "OAuth authentication required. Please sign in with Google first."
-                )
+            if not oauth_key:
+                raise MissingParamException(
+                    "OAuth authentication required. Please complete OAuth sign-in first."
+                )

Confirm that clients aren’t relying on a separate param field in the error payload; if they do, continue using the param= kwarg (e.g. MissingParamException(param="oauth_key")) or adjust the exception’s signature accordingly.

Comment thread backend/connector_v2/views.py Outdated
Comment thread backend/connector_v2/views.py
Comment thread frontend/src/components/input-output/configure-ds/ConfigureDs.jsx
Comment thread backend/connector_v2/views.py
Comment thread frontend/src/components/oauth-ds/google/GoogleOAuthButton.jsx Outdated
Copy link
Copy Markdown
Contributor

@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

Caution

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

⚠️ Outside diff range comments (1)
frontend/src/components/oauth-ds/oauth-ds/OAuthDs.jsx (1)

74-81: Guard missing cache_key before proceeding

If the API doesn’t return a valid cache_key, the flow will open a broken URL and set bad state.

-const cacheKey = response?.data?.cache_key;
-const encodedCacheKey = encodeURIComponent(cacheKey);
-setCacheKey(cacheKey);
+const cacheKey = response?.data?.cache_key;
+if (!cacheKey || typeof cacheKey !== "string") {
+  throw new Error("OAuth cache key missing from response");
+}
+const encodedCacheKey = encodeURIComponent(cacheKey);
+setCacheKey(cacheKey);
 
 // Persist cache key to localStorage
 localStorage.setItem(oauthCacheKey, cacheKey);
♻️ Duplicate comments (3)
backend/connector_v2/views.py (2)

85-89: Make error message provider-agnostic.

Remove "Google" to keep copy generic and future-proof.

-            if not oauth_key:
-                raise MissingParamException(
-                    "OAuth authentication required. Please sign in with Google first."
-                )
+            if not oauth_key:
+                raise MissingParamException(
+                    "OAuth authentication required. Please sign in first."
+                )

89-95: Handle cache miss explicitly; avoid relying on None-check only.

Wrap the cache fetch to surface a friendly, consistent error and keep a defensive None guard.

-            logger.info(f"Using OAuth cache key for {connector_id}")
-            connector_metadata = ConnectorAuthHelper.get_oauth_creds_from_cache(
-                cache_key=oauth_key,
-                delete_key=False,  # Don't delete yet - wait for successful operation
-            )
-            if connector_metadata is None:
-                raise MissingParamException(param=ConnectorAuthKey.OAUTH_KEY)
+            logger.info(f"Using OAuth cache key for {connector_id}")
+            try:
+                connector_metadata = ConnectorAuthHelper.get_oauth_creds_from_cache(
+                    cache_key=oauth_key,
+                    delete_key=False,  # Don't delete yet - wait for successful operation
+                )
+            except CacheMissException:
+                raise CacheMissException("OAuth session expired. Please sign in again.")
+            if connector_metadata is None:  # Defensive in case the helper returns None
+                raise CacheMissException("OAuth session expired. Please sign in again.")
frontend/src/components/oauth-ds/oauth-ds/OAuthDs.jsx (1)

66-68: Use localStorage for cross-window OAuth context (popup cannot read sessionStorage)

The OAuth popup cannot access sessionStorage of the opener tab; use localStorage so the popup can read/clear the context.

-// Store connector context in sessionStorage for OAuth callback (survives window.open)
-sessionStorage.setItem("oauth-current-connector", selectedSourceId);
+// Store connector context in localStorage so the popup can read it
+localStorage.setItem("oauth-current-connector", selectedSourceId);

Optional: include provider (and workflow/type if available) for stronger disambiguation:

-localStorage.setItem("oauth-current-connector", selectedSourceId);
+localStorage.setItem("oauth-current-connector", `${oAuthProvider}-${selectedSourceId}`);
🧹 Nitpick comments (5)
frontend/src/components/oauth-ds/oauth-ds/OAuthDs.jsx (5)

21-24: Key names: confirm uniqueness; consider scoping by provider

Right now keys are scoped by selectedSourceId only. If IDs aren’t globally unique across workflows/types, collisions can still occur. Consider including oAuthProvider (and, if available, workflow/connector type) in the key.

Example change:

-const oauthCacheKey = `oauth-cachekey-${selectedSourceId}`;
-const oauthStatusKey = `oauth-status-${selectedSourceId}`;
+const oauthCacheKey = `oauth-cachekey-${oAuthProvider}-${selectedSourceId}`;
+const oauthStatusKey = `oauth-status-${oAuthProvider}-${selectedSourceId}`;

25-26: Copy: align with PR wording

PR says: new connector should show “Sign in”. Suggest:

-const buttonText = isExistingConnector ? "Reauthenticate" : "Authenticate with Google";
+const buttonText = isExistingConnector ? "Reauthenticate" : "Sign in with Google";

51-56: Initialize status unconditionally to reflect cleared state

Ensure cleared/absent status resets the UI.

-const connectorStatus = localStorage.getItem(oauthStatusKey);
-if (connectorStatus) {
-  setStatus(connectorStatus);
-  setOAuthStatus(connectorStatus);
-}
+const connectorStatus = localStorage.getItem(oauthStatusKey);
+setStatus(connectorStatus);
+setOAuthStatus(connectorStatus);

86-91: Optional: add noopener for the popup

Mitigates reverse tabnabbing. Use if the popup doesn’t rely on window.opener.

-window.open(
+window.open(
   url,
   "_blank",
-  "toolbar=yes,scrollbars=yes,resizable=yes,top=200,left=500,width=500,height=600"
+  "toolbar=yes,scrollbars=yes,resizable=yes,top=200,left=500,width=500,height=600,noopener"
 );

112-118: Tighten PropTypes (required where used)

oAuthProvider, setCacheKey, and setStatus appear mandatory for correct behavior.

-OAuthDs.propTypes = {
-  oAuthProvider: PropTypes.string,
-  setCacheKey: PropTypes.func,
-  setStatus: PropTypes.func,
-  selectedSourceId: PropTypes.string.isRequired,
-  isExistingConnector: PropTypes.bool,
-};
+OAuthDs.propTypes = {
+  oAuthProvider: PropTypes.string.isRequired,
+  setCacheKey: PropTypes.func.isRequired,
+  setStatus: PropTypes.func.isRequired,
+  selectedSourceId: PropTypes.string.isRequired,
+  isExistingConnector: PropTypes.bool,
+};
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Cache: Disabled due to Reviews > Disable Cache setting

Knowledge Base: Disabled due to Reviews > Disable Knowledge Base setting

📥 Commits

Reviewing files that changed from the base of the PR and between 712bc5b and e236044.

📒 Files selected for processing (3)
  • backend/connector_v2/views.py (3 hunks)
  • frontend/src/components/oauth-ds/google/GoogleOAuthButton.jsx (2 hunks)
  • frontend/src/components/oauth-ds/oauth-ds/OAuthDs.jsx (4 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • frontend/src/components/oauth-ds/google/GoogleOAuthButton.jsx
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build
🔇 Additional comments (5)
backend/connector_v2/views.py (3)

100-120: Good: resilient, idempotent OAuth cache cleanup.

Catches cache-miss and swallows failures after logging; aligns with post-success cleanup semantics.


142-144: Good: cleanup after update.

Ensures the cache key is cleared only after successful update.


161-163: Good: cleanup after create.

Clears the cache post-success to prevent phantom “authenticated” states.

frontend/src/components/oauth-ds/oauth-ds/OAuthDs.jsx (2)

7-7: Good: centralized exception handling

Importing and using useExceptionHandler for OAuth errors is a solid improvement.


100-104: GoogleOAuthButton wiring looks correct

Passing status and buttonText is consistent and clear.

Comment thread frontend/src/components/oauth-ds/oauth-ds/OAuthDs.jsx
Comment thread frontend/src/components/oauth-ds/oauth-ds/OAuthDs.jsx
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Sep 1, 2025

filepath function $$\textcolor{#23d18b}{\tt{passed}}$$ SUBTOTAL
$$\textcolor{#23d18b}{\tt{runner/src/unstract/runner/clients/test\_docker.py}}$$ $$\textcolor{#23d18b}{\tt{test\_logs}}$$ $$\textcolor{#23d18b}{\tt{1}}$$ $$\textcolor{#23d18b}{\tt{1}}$$
$$\textcolor{#23d18b}{\tt{runner/src/unstract/runner/clients/test\_docker.py}}$$ $$\textcolor{#23d18b}{\tt{test\_cleanup}}$$ $$\textcolor{#23d18b}{\tt{1}}$$ $$\textcolor{#23d18b}{\tt{1}}$$
$$\textcolor{#23d18b}{\tt{runner/src/unstract/runner/clients/test\_docker.py}}$$ $$\textcolor{#23d18b}{\tt{test\_cleanup\_skip}}$$ $$\textcolor{#23d18b}{\tt{1}}$$ $$\textcolor{#23d18b}{\tt{1}}$$
$$\textcolor{#23d18b}{\tt{runner/src/unstract/runner/clients/test\_docker.py}}$$ $$\textcolor{#23d18b}{\tt{test\_client\_init}}$$ $$\textcolor{#23d18b}{\tt{1}}$$ $$\textcolor{#23d18b}{\tt{1}}$$
$$\textcolor{#23d18b}{\tt{runner/src/unstract/runner/clients/test\_docker.py}}$$ $$\textcolor{#23d18b}{\tt{test\_get\_image\_exists}}$$ $$\textcolor{#23d18b}{\tt{1}}$$ $$\textcolor{#23d18b}{\tt{1}}$$
$$\textcolor{#23d18b}{\tt{runner/src/unstract/runner/clients/test\_docker.py}}$$ $$\textcolor{#23d18b}{\tt{test\_get\_image}}$$ $$\textcolor{#23d18b}{\tt{1}}$$ $$\textcolor{#23d18b}{\tt{1}}$$
$$\textcolor{#23d18b}{\tt{runner/src/unstract/runner/clients/test\_docker.py}}$$ $$\textcolor{#23d18b}{\tt{test\_get\_container\_run\_config}}$$ $$\textcolor{#23d18b}{\tt{1}}$$ $$\textcolor{#23d18b}{\tt{1}}$$
$$\textcolor{#23d18b}{\tt{runner/src/unstract/runner/clients/test\_docker.py}}$$ $$\textcolor{#23d18b}{\tt{test\_get\_container\_run\_config\_without\_mount}}$$ $$\textcolor{#23d18b}{\tt{1}}$$ $$\textcolor{#23d18b}{\tt{1}}$$
$$\textcolor{#23d18b}{\tt{runner/src/unstract/runner/clients/test\_docker.py}}$$ $$\textcolor{#23d18b}{\tt{test\_run\_container}}$$ $$\textcolor{#23d18b}{\tt{1}}$$ $$\textcolor{#23d18b}{\tt{1}}$$
$$\textcolor{#23d18b}{\tt{runner/src/unstract/runner/clients/test\_docker.py}}$$ $$\textcolor{#23d18b}{\tt{test\_get\_image\_for\_sidecar}}$$ $$\textcolor{#23d18b}{\tt{1}}$$ $$\textcolor{#23d18b}{\tt{1}}$$
$$\textcolor{#23d18b}{\tt{runner/src/unstract/runner/clients/test\_docker.py}}$$ $$\textcolor{#23d18b}{\tt{test\_sidecar\_container}}$$ $$\textcolor{#23d18b}{\tt{1}}$$ $$\textcolor{#23d18b}{\tt{1}}$$
$$\textcolor{#23d18b}{\tt{TOTAL}}$$ $$\textcolor{#23d18b}{\tt{11}}$$ $$\textcolor{#23d18b}{\tt{11}}$$

@sonarqubecloud
Copy link
Copy Markdown

sonarqubecloud Bot commented Sep 1, 2025

@kirtimanmishrazipstack kirtimanmishrazipstack merged commit d34f6b8 into main Sep 1, 2025
7 checks passed
@kirtimanmishrazipstack kirtimanmishrazipstack deleted the UN-2776-gdrive-always-authenticated-inside-workflow branch September 1, 2025 09:41
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.

3 participants