feat: Connectors Update and stability improvements#886
Conversation
Frontend: add isDisconnecting state, handleDisconnect function and UI to allow disconnecting connectors (with Reconnect + Disconnect buttons), guard Add Knowledge visibility by connectionId, and disable conflicting actions while connecting/disconnecting. Backend: verify connector authentication in connector_status (reporting client_id and is_authenticated, and only treat connections as active if authenticated) to avoid stale active flags. Add new connector_disconnect endpoint to remove user connections, cleanup subscriptions, and return deleted count. App bootstrap: load .env early via python-dotenv and register the new DELETE /connectors/{connector_type}/disconnect route.
Propagate and auto-detect a generic base_url for OneDrive and SharePoint connectors across backend and frontend. Backend: added base_url to connector_status responses, introduced BaseConnector._detect_base_url, implemented detection in OneDrive and SharePoint connectors (derive site/domain from /me/drive webUrl) and preserve backward-compatible sharepoint_url; AuthService now attempts to auto-detect and persist base_url after authentication. Frontend: surface baseUrl in provider page, pass it into the unified picker and OneDrive handler (use endpointHint), and show a helpful message when SharePoint requires a configured site URL. Also adjusted OAuth scopes and prompt behavior for OneDrive/SharePoint to use Files.Read/Files.Read.Selected and use select_account instead of forcing consent, plus minor logging improvements.
There was a problem hiding this comment.
Pull request overview
This PR adds comprehensive connector disconnect functionality and authentication verification to both the frontend and backend, along with auto-detection of base URLs for SharePoint and OneDrive connectors. The changes enable users to disconnect cloud storage connectors, verify authentication status before treating connections as active, and automatically detect SharePoint/OneDrive URLs during the OAuth flow.
Changes:
- Backend: Added DELETE endpoint for disconnecting connectors with subscription cleanup, enhanced connector_status to verify authentication and report base_url, and implemented auto-detection of base URLs for SharePoint/OneDrive after OAuth
- Frontend: Added disconnect UI with Reconnect/Disconnect buttons, enhanced authentication checks to require both is_active and is_authenticated flags, and improved SharePoint configuration validation
- OAuth: Changed Microsoft Graph scopes from Files.Read.All to Files.Read + Files.Read.Selected to avoid admin consent requirements and updated prompt from "consent" to "select_account" for better UX
Reviewed changes
Copilot reviewed 12 out of 12 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| src/main.py | Loads .env early via dotenv and registers new DELETE /connectors/{connector_type}/disconnect route |
| src/api/connectors.py | Enhanced connector_status to verify authentication and report base_url; added connector_disconnect endpoint to remove connections and cleanup subscriptions |
| src/services/auth_service.py | Added auto-detection of base URLs for SharePoint/OneDrive connectors after authentication |
| src/connectors/base.py | Added _detect_base_url base method for connectors to override |
| src/connectors/sharepoint/connector.py | Implemented base_url property, auto-detection in handle_oauth_callback, and _detect_sharepoint_url method |
| src/connectors/sharepoint/oauth.py | Changed scopes to Files.Read/Files.Read.Selected and prompt to select_account |
| src/connectors/onedrive/connector.py | Added base_url property and _detect_onedrive_url method |
| src/connectors/onedrive/oauth.py | Changed scopes to Files.Read/Files.Read.Selected and prompt to select_account |
| frontend/app/settings/page.tsx | Added disconnect state, handleDisconnect function, and Reconnect/Disconnect buttons with proper loading states |
| frontend/app/upload/[provider]/page.tsx | Enhanced authentication check to require both is_active and is_authenticated |
| frontend/components/cloud-picker/unified-cloud-picker.tsx | Removed auto-detection for SharePoint (backend now handles it) and added validation message for missing SharePoint base_url |
| frontend/components/cloud-picker/provider-handlers.ts | Enhanced endpointHint to use base_url for SharePoint picker |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| logger = logging.getLogger(__name__) | ||
| from session_manager import SessionManager |
There was a problem hiding this comment.
The logger is being initialized before importing the modules that may use it. The import statements should come before the logger initialization. Move the logger initialization to after all imports to follow Python conventions.
| logger.error(f"OAuth callback failed: {e}") | ||
| raise | ||
|
|
There was a problem hiding this comment.
The OneDrive connector's handle_oauth_callback method should auto-detect the base URL after successful authentication, similar to the SharePoint connector which does this in lines 174-177 of sharepoint/connector.py. Currently, the method only returns success status without populating the base_url. Add base URL auto-detection logic after line 164 to ensure consistency and enable proper file picker functionality.
| const activeConnection = connections.find( | ||
| (conn: Connection) => conn.is_active, | ||
| (conn: Connection & { is_authenticated?: boolean }) => | ||
| conn.is_active && conn.is_authenticated, | ||
| ); |
There was a problem hiding this comment.
The inline type extension (Connection & { is_authenticated?: boolean }) is used here for type safety. While this works, consider adding is_authenticated as an optional property to the Connection interface at the top of the file for better type consistency across the codebase, since this field is now part of the API response from the backend.
Replace OAuth prompt value from `consent` to `select_account` in the settings page and auth context. This allows users to choose an account during the OAuth flow instead of forcing re-consent on every authentication. Files changed: frontend/app/settings/page.tsx and frontend/contexts/auth-context.tsx.
Fixes Missing Base url for sharepoint. Add extensive debug/info/warning/error logs across OneDrive and SharePoint connectors and OAuth handlers to improve diagnostics during auth and URL detection. Log connector initialization, token acquisition attempts/results, Graph API calls/responses, and exception tracebacks. In connectors API, log detection of base_url vs sharepoint_url and when neither exists. In AuthService, attempt auto-detection of connector base_url after auth, persist it to connection config and connector instance, and clear the cached connector so a fresh instance is created with the updated config. Also add safer handling when OAuth is not initialized in URL detection. These changes are mostly observational (logging) and include minor behavioral fixes to avoid errors when oauth is missing and to ensure updated base_url is picked up by new connector instances.
Add SharePoint v8 and OneDrive v8 frontend handlers and diagnostic logging, switch provider selection to use v8 picker for SharePoint and retain v7 for personal OneDrive. Pass full file objects (including downloadUrl) from the frontend to the backend and normalize selected_files to accept both legacy ID arrays and new file-info objects. Backend: connector token endpoint accepts a resource parameter to request SharePoint-scoped tokens when needed; sync paths accept optional file_infos and Langflow/OneDrive connectors cache file metadata. OneDrive connector now handles sharing ID formats (tries /shares encodings and /drives endpoints), can download via shares endpoint as a fallback, and uses cached download URLs when provided. Also expand OAuth scopes to include Sites.Read.All to improve SharePoint access.
Introduce is_valid_sharepoint_url(url) using urllib.parse.urlparse to validate hostnames and ensure they end with ".sharepoint.com" (and are not just the bare suffix). Replace the previous naive substring check in connector_token with this function to prevent URL substring/sanitization attacks (e.g. evil.sharepoint.com.attacker.com). Also add the necessary urlparse import and handle parsing errors safely.
Remove the locally defined is_valid_sharepoint_url function and import the validator from connectors.sharepoint.utils instead. This centralizes SharePoint URL validation, avoids duplicated logic, and keeps validation behavior consistent across the codebase.
Replace fragile substring checks with proper URL parsing in the SharePoint v8 picker handler. Added helpers (tryParseUrl, isGraphHostname, isSharePointHostname, hostnamesMatch) and updated auth resource detection to compare hostnames (case-insensitive) and detect Microsoft Graph vs SharePoint more robustly. Also small cleanup in SharePoint connector: removed an inline example comment and keep extracting the base SharePoint URL via urlparse(scheme://netloc). These changes reduce false positives from simple substring matching and improve reliability across different URL forms.
Update unified-cloud-picker message for SharePoint when no site URL is configured. The message was made more generic and actionable (remove example URL, instruct users to update connector settings with a valid site URL for their organization) to improve clarity in frontend/components/cloud-picker/unified-cloud-picker.tsx.

Frontend: add isDisconnecting state, handleDisconnect function and UI to allow disconnecting connectors (with Reconnect + Disconnect buttons), guard Add Knowledge visibility by connectionId, and disable conflicting actions while connecting/disconnecting. Backend: verify connector authentication in connector_status (reporting client_id and is_authenticated, and only treat connections as active if authenticated) to avoid stale active flags. Add new connector_disconnect endpoint to remove user connections, cleanup subscriptions, and return deleted count. App bootstrap: load .env early via python-dotenv and register the new DELETE /connectors/{connector_type}/disconnect route.