Skip to content

Conversation

@AnishSarkar22
Copy link
Contributor

@AnishSarkar22 AnishSarkar22 commented Jan 2, 2026

  • Introduced Notion & Linear OAuth connector, removed old API based one.
  • Introduced HMAC signed state parameters with timestamp validation for all oauth connectors. Introduced oauth_security security module for centralized management for oauth connectors. Previously it only had base64 encoding without state or timestamp validation.
  • Disabled write_todos tool.
  • Users can manage mid-syncing connectors.
  • Enhanced last indexed date display for connectors.
  • Fixed connector and file upload popup size for mobile view.
  • Added server side search and pagination for mentioned documents.

Description

Motivation and Context

FIX #

Screenshots

API Changes

  • This PR includes API changes

Change Type

  • Bug fix
  • New feature
  • Performance improvement
  • Refactoring
  • Documentation
  • Dependency/Build system
  • Breaking change
  • Other (specify):

Testing Performed

  • Tested locally
  • Manual/QA verification

Checklist

  • Follows project coding standards and conventions
  • Documentation updated as needed
  • Dependencies updated as needed
  • No lint/build errors or new warnings
  • All relevant tests are passing

High-level PR Summary

This PR introduces three distinct improvements: disabling the write_todos tool functionality across the backend and frontend by commenting out related code, enhancing the last indexed date display for connectors with more human-readable relative time formatting (e.g., "Just now", "Today at 2:30 PM", "3 days ago"), and fixing mobile responsiveness for the connector and document upload popups by adjusting heights, padding, and layout to improve usability on smaller screens.

⏱️ Estimated Review Time: 5-15 minutes

💡 Review Order Suggestion
Order File Path
1 surfsense_web/components/assistant-ui/connector-popup/components/connector-card.tsx
2 surfsense_web/components/assistant-ui/connector-popup/tabs/active-connectors-tab.tsx
3 surfsense_web/components/assistant-ui/connector-popup/components/connector-dialog-header.tsx
4 surfsense_web/components/assistant-ui/connector-popup.tsx
5 surfsense_web/components/sources/DocumentUploadTab.tsx
6 surfsense_web/components/assistant-ui/document-upload-popup.tsx
7 surfsense_web/app/dashboard/[search_space_id]/new-chat/[[...chat_id]]/page.tsx
8 surfsense_backend/app/tasks/chat/stream_new_chat.py

Need help? Join our Discord

Analyze latest changes

- Adjusted the height of the dialog content in the connector popup for better layout.
- Enhanced the last indexed date display with a new function for contextual formatting, providing clearer time references.
- Updated various text sizes for consistency across the connector card and dialog header components.
- Minor layout adjustments in the connector dialog header and active connectors tab for improved spacing.
…ents

- Commented out the write_todos tracking and messaging logic in the stream_new_chat.py file.
- Disabled the import and usage of WriteTodosToolUI in the new-chat page component.
- Updated related logic in the active connectors tab to remove indexing state handling for write_todos.
- These changes are part of a temporary disablement of the write_todos feature for further evaluation.
@vercel
Copy link

vercel bot commented Jan 2, 2026

@AnishSarkar22 is attempting to deploy a commit to the Rohan Verma's projects Team on Vercel.

A member of the Team first needs to authorize it.

Copy link

@recurseml recurseml bot left a comment

Choose a reason for hiding this comment

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

Review by RecurseML

🔍 Review performed on 70890bd..2b01120

✨ No bugs found, your code is sparkling clean

✅ Files analyzed, no issues (7)

surfsense_backend/app/tasks/chat/stream_new_chat.py
surfsense_web/app/dashboard/[search_space_id]/new-chat/[[...chat_id]]/page.tsx
surfsense_web/components/assistant-ui/connector-popup.tsx
surfsense_web/components/assistant-ui/connector-popup/components/connector-dialog-header.tsx
surfsense_web/components/assistant-ui/connector-popup/tabs/active-connectors-tab.tsx
surfsense_web/components/assistant-ui/document-upload-popup.tsx
surfsense_web/components/sources/DocumentUploadTab.tsx

- Introduced Notion OAuth support with new environment variables for client ID, client secret, and redirect URI.
- Implemented Notion connector routes for OAuth flow, including authorization and callback handling.
- Updated existing components to accommodate Notion integration, including validation changes and connector configuration.
- Enhanced the Notion indexer to utilize OAuth access tokens instead of integration tokens.
- Adjusted UI components to reflect the new Notion connector without requiring special configuration.
@AnishSarkar22 AnishSarkar22 changed the title Many Fixes feat: Notion & Linear oauth connector and many fixes Jan 2, 2026
- Introduced Linear OAuth support with new environment variables for client ID, client secret, and redirect URI.
- Implemented Linear connector routes for OAuth flow, including authorization and callback handling.
- Updated existing components to accommodate Linear integration, including validation changes and connector configuration.
- Enhanced the Linear indexer to utilize OAuth access tokens instead of API keys.
- Adjusted UI components to reflect the new Linear connector without requiring special configuration.
@AnishSarkar22 AnishSarkar22 changed the title feat: Notion & Linear oauth connector and many fixes feat: Notion & Linear OAuth connectors and many fixes Jan 2, 2026
…n connectors if user deny access

- Updated callback routes to handle optional error parameters for OAuth flows, improving user experience during authorization failures.
- Implemented error logging and redirection logic to provide feedback when access is denied or errors occur.
- Added validation for required parameters to ensure proper handling of authorization codes and state parameters.
- Enhanced documentation in the callback functions to clarify the purpose of each parameter.
…ctors

- Added encryption for sensitive tokens (access token, refresh token, client secret) in Google Calendar, Google Drive, Gmail, Linear, and Notion connectors to enhance security.
- Introduced OAuthStateManager for secure state parameter generation and validation, improving the integrity of OAuth flows.
- Updated callback routes to handle state validation and error management, ensuring robust handling of authorization processes.
- Enhanced indexers to support decryption of tokens for backward compatibility, maintaining functionality with existing encrypted credentials.
- Improved validation for date parameters in connector routes to ensure proper input handling.
@AnishSarkar22 AnishSarkar22 changed the title feat: Notion & Linear OAuth connectors and many fixes feat: Notion & Linear OAuth connectors, enhanced security of oauth connectors and few fixes Jan 2, 2026
@AnishSarkar22 AnishSarkar22 changed the title feat: Notion & Linear OAuth connectors, enhanced security of oauth connectors and few fixes feat: Notion & Linear OAuth connectors, enhanced security of OAuth connectors and few fixes Jan 2, 2026
@AnishSarkar22 AnishSarkar22 marked this pull request as ready for review January 2, 2026 19:03
Copy link

@recurseml recurseml bot left a comment

Choose a reason for hiding this comment

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

Review by RecurseML

🔍 Review performed on 2b01120..645e849

  Severity     Location     Issue     Delete  
High surfsense_backend/app/tasks/connector_indexers/linear_indexer.py:95 Breaking change without migration
High surfsense_backend/app/tasks/connector_indexers/notion_indexer.py:98 Breaking change without migration
High surfsense_backend/app/utils/oauth_security.py:190 Incorrect encryption detection heuristic
Medium surfsense_backend/app/tasks/connector_indexers/linear_indexer.py:112 Unhandled ValueError in encryption check
✅ Files analyzed, no issues (37)

surfsense_backend/.env.example
surfsense_backend/app/config/__init__.py
surfsense_backend/app/connectors/google_calendar_connector.py
surfsense_backend/app/connectors/google_drive/credentials.py
surfsense_backend/app/connectors/linear_connector.py
surfsense_backend/app/connectors/notion_history.py
surfsense_backend/app/routes/__init__.py
surfsense_backend/app/routes/airtable_add_connector_route.py
surfsense_backend/app/routes/google_calendar_add_connector_route.py
surfsense_backend/app/routes/google_drive_add_connector_route.py
surfsense_backend/app/routes/google_gmail_add_connector_route.py
surfsense_backend/app/routes/linear_add_connector_route.py
surfsense_backend/app/routes/notion_add_connector_route.py
surfsense_backend/app/tasks/connector_indexers/airtable_indexer.py
surfsense_backend/app/tasks/connector_indexers/google_calendar_indexer.py
surfsense_backend/app/tasks/connector_indexers/google_drive_indexer.py
surfsense_backend/app/tasks/connector_indexers/google_gmail_indexer.py
surfsense_backend/app/utils/validators.py
surfsense_web/components/assistant-ui/connector-popup/components/connector-card.tsx
surfsense_web/components/assistant-ui/connector-popup/components/connector-dialog-header.tsx
surfsense_web/components/assistant-ui/connector-popup/connect-forms/components/circleback-connect-form.tsx
surfsense_web/components/assistant-ui/connector-popup/connect-forms/components/linear-connect-form.tsx
surfsense_web/components/assistant-ui/connector-popup/connect-forms/components/notion-connect-form.tsx
surfsense_web/components/assistant-ui/connector-popup/connect-forms/index.tsx
surfsense_web/components/assistant-ui/connector-popup/connector-configs/components/linear-config.tsx
surfsense_web/components/assistant-ui/connector-popup/connector-configs/components/notion-config.tsx
surfsense_web/components/assistant-ui/connector-popup/connector-configs/index.tsx
surfsense_web/components/assistant-ui/connector-popup/connector-configs/views/connector-connect-view.tsx
surfsense_web/components/assistant-ui/connector-popup/connector-configs/views/connector-edit-view.tsx
surfsense_web/components/assistant-ui/connector-popup/connector-configs/views/indexing-configuration-view.tsx
surfsense_web/components/assistant-ui/connector-popup/constants/connector-constants.ts
surfsense_web/components/assistant-ui/connector-popup/hooks/use-connector-dialog.ts
surfsense_web/components/assistant-ui/connector-popup/tabs/active-connectors-tab.tsx
surfsense_web/components/assistant-ui/document-upload-popup.tsx
surfsense_web/components/editConnector/types.ts
surfsense_web/components/sources/DocumentUploadTab.tsx
surfsense_web/hooks/use-connector-edit-page.ts

linear_token = connector.config.get("LINEAR_API_KEY")
if not linear_token:
# Get the Linear access token from the connector config
linear_access_token = connector.config.get("access_token")
Copy link

Choose a reason for hiding this comment

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

Critical breaking change: The Linear indexer now requires 'access_token' in connector config, but existing Linear connectors created before this PR use 'LINEAR_API_KEY' instead. When the indexer runs on an existing connector, it will fail at line 96-103 with error 'Linear access token not found in connector config' because connector.config.get('access_token') returns None. This will cause all existing Linear connectors to crash during indexing until users manually reconnect them via OAuth. There is no migration path or backward compatibility handling for existing connectors.

Similar issue exists in notion_indexer.py line 98 where it expects 'access_token' but old connectors have 'NOTION_INTEGRATION_TOKEN'.

Evidence:

  1. File 5 (linear_connector.py) changed from API key authentication to OAuth Bearer token (lines 17-34)
  2. File 21 (validators.py) removed 'LINEAR_API_KEY' requirement (line 529 removed)
  3. File 25 (linear-connect-form.tsx) - entire old API key form was REMOVED
  4. File 18 (linear_indexer.py) line 95 now expects 'access_token' which won't exist in old connectors
  5. No migration logic exists to convert old connector configs to new format

React with 👍 to tell me that this comment was useful, or 👎 if not (and I'll stop posting more comments like this in the future)

# Get the Notion token from the connector config
notion_token = connector.config.get("NOTION_INTEGRATION_TOKEN")
# Get the Notion access token from the connector config (OAuth-based)
notion_token = connector.config.get("access_token")
Copy link

Choose a reason for hiding this comment

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

Critical breaking change: The Notion indexer now requires 'access_token' in connector config, but existing Notion connectors created before this PR use 'NOTION_INTEGRATION_TOKEN' instead. When the indexer runs on an existing connector, it will fail at line 99-106 with error 'Notion access token not found in connector config' because connector.config.get('access_token') returns None. This will cause all existing Notion connectors to crash during indexing until users manually reconnect them via OAuth. There is no migration path or backward compatibility handling for existing connectors.

Evidence:

  1. File 6 (notion_history.py) line 10 comment changed from 'integration token' to 'OAuth access token'
  2. File 21 (validators.py) removed 'NOTION_INTEGRATION_TOKEN' requirement (lines 517-520 removed)
  3. File 26 (notion-connect-form.tsx) - entire old integration token form was REMOVED
  4. File 19 (notion_indexer.py) line 98 now expects 'access_token' which won't exist in old connectors
  5. Frontend code still references NOTION_INTEGRATION_TOKEN (file 38, surfsense_web/hooks/use-connector-edit-page.ts lines 80, 117, 271-278) but backend no longer accepts it

React with 👍 to tell me that this comment was useful, or 👎 if not (and I'll stop posting more comments like this in the future)

token_encrypted = connector.config.get("_token_encrypted", False)
if token_encrypted or (
config.SECRET_KEY
and TokenEncryption(config.SECRET_KEY).is_encrypted(linear_access_token)
Copy link

Choose a reason for hiding this comment

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

Potential runtime error: The code creates a new TokenEncryption instance on every check to determine if a token is encrypted. If config.SECRET_KEY is None or empty, this will raise a ValueError from TokenEncryption.init (oauth_security.py line 144: 'raise ValueError("secret_key is required for token encryption")'). This check happens on line 110-113 even if token_encrypted flag is False. The issue is that the condition checks 'config.SECRET_KEY' for truthiness but then immediately uses it to create TokenEncryption, which could fail if SECRET_KEY is an empty string or other falsy value that passes the truthiness check but is invalid for encryption.

The same issue exists in notion_indexer.py line 110-113.

Evidence:

  1. Line 112 creates TokenEncryption(config.SECRET_KEY) without try-catch
  2. oauth_security.py lines 137-145 show TokenEncryption.init raises ValueError if secret_key is falsy
  3. The guard 'config.SECRET_KEY' on line 111 checks truthiness but doesn't validate if it's a valid encryption key

React with 👍 to tell me that this comment was useful, or 👎 if not (and I'll stop posting more comments like this in the future)

@MODSetter
Copy link
Owner

@AnishSarkar22 Can you verify the recurse ml pr review once.

@AnishSarkar22
Copy link
Contributor Author

@AnishSarkar22 Can you verify the recurse ml pr review once.

Yeah checking it.

- Enhanced token decryption logic in Airtable, Google Drive, Linear, and Notion indexers to only attempt decryption when tokens are explicitly marked as encrypted.
- Added error handling for missing SECRET_KEY when tokens are marked as encrypted, improving robustness and clarity in error reporting.
- Updated comments to clarify the handling of plaintext tokens when encryption is not indicated.
…ctors

- Updated documentation for the LinearConnector and NotionHistoryConnector classes to specify that the access token can also be an API key or integration token, enhancing clarity for users regarding token usage.
…ors similar to google oauth based ones

- Enhanced LinearConnector and NotionHistoryConnector classes to support automatic token refresh, improving reliability in accessing APIs.
- Updated initialization to require session and connector ID, allowing for dynamic credential management.
- Introduced new credential schemas for Linear and Notion, encapsulating access and refresh tokens with expiration handling.
- Refactored indexers to utilize the new connector structure, ensuring seamless integration with the updated authentication flow.
- Improved error handling and logging during token refresh processes for better debugging and user feedback.
@AnishSarkar22
Copy link
Contributor Author

AnishSarkar22 commented Jan 3, 2026

@MODSetter Please check it, the issues should be fixed now.

@MODSetter
Copy link
Owner

Clone of #664

@MODSetter MODSetter closed this Jan 5, 2026
Copy link

@recurseml recurseml bot left a comment

Choose a reason for hiding this comment

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

Review by RecurseML

🔍 Review performed on 645e849..76de0b5

✨ No bugs found, your code is sparkling clean

✅ Files analyzed, no issues (9)

surfsense_backend/app/routes/linear_add_connector_route.py
surfsense_backend/app/routes/notion_add_connector_route.py
surfsense_backend/app/schemas/linear_auth_credentials.py
surfsense_backend/app/schemas/notion_auth_credentials.py
surfsense_backend/app/tasks/connector_indexers/airtable_indexer.py
surfsense_backend/app/tasks/connector_indexers/google_drive_indexer.py
surfsense_backend/app/tasks/connector_indexers/linear_indexer.py
surfsense_backend/app/tasks/connector_indexers/notion_indexer.py
surfsense_web/components/new-chat/document-mention-picker.tsx

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.

2 participants