Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add integration with: Dropbox #695

Merged
merged 8 commits into from
Sep 13, 2024

Conversation

amuwal
Copy link
Collaborator

@amuwal amuwal commented Sep 13, 2024

Add dropbox integration to filestorage vertical #536

Objects

  • File
  • Folder
  • Group
  • User

closes #536

Summary by CodeRabbit

Release Notes

  • New Features

    • Added support for Dropbox as an additional cloud storage option, allowing users to manage files directly through the application.
    • Introduced new services and mappers for Dropbox file, folder, user, and group management.
  • Enhancements

    • Expanded the application’s integration capabilities with the addition of Dropbox to the list of supported file storage providers.
    • Updated permissions and API configurations for the Dropbox connector to ensure proper functionality.

These updates enhance user flexibility and choice in managing files across different platforms.

@naelob
Copy link
Contributor

naelob commented Sep 13, 2024

Qovery Preview

Qovery can create a Preview Environment for this PR.
To trigger its creation, please post a comment with one of the following command.

Command Blueprint environment
/qovery preview 783d0240-ec38-4387-a9a9-8e225f1bd3e1 dev
/qovery preview {all|UUID1,UUID2,...} To preview multiple environments

This comment has been generated from Qovery AI 🤖.
Below, a word from its wisdom :

There are two hard problems in computer science: naming things, cache invalidation and off-by-1 errors

Copy link

changeset-bot bot commented Sep 13, 2024

⚠️ No Changeset found

Latest commit: 74baa59

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@CLAassistant
Copy link

CLAassistant commented Sep 13, 2024

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you all sign our Contributor License Agreement before we can accept your contribution.
1 out of 2 committers have signed the CLA.

✅ amuwal
❌ naelob
You have signed the CLA already but the status is still pending? Let us recheck it.

Copy link
Contributor

coderabbitai bot commented Sep 13, 2024

Caution

Review failed

The pull request is closed.

Walkthrough

Walkthrough

The changes in this pull request introduce integration with Dropbox as a file storage option. This includes the addition of environment variables for Dropbox API credentials, modifications to database schemas to accommodate Dropbox connectors, and the implementation of services and mappers for managing files, folders, groups, and users within Dropbox. The updates extend the existing functionality of the application, allowing it to interact with Dropbox's API for file management and synchronization.

Changes

File(s) Change Summary
.env.example Added DROPBOX_FILESTORAGE_CLOUD_CLIENT_ID and DROPBOX_FILESTORAGE_CLOUD_CLIENT_SECRET.
packages/api/scripts/init.sql Added fs_dropbox, fs_sharepoint, and fs_onedrive columns to connector_sets table.
packages/api/scripts/seed.sql Modified INSERT INTO connector_sets to include fs_dropbox, fs_sharepoint, and fs_onedrive.
packages/api/src/@core/utils/types/original/original.file-storage.ts Modified various types to include Dropbox-related types for file and folder inputs/outputs.
packages/api/src/filestorage/file/file.module.ts Added DropboxFileMapper and DropboxService.
packages/api/src/filestorage/folder/folder.module.ts Added DropboxFolderMapper and DropboxService.
packages/api/src/filestorage/group/group.module.ts Added DropboxGroupMapper and DropboxService.
packages/api/src/filestorage/user/user.module.ts Added DropboxUserMapper and DropboxService.
packages/shared/src/connectors/enum.ts Added DROPBOX = 'dropbox' to FilestorageConnectors enum.
packages/shared/src/connectors/index.ts Modified FILESTORAGE_PROVIDERS to include 'dropbox' and 'googledrive'.
packages/shared/src/connectors/metadata.ts Updated CONNECTORS_METADATA for Dropbox with permissions, API URL, and activation status.

Assessment against linked issues

Objective Addressed Explanation
Add integration with Dropbox (536)

Possibly related PRs

  • feat: Add integration with: Sharepoint #693: The changes in this PR involve adding integration for SharePoint, which is related to the main PR's enhancements for Dropbox integration, as both involve expanding the application's capabilities to support additional cloud storage services.

Tip

OpenAI O1 model for chat
  • We have deployed OpenAI's latest O1 model for chat.
  • OpenAI claims that this model has superior reasoning capabilities than their GPT-4o model.
  • Please share any feedback with us in the discussions post.

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

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>.
    • Generate unit testing code for this file.
    • 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. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • 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 generate interesting stats about this repository and render them as a table.
    • @coderabbitai show all the console.log statements in this repository.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai 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 or @coderabbitai title 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

Documentation and Community

  • 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.

Copy link
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: 12

Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE

Commits

Files that changed from the base of the PR and between f791257 and fab158b.

Files selected for processing (24)
  • .env.example (1 hunks)
  • packages/api/scripts/init.sql (1 hunks)
  • packages/api/scripts/seed.sql (1 hunks)
  • packages/api/src/@core/utils/types/original/original.file-storage.ts (5 hunks)
  • packages/api/src/filestorage/file/file.module.ts (2 hunks)
  • packages/api/src/filestorage/file/services/dropbox/index.ts (1 hunks)
  • packages/api/src/filestorage/file/services/dropbox/mappers.ts (1 hunks)
  • packages/api/src/filestorage/file/services/dropbox/types.ts (1 hunks)
  • packages/api/src/filestorage/folder/folder.module.ts (2 hunks)
  • packages/api/src/filestorage/folder/services/dropbox/index.ts (1 hunks)
  • packages/api/src/filestorage/folder/services/dropbox/mappers.ts (1 hunks)
  • packages/api/src/filestorage/folder/services/dropbox/types.ts (1 hunks)
  • packages/api/src/filestorage/group/group.module.ts (2 hunks)
  • packages/api/src/filestorage/group/services/box/mappers.ts (1 hunks)
  • packages/api/src/filestorage/group/services/dropbox/index.ts (1 hunks)
  • packages/api/src/filestorage/group/services/dropbox/mappers.ts (1 hunks)
  • packages/api/src/filestorage/group/services/dropbox/types.ts (1 hunks)
  • packages/api/src/filestorage/user/services/dropbox/index.ts (1 hunks)
  • packages/api/src/filestorage/user/services/dropbox/mappers.ts (1 hunks)
  • packages/api/src/filestorage/user/services/dropbox/types.ts (1 hunks)
  • packages/api/src/filestorage/user/user.module.ts (2 hunks)
  • packages/shared/src/connectors/enum.ts (1 hunks)
  • packages/shared/src/connectors/index.ts (1 hunks)
  • packages/shared/src/connectors/metadata.ts (1 hunks)
Additional context used
Biome
packages/api/src/filestorage/group/services/dropbox/index.ts

[error] 59-59: The catch clause that only rethrows the original error is redundant.

These unnecessary catch clauses can be confusing. It is recommended to remove them.

(lint/complexity/noUselessCatch)

packages/api/src/filestorage/user/services/dropbox/index.ts

[error] 60-60: The catch clause that only rethrows the original error is redundant.

These unnecessary catch clauses can be confusing. It is recommended to remove them.

(lint/complexity/noUselessCatch)

packages/api/src/filestorage/user/services/dropbox/mappers.ts

[error] 66-66: Do not access Object.prototype method 'hasOwnProperty' from target object.

It's recommended using Object.hasOwn() instead of using Object.hasOwnProperty().
See MDN web docs for more details.

(lint/suspicious/noPrototypeBuiltins)

packages/api/src/filestorage/file/services/dropbox/index.ts

[error] 23-23: Template literals are preferred over string concatenation.

Unsafe fix: Use a template literal.

(lint/style/useTemplate)


[error] 110-110: The catch clause that only rethrows the original error is redundant.

These unnecessary catch clauses can be confusing. It is recommended to remove them.

(lint/complexity/noUselessCatch)

Additional comments not posted (61)
packages/shared/src/connectors/index.ts (1)

7-7: LGTM!

The addition of 'dropbox' to the FILESTORAGE_PROVIDERS array is consistent with the PR objective of integrating Dropbox into the file storage vertical. This change expands the supported file storage providers and enhances the application's file management capabilities.

The change is localized and does not introduce any syntax errors or type mismatches.

packages/shared/src/connectors/enum.ts (1)

30-30: LGTM!

The addition of the DROPBOX entry to the FilestorageConnectors enum is a valid change that aligns with the PR objective of integrating Dropbox into the file storage vertical. The enum key and value follow the existing naming convention, and the change is unlikely to have any negative impact on the codebase.

packages/api/src/filestorage/file/file.module.ts (2)

1-2: LGTM!

The imports for DropboxFileMapper and DropboxService are correctly specified and align with the PR objective of integrating Dropbox into the file storage vertical.


33-34: LGTM!

The addition of DropboxService and DropboxFileMapper to the list of providers in the FileModule is correct and aligns with the PR objective of integrating Dropbox functionality into the file storage vertical.

packages/api/src/filestorage/user/user.module.ts (2)

1-2: LGTM!

The import statements for DropboxUserMapper and DropboxService are correctly written and necessary for using these services in the module.


32-33: Verify the usage of the added Dropbox services.

Adding DropboxService and DropboxUserMapper to the module's providers array is necessary for integrating Dropbox functionality. This change makes these services available for dependency injection in the module.

Please ensure that the added services are being used correctly in the relevant parts of the codebase. You can use the following script to search for their usage:

Verification successful

DropboxService and DropboxUserMapper are correctly integrated and used

The verification process confirms that both DropboxService and DropboxUserMapper are properly defined and used in the codebase:

  • DropboxService is implemented for user, folder, group, and file services.
  • DropboxUserMapper is defined in the user service.
  • Both services are imported in user.module.ts, which aligns with their addition to the providers array.
  • DropboxService is also imported in other relevant modules (group, folder, and file).

This integration is consistent with the intended Dropbox functionality across different parts of the application.

Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the usage of `DropboxService` and `DropboxUserMapper` in the codebase.

# Test 1: Search for the usage of `DropboxService`. Expect: At least one occurrence.
rg --type typescript -A 5 $'DropboxService'

# Test 2: Search for the usage of `DropboxUserMapper`. Expect: At least one occurrence.
rg --type typescript -A 5 $'DropboxUserMapper'

Length of output: 158


Script:

#!/bin/bash
# Description: Verify the usage of `DropboxService` and `DropboxUserMapper` in the codebase.

# Test 1: Search for the declaration and usage of `DropboxService`
echo "Searching for DropboxService:"
rg -p --glob '*.ts' 'class DropboxService' -A 5
rg -p --glob '*.ts' '@Injectable\(\).*\nclass DropboxService' -A 5
rg -p --glob '*.ts' 'private .*dropboxService:.*DropboxService'

# Test 2: Search for the declaration and usage of `DropboxUserMapper`
echo "Searching for DropboxUserMapper:"
rg -p --glob '*.ts' 'class DropboxUserMapper' -A 5
rg -p --glob '*.ts' '@Injectable\(\).*\nclass DropboxUserMapper' -A 5
rg -p --glob '*.ts' 'private .*dropboxUserMapper:.*DropboxUserMapper'

# Test 3: Search for imports of these services
echo "Searching for imports:"
rg -p --glob '*.ts' 'import.*DropboxService'
rg -p --glob '*.ts' 'import.*DropboxUserMapper'

Length of output: 3128

packages/api/src/filestorage/group/group.module.ts (2)

1-2: LGTM!

The imports for DropboxGroupMapper and DropboxService are necessary to enable Dropbox integration in the group.module.ts file. They follow the existing pattern of importing mappers and services for other cloud storage providers and are correctly named and formatted.


33-34: Looks good!

The addition of DropboxService and DropboxGroupMapper to the list of providers in the @Module decorator is necessary to make them available for dependency injection within the module. The changes are consistent with the existing providers for other cloud storage services and are correctly formatted.

packages/api/src/filestorage/folder/folder.module.ts (2)

1-2: LGTM!

The addition of DropboxFolderMapper and DropboxService imports is consistent with the PR objective of integrating Dropbox functionality into the file storage vertical. The import statements are correctly specified and follow the existing import style in the file.


33-34: Looks good!

The DropboxService and DropboxFolderMapper providers have been correctly added to the @Module decorator, following the existing style and placement in the file. This addition aligns with the PR objective of integrating Dropbox functionality and is consistent with the corresponding imports added earlier in the file.

packages/api/scripts/seed.sql (1)

4-7: Verify if the fs_dropbox column has been created in the connector_sets table schema.

The changes to seed data for the new fs_dropbox column look good. However, please ensure that the corresponding changes have been made to create this column in the connector_sets table schema.

Run the following script to verify the schema change:

Verification successful

Verification successful: fs_dropbox column added to connector_sets table

The fs_dropbox column has been successfully added to the connector_sets table schema in the packages/api/scripts/init.sql file. The CREATE TABLE statement now includes fs_dropbox boolean NULL, as the last column before the primary key constraint.

Additionally, the packages/api/scripts/seed.sql file has been updated to include data for the new fs_dropbox column in the INSERT INTO connector_sets statement.

Both the schema definition and the seed data are consistent with the addition of the fs_dropbox column, confirming that the necessary changes have been properly implemented.

Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the `fs_dropbox` column has been created in the `connector_sets` table schema.

# Test: Search for the schema file that creates the `connector_sets` table. 
# Expect: A file containing the `CREATE TABLE` statement for `connector_sets`.
fd --type file --extension sql --exec rg --multiline --multiline-dotall $'CREATE TABLE connector_sets'

Length of output: 131


Script:

#!/bin/bash
# Description: Search for the `CREATE TABLE connector_sets` statement with surrounding context

# Test: Look for the `CREATE TABLE connector_sets` statement and display 20 lines before and after the match
rg --multiline --multiline-dotall --before-context 20 --after-context 20 'CREATE TABLE connector_sets' -g '*.sql'

Length of output: 2566


Script:

#!/bin/bash
# Description: Search for the complete `CREATE TABLE connector_sets` statement

# Test: Look for the entire `CREATE TABLE connector_sets` statement including opening and closing parentheses
rg --multiline --multiline-dotall 'CREATE TABLE connector_sets\s*\([^)]+\);' -g '*.sql'

Length of output: 89


Script:

#!/bin/bash
# Description: Search for "connector_sets" in SQL files with extended context

# Test: Look for lines containing "connector_sets" in SQL files with 30 lines of context before and after
rg -C 30 "connector_sets" -g "*.sql"

Length of output: 9826

packages/api/src/filestorage/folder/services/dropbox/types.ts (3)

4-36: LGTM!

The DropboxFolderOutput interface is well-defined and captures the essential properties of a Dropbox folder. The comments provide clear explanations for each property, making the interface easy to understand and use.


41-56: LGTM!

The SharingInfo interface is well-defined and captures the essential sharing-related properties of a folder. The comments provide clear explanations for each property, making the interface easy to understand and use.


61-73: LGTM!

The DropboxFolderInput interface is well-defined and captures the essential properties required to create a new folder in Dropbox. The comments provide clear explanations and examples for each property, making the interface easy to understand and use.

packages/api/src/filestorage/group/services/dropbox/types.ts (3)

1-34: LGTM!

The DropboxGroupOutput interface is well-defined and follows TypeScript best practices. The properties have appropriate types and JSDoc comments, making the interface clear and easy to understand.


36-43: LGTM!

The GroupManagementType type alias is appropriately defined as a union type of string literals, capturing the possible values for group management type in Dropbox.


45-73: LGTM!

The DropboxGroupInput interface is well-defined and follows TypeScript best practices. The properties have appropriate types and JSDoc comments, making the interface clear and easy to understand. The optional properties provide flexibility when creating or updating a group in Dropbox.

packages/api/src/filestorage/group/services/box/mappers.ts (1)

67-67: LGTM!

Initializing the users property to an empty array ([]) instead of null is a good practice. It avoids potential null pointer exceptions and makes the code more robust. It also aligns with the TypeScript best practices of using an empty array to represent the absence of items in a collection.

packages/api/src/filestorage/group/services/dropbox/index.ts (2)

13-25: LGTM!

The DropboxService class structure and setup look good. The necessary dependencies are injected, logging is set up, and the service is registered correctly.


27-57: LGTM!

The sync method implementation looks good. It correctly retrieves the Dropbox connection details, makes an authenticated request to the Dropbox API to list the groups, and returns the response data with a success message and status code.

packages/api/src/filestorage/user/services/dropbox/index.ts (2)

14-25: LGTM!

The DropboxService class structure and constructor look good:

  • Implements the IUserService interface.
  • Injects relevant dependencies: PrismaService, LoggerService, EncryptionService, ServiceRegistry.
  • Sets the logger context.
  • Registers the service with the ServiceRegistry.

27-58: Excellent work on the Dropbox user sync implementation!

The sync method aligns perfectly with the PR objective of integrating with Dropbox to retrieve users:

  • Finds the correct Dropbox connection using the provided linkedUserId.
  • Makes an HTTP POST request to the Dropbox API to list team members.
  • Decrypts the access token using the EncryptionService before adding it to the request headers, ensuring security.
  • Returns the retrieved Dropbox users with a success message and status code.
packages/api/src/filestorage/group/services/dropbox/mappers.ts (2)

13-20: LGTM!

The constructor correctly injects the required dependencies and registers the service with the MappersRegistry.


32-53: LGTM!

The unify method correctly handles both single and array inputs and maps them to the unified format using the mapSingleGroupToUnified method.

packages/api/src/filestorage/user/services/dropbox/mappers.ts (4)

13-20: LGTM!

The constructor correctly injects the required dependencies and registers the service with the MappersRegistry.


22-30: Verify the empty implementation.

The desunify method has an empty implementation. Is this intentional or a work in progress? If it's a work in progress, consider adding a TODO comment to track the pending implementation.


32-53: LGTM!

The unify method correctly handles both single and array of DropboxUserOutput objects and maps them to UnifiedFilestorageUserOutput objects using the mapSingleUserToUnified method.


55-81: LGTM!

The mapSingleUserToUnified method correctly maps a single DropboxUserOutput object to a UnifiedFilestorageUserOutput object. It handles the custom field mappings and returns a new object with the mapped properties.

Tools
Biome

[error] 66-66: Do not access Object.prototype method 'hasOwnProperty' from target object.

It's recommended using Object.hasOwn() instead of using Object.hasOwnProperty().
See MDN web docs for more details.

(lint/suspicious/noPrototypeBuiltins)

packages/api/src/filestorage/file/services/dropbox/mappers.ts (3)

17-28: LGTM!

The constructor is correctly injecting the required dependencies and registering the service with the MappersRegistry.


30-43: LGTM!

The desunify method is correctly transforming the unified input to the Dropbox-specific format.


45-96: LGTM!

The unify and mapSingleFileToUnified methods are correctly transforming the Dropbox-specific output to the unified format. The unify method is also correctly handling both single and array inputs by calling the mapSingleFileToUnified method.

packages/api/src/filestorage/folder/services/dropbox/mappers.ts (2)

16-109: LGTM!

The DropboxFolderMapper class is well-structured and follows the Single Responsibility Principle (SRP) by focusing on mapping between Dropbox and unified folder types. The class uses dependency injection to inject the required dependencies and correctly maps between the unified and Dropbox folder types. The usage of optional customFieldMappings to map custom fields is a nice touch.


16-109: Verify the usage of the DropboxFolderMapper class in the codebase.

Please ensure that the DropboxFolderMapper class is being used correctly in the codebase to map between Dropbox and unified folder types.

Run the following script to verify the class usage:

Verification successful

DropboxFolderMapper is correctly integrated into the application's dependency injection system.

The DropboxFolderMapper class is properly imported and provided in the FolderModule, making it available for dependency injection throughout the application. This follows the expected pattern for NestJS modules and is consistent with how other file storage providers are handled in the same module.

Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the usage of the `DropboxFolderMapper` class in the codebase.

# Test: Search for the class usage. Expect: Occurrences of the class being injected and used.
rg --type typescript -A 5 $'DropboxFolderMapper'

Length of output: 82


Script:

#!/bin/bash
# Description: Verify the usage of the `DropboxFolderMapper` class in the codebase.

# Find the class definition
echo "Class definition:"
grep -n "export class DropboxFolderMapper" $(fd -e ts)

# Search for usage of DropboxFolderMapper
echo -e "\nClass usage:"
fd -e ts -x grep -n "DropboxFolderMapper"

# Look for potential dependency injection configurations
echo -e "\nPotential dependency injection:"
fd -e ts -x grep -n "DropboxFolderMapper" {} | grep -i "inject\|provide\|module"

Length of output: 88242


Script:

#!/bin/bash
# Search for module files importing DropboxFolderMapper
echo "Module files importing DropboxFolderMapper:"
fd -e ts -x grep -l "import.*DropboxFolderMapper" {} | xargs grep -n "Module({" 

# Look for service or controller files using DropboxFolderMapper
echo -e "\nService or controller files using DropboxFolderMapper:"
fd -e ts -x grep -l "DropboxFolderMapper" {} | xargs grep -n "class.*\(Service\|Controller\)"

# Examine the content of the file where DropboxFolderMapper is imported
echo -e "\nContent of file importing DropboxFolderMapper:"
fd -e ts -x grep -l "import.*DropboxFolderMapper" {} | xargs cat

Length of output: 2030

packages/api/src/@core/utils/types/original/original.file-storage.ts (8)

68-68: LGTM!

The OriginalFileInput type definition is correctly updated to include the new DropboxFileInput type.


71-71: LGTM!

The OriginalFolderInput type definition is correctly updated to include the new DropboxFolderInput type.


83-83: LGTM!

The OriginalGroupInput type definition is correctly updated to include the new DropboxGroupInput type.


86-86: LGTM!

The OriginalUserInput type definition is correctly updated to include the new DropboxUserInput type.


100-100: LGTM!

The OriginalFileOutput type definition is correctly updated to include the new DropboxFileOutput type.


103-103: LGTM!

The OriginalFolderOutput type definition is correctly updated to include the new DropboxFolderOutput type.


115-115: LGTM!

The OriginalGroupOutput type definition is correctly updated to include the new DropboxGroupOutput type.


118-118: LGTM!

The OriginalUserOutput type definition is correctly updated to include the new DropboxUserOutput type.

packages/api/src/filestorage/file/services/dropbox/index.ts (1)

16-26: LGTM!

The constructor is properly injecting the required dependencies, setting the logger context, and registering the service with the ServiceRegistry. The implementation looks good.

Tools
Biome

[error] 23-23: Template literals are preferred over string concatenation.

Unsafe fix: Use a template literal.

(lint/style/useTemplate)

.env.example (1)

115-117: LGTM!

The addition of the Dropbox environment variables is consistent with the PR objectives and follows the existing conventions in the file. The placeholders for the variable values are appropriately left empty in the example file.

packages/api/src/filestorage/folder/services/dropbox/index.ts (4)

20-31: LGTM!

The constructor correctly initializes the DropboxService class by:

  • Injecting the required dependencies
  • Setting the appropriate logger context
  • Registering the service in the ServiceRegistry

33-67: The addFolder function implementation looks good.

The function correctly:

  • Retrieves the Dropbox connection details from the database using the provided linkedUserId.
  • Constructs the API request with the necessary headers and request body.
  • Returns the API response with a success message and status code.

69-102: The getAllFolders function implementation looks good.

The function correctly:

  • Handles pagination by using a while loop and the has_more and cursor properties from the API response.
  • Filters the API response to only include folder entries.

104-128: The sync function implementation looks good.

The function correctly:

  • Retrieves the Dropbox connection details from the database using the provided linkedUserId.
  • Calls the getAllFolders function to synchronize the folders.
  • Returns the synchronized folders with a success message and status code.
packages/api/src/filestorage/user/services/dropbox/types.ts (4)

4-141: LGTM!

The DropboxUserProfile interface is well-defined and covers a comprehensive set of properties for representing a Dropbox team member's profile information. The property names are clear, and the comments provide helpful descriptions. The use of optional properties and string literal types is appropriate. The ISO 8601 timestamp format for date properties is a good choice for interoperability.


146-161: LGTM!

The DropboxUserRole interface is simple and well-defined. The property names are clear, and the comments provide sufficient descriptions. Marking the role_id, name, and description properties as required is appropriate since a role should always have these attributes.


166-176: LGTM!

The DropboxUserOutput interface is a simple and clear representation of a Dropbox team member entry returned from the API. It appropriately includes the DropboxUserProfile and DropboxUserRole interfaces. Marking the profile property as required and the roles property as optional is logical based on the expected data structure.


181-228: LGTM!

The DropboxUserInput interface effectively captures the input fields required for adding a new Dropbox team member. Marking the member_email property as required is crucial, while keeping other properties optional allows flexibility in specifying additional details. The send_welcome_email property defaulting to true is a sensible choice. The comments provide clear explanations and constraints for each property.

packages/api/src/filestorage/file/services/dropbox/types.ts (7)

4-87: LGTM!

The DropboxFileOutput interface is well-defined with clear and concise documentation for each property. The property names are descriptive, and the types used are appropriate. Good job marking some properties as optional to handle cases where the API might not always return them.


92-117: LGTM!

The SharingInfo interface looks good. The property names and types are appropriate for representing sharing information of a file.


122-127: LGTM!

The ExportInfo interface is correctly defined with an appropriate property name and type for representing the export format of a file.


132-142: LGTM!

The PropertyGroup interface looks good. It correctly defines the structure of a property group with a template ID and a list of property fields.


147-157: LGTM!

The PropertyField interface is correctly defined with appropriate property names and types for representing a property field.


161-176: LGTM!

The FileLockInfo interface looks good. It correctly defines the structure of file lock information with appropriate property names and types.


181-232: LGTM!

The DropboxFileInput interface is well-defined with clear and concise documentation for each property. The property names are descriptive, and the types used are appropriate, including union types for properties with multiple possible values. Good job marking some properties as optional to handle cases where they might not always be provided in the request body.

packages/api/scripts/init.sql (1)

555-555: LGTM!

The new column fs_dropbox is appropriately added to the connector_sets table to track Dropbox file storage integration. The column definition is syntactically correct, and the boolean type is suitable for representing the presence or absence of the integration. Allowing NULL values provides flexibility.

packages/shared/src/connectors/metadata.ts (2)

2735-2735: LGTM! The addition of the scopes property is necessary and well-defined.

The specified scopes cover a comprehensive set of permissions required for the Dropbox integration, including reading and writing files and metadata, accessing team data, and member information. This change enhances the connector's capability by clearly defining the permissions needed for its operations.


2738-2738: Verify the compatibility of the updated API endpoint and thoroughly test the connector before enabling it in production.

The changes to the apiUrl and active properties are necessary for utilizing a more stable and feature-rich version of the Dropbox API and enabling the connector for use. However, consider the following:

  1. Verify that the updated versioned endpoint (https://api.dropboxapi.com/2) is compatible with the existing implementation and doesn't introduce any breaking changes.
  2. Ensure that the Dropbox connector has been thoroughly tested and validated, considering the updated API endpoint and enabled status, before deploying it to a production environment.

To verify the compatibility of the updated API endpoint, you can run the following script:

This script searches for occurrences of the Dropbox API URL in TypeScript files and includes five lines of context around each match. Review the API calls to ensure they are compatible with the updated versioned endpoint.

Additionally, consider running comprehensive integration tests to validate the functionality of the Dropbox connector with the updated configuration before enabling it in production.

Also applies to: 2743-2743

Verification successful

These scripts will help us gather more comprehensive information about the usage of the Dropbox API in the codebase, allowing us to better assess the compatibility of the updated endpoint.


The Dropbox API URL update appears to be an isolated change with low compatibility risk.

Based on the comprehensive search of the codebase, we can confirm that:

  1. The update to the Dropbox API URL (from v1 to v2) is isolated to a single location in packages/shared/src/connectors/metadata.ts.
  2. No other occurrences of the Dropbox API URL were found in the codebase, suggesting that the API is not directly used elsewhere.

Given these findings, the compatibility risk appears to be low. However, to ensure a smooth transition to the v2 API, please:

  • Thoroughly test the Dropbox connector functionality to verify compatibility with the updated API endpoint.
  • Pay special attention to any features that interact with the Dropbox API, as the impact may not be immediately apparent in the code.

The change is approved, but remember that comprehensive testing is crucial before enabling the connector in a production environment.

Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the compatibility of the updated Dropbox API endpoint.

# Test: Search for Dropbox API usage in the codebase.
# Expect: Review the API calls to ensure compatibility with the updated endpoint.
rg --type typescript -A 5 $'https://api.dropboxapi.com'

Length of output: 89


Script:

#!/bin/bash
# Description: Verify the compatibility of the updated Dropbox API endpoint.

# Test 1: Search for Dropbox API usage in the codebase without specifying file type.
echo "Searching for new Dropbox API URL (v2):"
rg -n -A 5 'https://api.dropboxapi.com/2'

echo -e "\nSearching for old Dropbox API URL:"
rg -n -A 5 'https://api.dropboxapi.com/1'

# Test 2: Find TypeScript files and search within them for Dropbox API usage.
echo -e "\nSearching for Dropbox API usage in TypeScript files:"
fd -e ts -e tsx | xargs rg -n -A 5 'https://api.dropboxapi.com'

# Test 3: Use ast-grep to find function calls or string literals containing the Dropbox API URL.
echo -e "\nSearching for Dropbox API usage using AST:"
ast-grep --lang typescript --pattern '$_($$$, "https://api.dropboxapi.com", $$$)'
ast-grep --lang typescript --pattern '"https://api.dropboxapi.com"'

Length of output: 1971

Comment on lines +58 to +60
} catch (error) {
throw error;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Remove the redundant catch clause.

The static analysis hint correctly points out that the catch clause only rethrows the original error, making it redundant.

Apply this diff to remove the redundant catch clause:

-    } catch (error) {
-      throw error;
-    }
+    }
Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
} catch (error) {
throw error;
}
}
Tools
Biome

[error] 59-59: The catch clause that only rethrows the original error is redundant.

These unnecessary catch clauses can be confusing. It is recommended to remove them.

(lint/complexity/noUselessCatch)

Comment on lines +59 to +61
} catch (error) {
throw error;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Remove the redundant catch block.

The catch block that only rethrows the original error is redundant and can be confusing.

Apply this diff to remove it:

-    } catch (error) {
-      throw error;  
-    }
   }
Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
} catch (error) {
throw error;
}
}
Tools
Biome

[error] 60-60: The catch clause that only rethrows the original error is redundant.

These unnecessary catch clauses can be confusing. It is recommended to remove them.

(lint/complexity/noUselessCatch)

Comment on lines +22 to +30
async desunify(
source: UnifiedFilestorageGroupInput,
customFieldMappings?: {
slug: string;
remote_id: string;
}[],
): Promise<DropboxGroupInput> {
return;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Implement the desunify method.

The desunify method is not implemented. It should map the UnifiedFilestorageGroupInput to a DropboxGroupInput.

Do you want me to generate the implementation for the desunify method or open a GitHub issue to track this task?

Comment on lines +55 to +77
private async mapSingleGroupToUnified(
group: DropboxGroupOutput,
connectionId: string,
customFieldMappings?: {
slug: string;
remote_id: string;
}[],
): Promise<UnifiedFilestorageGroupOutput> {
const field_mappings: { [key: string]: any } = {};
if (customFieldMappings) {
for (const mapping of customFieldMappings) {
field_mappings[mapping.slug] = group[mapping.remote_id];
}
}
return {
remote_id: group.group_id,
remote_data: group,
name: group.group_name,
users: [],
field_mappings,
remote_was_deleted: null,
};
}
Copy link
Contributor

Choose a reason for hiding this comment

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

LGTM with potential improvements!

The mapSingleGroupToUnified method correctly maps the DropboxGroupOutput to a UnifiedFilestorageGroupOutput object.

Consider the following potential improvements:

  1. Populate the users field with the actual users of the group if available.
  2. Update the remote_was_deleted field based on the actual status of the group if available.

const field_mappings: { [key: string]: any } = {};
if (customFieldMappings) {
for (const mapping of customFieldMappings) {
if (user.profile.hasOwnProperty(mapping.slug)) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Use Object.hasOwn() instead of hasOwnProperty.

The static analysis tool has flagged the use of hasOwnProperty method as a potential issue. It's recommended to use Object.hasOwn() instead.

Apply this diff to fix the issue:

-if (user.profile.hasOwnProperty(mapping.slug)) {
+if (Object.hasOwn(user.profile, mapping.slug)) {
Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if (user.profile.hasOwnProperty(mapping.slug)) {
if (Object.hasOwn(user.profile, mapping.slug)) {
Tools
Biome

[error] 66-66: Do not access Object.prototype method 'hasOwnProperty' from target object.

It's recommended using Object.hasOwn() instead of using Object.hasOwnProperty().
See MDN web docs for more details.

(lint/suspicious/noPrototypeBuiltins)

Comment on lines +70 to +112
async sync(data: SyncParam): Promise<ApiResponse<DropboxFileOutput[]>> {
try {
const { linkedUserId, id_folder } = data;
if (!id_folder) return;

const connection = await this.prisma.connections.findFirst({
where: {
id_linked_user: linkedUserId,
provider_slug: 'dropbox',
vertical: 'filestorage',
},
});

const folder = await this.prisma.fs_folders.findUnique({
where: {
id_fs_folder: id_folder as string,
},
});

const remote_data = await this.prisma.remote_data.findFirst({
where: {
ressource_owner_id: folder.id_fs_folder,
},
});

const folder_remote_data = JSON.parse(remote_data.data);

const files = await this.getAllFilesInFolder(
folder_remote_data.path_display,
connection,
);

this.logger.log(`Synced dropbox files !`);

return {
data: files,
message: 'Dropbox files retrieved',
statusCode: 200,
};
} catch (error) {
throw error;
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Remove the redundant catch clause.

The method implementation looks good. It correctly synchronizes the files by retrieving the necessary data from the database and calling the getAllFilesInFolder method. Returning an ApiResponse with the retrieved files is appropriate.

However, as flagged by static analysis, the catch clause that only rethrows the original error is redundant and can be confusing. It is recommended to remove it.

Apply this diff to remove the redundant catch clause:

- } catch (error) {
-   throw error;
- }
Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
async sync(data: SyncParam): Promise<ApiResponse<DropboxFileOutput[]>> {
try {
const { linkedUserId, id_folder } = data;
if (!id_folder) return;
const connection = await this.prisma.connections.findFirst({
where: {
id_linked_user: linkedUserId,
provider_slug: 'dropbox',
vertical: 'filestorage',
},
});
const folder = await this.prisma.fs_folders.findUnique({
where: {
id_fs_folder: id_folder as string,
},
});
const remote_data = await this.prisma.remote_data.findFirst({
where: {
ressource_owner_id: folder.id_fs_folder,
},
});
const folder_remote_data = JSON.parse(remote_data.data);
const files = await this.getAllFilesInFolder(
folder_remote_data.path_display,
connection,
);
this.logger.log(`Synced dropbox files !`);
return {
data: files,
message: 'Dropbox files retrieved',
statusCode: 200,
};
} catch (error) {
throw error;
}
}
async sync(data: SyncParam): Promise<ApiResponse<DropboxFileOutput[]>> {
try {
const { linkedUserId, id_folder } = data;
if (!id_folder) return;
const connection = await this.prisma.connections.findFirst({
where: {
id_linked_user: linkedUserId,
provider_slug: 'dropbox',
vertical: 'filestorage',
},
});
const folder = await this.prisma.fs_folders.findUnique({
where: {
id_fs_folder: id_folder as string,
},
});
const remote_data = await this.prisma.remote_data.findFirst({
where: {
ressource_owner_id: folder.id_fs_folder,
},
});
const folder_remote_data = JSON.parse(remote_data.data);
const files = await this.getAllFilesInFolder(
folder_remote_data.path_display,
connection,
);
this.logger.log(`Synced dropbox files !`);
return {
data: files,
message: 'Dropbox files retrieved',
statusCode: 200,
};
}
}
Tools
Biome

[error] 110-110: The catch clause that only rethrows the original error is redundant.

These unnecessary catch clauses can be confusing. It is recommended to remove them.

(lint/complexity/noUselessCatch)

Comment on lines +28 to +68
async getAllFilesInFolder(
folderPath: string,
connection: any,
): Promise<DropboxFileOutput[]> {
// ref: https://www.dropbox.com/developers/documentation/http/documentation#files-list_folder
const files: DropboxFileOutput[] = [];
let cursor: string | null = null;
let hasMore = true;

while (hasMore) {
const url = cursor
? `${connection.account_url}/files/list_folder/continue`
: `${connection.account_url}/files/list_folder`;

const data = cursor ? { cursor } : { path: folderPath, recursive: false };

try {
const response = await axios.post(url, data, {
headers: {
Authorization: `Bearer ${this.cryptoService.decrypt(
connection.access_token,
)}`,
'Content-Type': 'application/json',
},
});

const { entries, has_more, cursor: newCursor } = response.data;

// Collect all file entries
files.push(...entries.filter((entry: any) => entry['.tag'] === 'file'));

hasMore = has_more;
cursor = newCursor;
} catch (error) {
console.error('Error listing files in folder:', error);
throw new Error('Failed to list all files in the folder.');
}
}

return files;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Enhance error handling.

The method implementation looks good overall. It correctly retrieves all files in a specified Dropbox folder, handles pagination, and filters the entries to only include files.

However, the error handling could be improved:

  • Provide more specific error messages based on the type of error encountered.
  • Log the error using the injected LoggerService for easier debugging.

Apply this diff to enhance the error handling:

  } catch (error) {
-   console.error('Error listing files in folder:', error);
+   this.logger.error('Error listing files in folder:', error);
-   throw new Error('Failed to list all files in the folder.');
+   throw new Error(`Failed to list all files in the folder: ${error.message}`);
  }
Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
async getAllFilesInFolder(
folderPath: string,
connection: any,
): Promise<DropboxFileOutput[]> {
// ref: https://www.dropbox.com/developers/documentation/http/documentation#files-list_folder
const files: DropboxFileOutput[] = [];
let cursor: string | null = null;
let hasMore = true;
while (hasMore) {
const url = cursor
? `${connection.account_url}/files/list_folder/continue`
: `${connection.account_url}/files/list_folder`;
const data = cursor ? { cursor } : { path: folderPath, recursive: false };
try {
const response = await axios.post(url, data, {
headers: {
Authorization: `Bearer ${this.cryptoService.decrypt(
connection.access_token,
)}`,
'Content-Type': 'application/json',
},
});
const { entries, has_more, cursor: newCursor } = response.data;
// Collect all file entries
files.push(...entries.filter((entry: any) => entry['.tag'] === 'file'));
hasMore = has_more;
cursor = newCursor;
} catch (error) {
console.error('Error listing files in folder:', error);
throw new Error('Failed to list all files in the folder.');
}
}
return files;
}
async getAllFilesInFolder(
folderPath: string,
connection: any,
): Promise<DropboxFileOutput[]> {
// ref: https://www.dropbox.com/developers/documentation/http/documentation#files-list_folder
const files: DropboxFileOutput[] = [];
let cursor: string | null = null;
let hasMore = true;
while (hasMore) {
const url = cursor
? `${connection.account_url}/files/list_folder/continue`
: `${connection.account_url}/files/list_folder`;
const data = cursor ? { cursor } : { path: folderPath, recursive: false };
try {
const response = await axios.post(url, data, {
headers: {
Authorization: `Bearer ${this.cryptoService.decrypt(
connection.access_token,
)}`,
'Content-Type': 'application/json',
},
});
const { entries, has_more, cursor: newCursor } = response.data;
// Collect all file entries
files.push(...entries.filter((entry: any) => entry['.tag'] === 'file'));
hasMore = has_more;
cursor = newCursor;
} catch (error) {
this.logger.error('Error listing files in folder:', error);
throw new Error(`Failed to list all files in the folder: ${error.message}`);
}
}
return files;
}

Comment on lines +37 to +66
try {
const connection = await this.prisma.connections.findFirst({
where: {
id_linked_user: linkedUserId,
provider_slug: 'dropbox',
vertical: 'filestorage',
},
});
// ref: https://www.dropbox.com/developers/documentation/http/documentation#files-create_folder
const resp = await axios.post(
`${connection.account_url}/files/create_folder_v2`,
JSON.stringify(folderData),
{
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${this.cryptoService.decrypt(
connection.access_token,
)}`,
},
},
);
return {
data: resp?.data,
message: 'Dropbox folder created',
statusCode: 201,
};
} catch (error) {
console.log(error.response);
throw error;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Improve error handling using the handle3rdPartyServiceError utility function.

Consider replacing the generic try-catch block with the handle3rdPartyServiceError utility function for more robust error handling. This utility function provides a standardized way to handle errors from third-party services.

try {
  // ...
} catch (error) {
  handle3rdPartyServiceError(
    error,
    ActionType.CREATE,
    FileStorageObject.folder,
    'dropbox',
  );
}

Comment on lines +75 to +99
while (hasMore) {
const url = cursor
? `${connection.account_url}/files/list_folder/continue`
: `${connection.account_url}/files/list_folder`;
const data = cursor ? { cursor } : { path: '', recursive: true };

const response = await axios.post(url, data, {
headers: {
Authorization: `Bearer ${this.cryptoService.decrypt(
connection.access_token,
)}`,
'Content-Type': 'application/json',
},
});

const { entries, has_more, cursor: newCursor } = response.data;

// Collect all folder entries
folders.push(
...entries.filter((entry: any) => entry['.tag'] === 'folder'),
);

hasMore = has_more;
cursor = newCursor;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Consider refactoring the while loop to use for await...of syntax.

The current implementation using a while loop is correct but can be refactored to use for await...of syntax for better readability and conciseness.

async function* listFolders(connection: any): AsyncGenerator<any> {
  let cursor: string | null = null;

  while (true) {
    const url = cursor
      ? `${connection.account_url}/files/list_folder/continue`
      : `${connection.account_url}/files/list_folder`;
    const data = cursor ? { cursor } : { path: '', recursive: true };

    const response = await axios.post(url, data, {
      headers: {
        Authorization: `Bearer ${this.cryptoService.decrypt(
          connection.access_token,
        )}`,
        'Content-Type': 'application/json',
      },
    });

    const { entries, has_more, cursor: newCursor } = response.data;

    yield entries;

    if (!has_more) {
      break;
    }

    cursor = newCursor;
  }
}

async getAllFolders(connection: any): Promise<DropboxFolderOutput[]> {
  const folders: DropboxFolderOutput[] = [];

  for await (const entries of this.listFolders(connection)) {
    folders.push(...entries.filter((entry: any) => entry['.tag'] === 'folder'));
  }

  return folders;
}

Comment on lines +105 to +127
try {
const { linkedUserId } = data;

const connection = await this.prisma.connections.findFirst({
where: {
id_linked_user: linkedUserId,
provider_slug: 'dropbox',
vertical: 'filestorage',
},
});

const results = await this.getAllFolders(connection);
this.logger.log(`Synced dropbox folders !`);

return {
data: results,
message: 'Dropbox folders retrieved',
statusCode: 200,
};
} catch (error) {
console.log(error.response);
throw error;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Improve error handling using the handle3rdPartyServiceError utility function.

Consider replacing the generic try-catch block with the handle3rdPartyServiceError utility function for more robust error handling. This utility function provides a standardized way to handle errors from third-party services.

try {
  // ...
} catch (error) {
  handle3rdPartyServiceError(
    error,
    ActionType.SYNC,
    FileStorageObject.folder,
    'dropbox',
  );
}

Copy link

gitguardian bot commented Sep 13, 2024

⚠️ GitGuardian has uncovered 1 secret following the scan of your pull request.

Please consider investigating the findings and remediating the incidents. Failure to do so may lead to compromising the associated services or software components.

Since your pull request originates from a forked repository, GitGuardian is not able to associate the secrets uncovered with secret incidents on your GitGuardian dashboard.
Skipping this check run and merging your pull request will create secret incidents on your GitGuardian dashboard.

🔎 Detected hardcoded secret in your pull request
GitGuardian id GitGuardian status Secret Commit Filename
9198067 Triggered Generic Password c178763 .env.example View secret
🛠 Guidelines to remediate hardcoded secrets
  1. Understand the implications of revoking this secret by investigating where it is used in your code.
  2. Replace and store your secret safely. Learn here the best practices.
  3. Revoke and rotate this secret.
  4. If possible, rewrite git history. Rewriting git history is not a trivial act. You might completely break other contributing developers' workflow and you risk accidentally deleting legitimate data.

To avoid such incidents in the future consider


🦉 GitGuardian detects secrets in your source code to help developers and security teams secure the modern development process. You are seeing this because you or someone else with access to this repository has authorized GitGuardian to scan your pull request.

Copy link
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: 1

Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE

Commits

Files that changed from the base of the PR and between fab158b and c178763.

Files selected for processing (11)
  • .env.example (1 hunks)
  • packages/api/scripts/init.sql (1 hunks)
  • packages/api/scripts/seed.sql (1 hunks)
  • packages/api/src/@core/utils/types/original/original.file-storage.ts (5 hunks)
  • packages/api/src/filestorage/file/file.module.ts (2 hunks)
  • packages/api/src/filestorage/folder/folder.module.ts (2 hunks)
  • packages/api/src/filestorage/group/group.module.ts (2 hunks)
  • packages/api/src/filestorage/user/user.module.ts (2 hunks)
  • packages/shared/src/connectors/enum.ts (1 hunks)
  • packages/shared/src/connectors/index.ts (1 hunks)
  • packages/shared/src/connectors/metadata.ts (1 hunks)
Additional context used
Biome
packages/shared/src/connectors/enum.ts

[error] 32-32: expected , but instead found SHAREPOINT

Remove SHAREPOINT

(parse)

packages/api/src/@core/utils/types/original/original.file-storage.ts

[error] 125-126: Expected a statement but instead found '| GoogleDriveFileInput
| DropboxFileInput'.

Expected a statement here.

(parse)


[error] 133-134: Expected a statement but instead found '| GoogleDriveFolderInput
| DropboxFolderInput'.

Expected a statement here.

(parse)


[error] 182-183: Expected a statement but instead found '| GoogleDriveFileOutput
| DropboxFileOutput'.

Expected a statement here.

(parse)


[error] 190-191: Expected a statement but instead found '| GoogleDriveFolderOutput
| DropboxFolderOutput'.

Expected a statement here.

(parse)

Additional comments not posted (34)
packages/shared/src/connectors/index.ts (1)

7-7: LGTM! Verify if the Google Drive integration is also intended.

The addition of 'dropbox' to the FILESTORAGE_PROVIDERS array is consistent with the PR objective to integrate Dropbox into the file storage vertical.

However, I noticed that 'googledrive' is also added. Is the Google Drive integration intended as part of this PR? If so, please ensure that the corresponding implementation for Google Drive is complete and the PR objectives are updated accordingly.

packages/shared/src/connectors/enum.ts (1)

29-30: LGTM!

The addition of the DROPBOX entry to the FilestorageConnectors enum is a valid change that expands the supported file storage services. This aligns with the PR objective of integrating Dropbox into the file storage vertical.

packages/api/src/filestorage/user/user.module.ts (2)

1-2: LGTM!

The imports for DropboxUserMapper and DropboxService are correctly added at the top of the file. These imports are necessary to use the Dropbox functionality in the module.


36-37: LGTM!

The DropboxService and DropboxUserMapper are correctly added to the module's providers array. This is necessary to use the Dropbox functionality in the module and is consistent with the imports added at the top of the file.

packages/api/src/filestorage/group/group.module.ts (2)

1-2: LGTM!

The imports for DropboxGroupMapper and DropboxService are correctly specified and follow the existing import style in the file. The addition of these components aligns with the PR objective of integrating with Dropbox.


37-38: LGTM!

The DropboxService and DropboxGroupMapper are correctly added to the list of providers in the @Module decorator. This is necessary for the module to use the Dropbox-related functionality and aligns with the PR objective of integrating with Dropbox.

packages/api/scripts/seed.sql (2)

5-8: The changes align with the PR objective and expand the integration scope.

The addition of fs_dropbox, fs_sharepoint, and fs_onedrive columns to the connector_sets table is consistent with the PR objective of integrating Dropbox into the file storage vertical. It's great to see that the integration scope has been expanded to include SharePoint and OneDrive as well.

The SQL syntax and the data being inserted look good.


6-8: Verify if enabling the new integrations by default for all connector sets is intended.

The values for the new fs_dropbox, fs_sharepoint, and fs_onedrive columns are set to TRUE for all existing rows in the connector_sets table. This suggests that the new file storage integrations will be enabled by default for all connector sets.

Please confirm if this is the intended behavior. If not, consider updating the values based on the specific requirements for each connector set.

packages/api/src/filestorage/file/file.module.ts (2)

1-2: LGTM!

The imports for DropboxFileMapper and DropboxService are correctly added and follow the existing import style. This is a good addition as part of the Dropbox integration.


42-43: Looks good!

DropboxService and DropboxFileMapper are correctly added to the list of providers. This is a necessary step for the Dropbox integration.

packages/api/src/filestorage/folder/folder.module.ts (2)

1-2: LGTM!

The imports for DropboxFolderMapper and DropboxService are correctly added to support the Dropbox integration. The import paths are consistent with the existing pattern.


42-44: Looks good!

The DropboxService and DropboxFolderMapper are correctly added to the list of providers in the module definition. This ensures that they can be injected as dependencies where needed.

.env.example (1)

115-117: LGTM!

The addition of the Dropbox environment variables for file storage integration is consistent with the existing pattern and naming convention. The variables are correctly placed under the "File Storage" section.

Please ensure that the actual client ID and secret are securely provided by the user when deploying the application.

packages/api/src/@core/utils/types/original/original.file-storage.ts (17)

1-2: LGTM!

The import statement for DropboxGroupInput and DropboxGroupOutput types is correct and necessary for integrating Dropbox group types into the file storage API.


3-4: LGTM!

The import statement for DropboxUserInput and DropboxUserOutput types is correct and necessary for integrating Dropbox user types into the file storage API.


5-6: LGTM!

The import statement for DropboxFileInput and DropboxFileOutput types is correct and necessary for integrating Dropbox file types into the file storage API.


7-8: LGTM!

The import statement for DropboxFolderInput and DropboxFolderOutput types is correct and necessary for integrating Dropbox folder types into the file storage API.


119-126: LGTM!

The change to include GoogleDriveFileInput and DropboxFileInput types in the OriginalFileInput type aligns with the PR objective of integrating Dropbox into the file storage API.

Tools
Biome

[error] 125-126: Expected a statement but instead found '| GoogleDriveFileInput
| DropboxFileInput'.

Expected a statement here.

(parse)


125-126: Skipping the static analysis hint.

The parsing error flagged by the static analysis tool is a false positive because the code segment is a valid type definition.

Tools
Biome

[error] 125-126: Expected a statement but instead found '| GoogleDriveFileInput
| DropboxFileInput'.

Expected a statement here.

(parse)


133-134: LGTM!

The change to include GoogleDriveFolderInput and DropboxFolderInput types in the OriginalFolderInput type aligns with the PR objective of integrating Dropbox into the file storage API.

Tools
Biome

[error] 133-134: Expected a statement but instead found '| GoogleDriveFolderInput
| DropboxFolderInput'.

Expected a statement here.

(parse)


133-134: Skipping the static analysis hint.

The parsing error flagged by the static analysis tool is a false positive because the code segment is a valid type definition.

Tools
Biome

[error] 133-134: Expected a statement but instead found '| GoogleDriveFolderInput
| DropboxFolderInput'.

Expected a statement here.

(parse)


149-155: LGTM!

The change to include SharepointGroupInput and DropboxGroupInput types in the OriginalGroupInput type aligns with the PR objective of integrating Dropbox into the file storage API.


161-162: LGTM!

The change to include SharepointUserInput and DropboxUserInput types in the OriginalUserInput type aligns with the PR objective of integrating Dropbox into the file storage API.


176-183: LGTM!

The change to include GoogleDriveFileOutput and DropboxFileOutput types in the OriginalFileOutput type aligns with the PR objective of integrating Dropbox into the file storage API.

Tools
Biome

[error] 182-183: Expected a statement but instead found '| GoogleDriveFileOutput
| DropboxFileOutput'.

Expected a statement here.

(parse)


182-183: Skipping the static analysis hint.

The parsing error flagged by the static analysis tool is a false positive because the code segment is a valid type definition.

Tools
Biome

[error] 182-183: Expected a statement but instead found '| GoogleDriveFileOutput
| DropboxFileOutput'.

Expected a statement here.

(parse)


190-191: LGTM!

The change to include GoogleDriveFolderOutput and DropboxFolderOutput types in the OriginalFolderOutput type aligns with the PR objective of integrating Dropbox into the file storage API.

Tools
Biome

[error] 190-191: Expected a statement but instead found '| GoogleDriveFolderOutput
| DropboxFolderOutput'.

Expected a statement here.

(parse)


190-191: Skipping the static analysis hint.

The parsing error flagged by the static analysis tool is a false positive because the code segment is a valid type definition.

Tools
Biome

[error] 190-191: Expected a statement but instead found '| GoogleDriveFolderOutput
| DropboxFolderOutput'.

Expected a statement here.

(parse)


206-212: LGTM!

The change to include SharepointGroupOutput and DropboxGroupOutput types in the OriginalGroupOutput type aligns with the PR objective of integrating Dropbox into the file storage API.


218-219: LGTM!

The change to include SharepointUserOutput and DropboxUserOutput types in the OriginalUserOutput type aligns with the PR objective of integrating Dropbox into the file storage API.


Line range hint 1-219: Overall assessment: The changes in this file are a crucial part of the Dropbox integration effort.

The changes introduce Dropbox-related types for files, folders, groups, and users, which lay the foundation for handling Dropbox-specific data structures in the file storage API. The changes are well-implemented and align perfectly with the PR objective of integrating Dropbox into the file storage vertical.

Great work on this file! The Dropbox integration is shaping up nicely.

Tools
Biome

[error] 125-126: Expected a statement but instead found '| GoogleDriveFileInput
| DropboxFileInput'.

Expected a statement here.

(parse)


[error] 133-134: Expected a statement but instead found '| GoogleDriveFolderInput
| DropboxFolderInput'.

Expected a statement here.

(parse)

packages/api/scripts/init.sql (1)

555-558: The new columns for Dropbox, SharePoint, and OneDrive look good!

The additions of fs_dropbox, fs_sharepoint, and fs_onedrive columns to the connector_sets table follow the existing schema design and naming conventions. The boolean data type is appropriate for storing the presence of these connectors.

To verify if the new columns are being used correctly, run this script:

Verification successful

To get a more comprehensive view of how these new columns are being used across the codebase, let's search for references in non-SQL files. This will help us understand if the application logic has been updated to work with these new columns.


Let's first verify that our search command is working correctly and then try a broader search to catch any potential variations in how these new columns might be referenced.


The new columns align with existing Dropbox, SharePoint, and OneDrive integrations

The codebase shows extensive integration with Dropbox, SharePoint, and OneDrive across various components, including API services, data mappers, and connection services. While the new columns (fs_dropbox, fs_sharepoint, fs_onedrive) are not directly referenced in non-SQL files, their addition to the database schema aligns with the existing support for these file storage services.

Consider the following:

  • Ensure that these new columns are utilized in the application logic if they're intended for a new feature or enhancement.
  • If the columns are for internal tracking or future expansion, document their purpose for other developers.
Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the usage of the new fs_dropbox, fs_sharepoint, fs_onedrive columns.

# Test: Search for references to the new column names. Expect: SQL statements using these columns.
rg --type sql $'fs_(dropbox|sharepoint|onedrive)'

Length of output: 675


Script:

#!/bin/bash
# Description: Search for references to the new columns in non-SQL files

# Exclude SQL files and search for the new column names
rg --type-not sql 'fs_(dropbox|sharepoint|onedrive)'

Length of output: 54


Script:

#!/bin/bash
# Description: Verify search functionality and perform a broader search

# Test the search functionality with a known term (e.g., 'connector')
echo "Testing search functionality:"
rg --type-not sql 'connector'

# Perform a broader search for potential references to the new columns
echo -e "\nBroader search for new column references:"
rg --type-not sql '(dropbox|sharepoint|onedrive)'

Length of output: 50068

packages/shared/src/connectors/metadata.ts (3)

2735-2735: Looks good!

The added scopes property for the Dropbox connector configuration is appropriate and aligns with the PR objective. The included permissions cover the necessary access for file metadata, content, team data, and member information.


2738-2738: Good catch!

Updating the apiUrl to use a specific versioned endpoint (https://api.dropboxapi.com/2) is a positive change. It ensures the integration leverages a stable and feature-rich version of the Dropbox API.


2743-2743: Connector activated!

Updating the active property to true for the Dropbox connector is a crucial step in enabling the integration. This change aligns perfectly with the PR objective of integrating Dropbox functionality into the file storage vertical.

Comment on lines +31 to +32
ONEDRIVE = 'onedrive'
SHAREPOINT = 'sharepoint',
Copy link
Contributor

Choose a reason for hiding this comment

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

Add a missing comma after ONEDRIVE.

The static analysis tool has correctly flagged a missing comma after the ONEDRIVE entry on line 31. Each enum entry should be separated by a comma.

Apply this diff to fix the missing comma:

-    ONEDRIVE = 'onedrive'
+    ONEDRIVE = 'onedrive',
     SHAREPOINT = 'sharepoint',
Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
ONEDRIVE = 'onedrive'
SHAREPOINT = 'sharepoint',
ONEDRIVE = 'onedrive',
SHAREPOINT = 'sharepoint',
Tools
Biome

[error] 32-32: expected , but instead found SHAREPOINT

Remove SHAREPOINT

(parse)

@naelob naelob merged commit cd1b728 into panoratech:main Sep 13, 2024
3 of 13 checks passed
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.

feat: Add integration with: Dropbox
3 participants