Conversation
- Updated the user metadata service to assess Google connection and sync status, enriching metadata with connection status and sync state. - Introduced a new driver for user metadata service tests to streamline testing of metadata updates. - Modified existing tests to validate new Google metadata assessment logic, ensuring accurate handling of connection and sync states. - Refactored user driver to support conditional user creation based on Google connection status. - Cleaned up WebSocket server logic by removing deprecated Google token status checks on connection.
Co-authored-by: Tyler Dane <tyler-dane@users.noreply.github.com>
…tIncremental Co-authored-by: Tyler Dane <tyler-dane@users.noreply.github.com>
- fix(sync): force-restart sync when Google returns 410 error instead of delegating to assessGoogleMetadata, which checks token existence not validity - fix(web): add catch-all for connected users with unhandled sync status to show correct label Co-authored-by: Tyler Dane <tyler-dane@users.noreply.github.com>
Co-authored-by: Tyler Dane <tyler-dane@users.noreply.github.com>
- Introduced new functions to wait for Google Calendar import start and end events. - Updated tests to utilize these functions for improved clarity and reliability. - Refactored import result parsing for better type safety and readability. - Adjusted test assertions to ensure correct behavior during import processes.
- Added a catch block to handle errors from the afterEvent promise, ensuring proper rejection with a standardized Error object. - Enhanced error handling in the beforeEvent callback to ensure consistent error reporting.
…Google hook - Refactored the useConnectGoogle hook to return a structured configuration for command actions and sidebar status. - Updated tests to reflect changes in the hook's return structure, ensuring accurate assertions for various connection states. - Improved the SidebarIconRow component to utilize the new configuration for displaying Google Calendar connection status. - Added a disabled state for the TooltipWrapper when the Google Calendar is connected or syncing.
- Added a `force` option to the `importGCal` method in `SyncControllerDriver` to allow forced imports. - Introduced a new `WatchDriver` for managing watch collection tests, improving test isolation and flexibility. - Updated `importGCal` method in `SyncController` to handle the `force` parameter, enabling forced sync operations. - Enhanced tests in `sync.controller.test.ts` to verify forced import behavior and ensure correct handling of completed sync states. - Improved user metadata service to return healthy status without active watches when not using HTTPS. - Updated user service tests to validate event sync token persistence without HTTPS, ensuring local sync health.
…tGoogle hook - Enhanced the useConnectGoogle hook to manage Google Calendar repair state, integrating a new repair action that triggers forced imports. - Updated the SyncApi to accept an options parameter for the importGCal method, allowing for forced sync operations. - Refactored tests for useConnectGoogle and related components to validate the new repair logic and ensure accurate assertions for various connection states. - Improved user interface feedback during repair processes, including updated tooltips and sidebar statuses. - Ensured that socket emissions for user metadata fetching are correctly triggered during import events.
…yer imports - Added a note in testing documentation to discourage importing `mongoService` or other persistence layers directly in tests. - Recommended using test drivers (e.g., `UserDriver`, `WatchDriver`) to maintain test agnosticism towards the backing store, facilitating easier transitions away from MongoDB in the future.
Co-authored-by: Tyler Dane <tyler-dane@users.noreply.github.com>
…ndar labels Co-authored-by: Tyler Dane <tyler-dane@users.noreply.github.com>
…e UI fix(backend): add race condition check before scheduling Google repair fix(web): only close command palette when repair triggered from command palette Co-authored-by: Tyler Dane <tyler-dane@users.noreply.github.com>
Co-authored-by: Tyler Dane <tyler-dane@users.noreply.github.com>
…cessing - Updated SyncController to skip recovery if a full import is already active for the user. - Refactored syncService to ignore stale notifications when no exact watch record exists, improving notification handling. - Enhanced tests to validate the new behavior for handling Google Calendar notifications and sync states. - Improved user metadata service to return appropriate sync statuses without scheduling unnecessary repairs.
- Introduced a new type for the response structure from SupertokensUserMetadata, improving type safety. - Updated the getStoredUserMetadata and updateUserMetadata methods to handle the new response format, ensuring proper error handling and returning the correct metadata. - Enhanced code readability by simplifying the response handling process.
…e management - Introduced a new utility function, `refreshUserMetadata`, to handle user metadata retrieval and state updates in the Redux store. - Enhanced the `userMetadataSlice` to include loading states, allowing for better user experience during metadata fetching. - Updated the `SessionProvider` to refresh user metadata upon session initialization and when a session already exists. - Refactored the `useConnectGoogle` hook to incorporate user metadata status, improving the handling of Google Calendar connection states. - Added tests for the new user metadata utility and updated existing tests to ensure proper functionality and state management.
- Mocked the `react-cmdk` library to provide a more accurate testing environment for the command palette component. - Updated test assertions to use `getByRole` for button state checks, ensuring better accessibility compliance and clarity in tests. - Improved the handling of disabled button states in tests for Google Calendar connection and syncing actions.
- Removed the use of `FETCH_USER_METADATA` in favor of directly reconnecting the socket to ensure a fresh session after Google revocation. - Updated the test case to reflect the new behavior, verifying that the socket reconnects instead of emitting a metadata fetch event. - Improved code clarity by simplifying the revocation handling logic.
…red payloads - Introduced a new type, `ImportGCalEndPayload`, to standardize the payload structure for Google Calendar import completion events. - Updated the `handleImportGCalEnd` method to accept the new payload type, improving type safety and clarity. - Refactored various components and tests to utilize the structured payload, ensuring consistent handling of import results and error messages. - Enhanced tests to validate the new payload structure and its impact on the import flow.
…unctions - Introduced utility functions for managing Google sign-in success and session user ID resolution, improving the handling of Google authentication flows. - Updated the `signInUpPOST` API implementation to integrate Google sign-in success handling, ensuring proper session management. - Added tests for the new utility functions to validate their behavior in various scenarios, enhancing overall test coverage. - Refactored the `useGoogleAuth` hook to support reconnect intents, improving user experience during Google Calendar reconnections.
…connect handling - Renamed `reconnectGoogleForSession` to `repairGoogleConnection` for clarity in the authentication service. - Updated parameter names for consistency, changing `sessionUserId` to `compassUserId`. - Introduced `determineGoogleAuthMode` to assess the user's Google authentication state and return appropriate modes. - Enhanced tests to cover new authentication modes and ensure proper handling of reconnect scenarios. - Removed unused GoogleAuthIntent handling from various components, streamlining the authentication process.
| const value = await this.fetchUserMetadata(userId); | ||
| const update = mergeWith(value, data); | ||
| const value = await this.getStoredUserMetadata(userId); | ||
| const update = mergeWith(value, data) as UserMetadata; |
Check warning
Code scanning / CodeQL
Prototype-polluting merge call Medium
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI about 18 hours ago
General approach: Remove the use of the vulnerable lodash.mergewith for merging untrusted input, or ensure that untrusted input cannot inject dangerous keys like __proto__, constructor, or prototype. Since we are constrained to change only the shown files, the most robust fix here is to stop using lodash.mergewith in updateUserMetadata and instead use a safe deep-merge implementation that ignores prototype-pollution keys, or a shallow merge if deep semantics are not strictly necessary.
Best concrete fix for this code: Replace the call mergeWith(value, data) with a safe merge that:
- Starts from a fresh plain object.
- Performs a recursive merge only over “safe” keys (excluding
__proto__,constructor,prototype). - Copies properties from the existing stored metadata (
value) and from the user-supplieddata, wheredataoverridesvalue.
This preserves the behavior of “nested objects and all lower-level properties will merge with existing ones” while removing the prototype-pollution vector.
We will implement a small internal helper function safeMergeUserMetadata inside user-metadata.service.ts:
- It will recursively merge two
anyobjects. - It will skip keys
"__proto__","prototype", and"constructor". - It will only recursively merge when both sides are non-null plain objects (not arrays, functions, or other special objects).
- Otherwise it will take the “source” value (from
data) as the override.
Then, inupdateUserMetadata, we will replacemergeWith(value, data)withsafeMergeUserMetadata(value, data)and remove the unusedlodash.mergewithimport. No changes are needed in the controller once the sink is safe.
Concretely:
- In
packages/backend/src/user/services/user-metadata.service.ts:- Remove
import mergeWith from "lodash.mergewith";. - Add a
const POLLUTION_KEYS = new Set([...])and afunction safeMergeUserMetadata<T>(target: T, source: Partial<T>): Tnear the top of the file (after imports or before the class). - Change line 167 to use
safeMergeUserMetadata(value, data)instead ofmergeWith(value, data).
- Remove
packages/backend/src/user/controllers/user.controller.tsdoes not need code changes for the fix.packages/backend/package.json: we are not required to adjust dependencies for the core code fix, though in a real project you would also removelodash.mergewithor update it. Per instructions, we will not touch it.
reconnectGoogleForSessiontorepairGoogleConnectionfor clarity in the authentication service.sessionUserIdtocompassUserId.determineGoogleAuthModeto assess the user's Google authentication state and return appropriate modes.