Skip to content

Add Import CSV and Export CSV Permissions #13421

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

Merged
merged 13 commits into from
Jul 25, 2025

Conversation

abdulrahmancodes
Copy link
Contributor

No description provided.

- Introduced new permission flags for importing and exporting CSV files in the PermissionFlagType enum.
- Updated relevant components to check for these permissions before rendering export/import actions.
- Enhanced the SettingsRolePermissionsToolSection to include options for managing CSV permissions.

This change improves the role-based access control for CSV operations in the application.
@abdulrahmancodes abdulrahmancodes self-assigned this Jul 24, 2025
Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

Greptile Summary

This PR implements granular permission controls for CSV import and export functionality across the Twenty CRM application. The changes add two new permission flags (IMPORT_CSV and EXPORT_CSV) to the existing role-based permission system, allowing administrators to control which users can import data from CSV files or export data to CSV files.

The implementation follows the established permissions architecture by:

  • Adding the new permission flags to the backend constants and services with secure defaults (disabled by default)
  • Updating the frontend GraphQL generated types to include the new permission flags
  • Integrating permission checks into existing action components using the useHasSettingsPermission hook
  • Adding UI configuration for these permissions in the settings panel under the "Actions" section

The changes affect multiple layers of the application: the backend permission service sets secure defaults, the frontend action components (ExportMultipleRecordsAction, ExportSingleRecordAction, ImportRecordsNoSelectionRecordAction) now conditionally render based on user permissions, and the settings UI allows administrators to configure these permissions per role. This follows the principle of least privilege by defaulting new permissions to false and requiring explicit granting of access.

Confidence score: 5/5

  • This PR is extremely safe to merge with minimal risk of production issues
  • The implementation follows established patterns consistently across all modified files and maintains backward compatibility
  • No files need additional attention as the changes are straightforward permission additions with proper security defaults

8 files reviewed, 1 comment

Edit Code Review Bot Settings | Greptile

Copy link
Contributor

github-actions bot commented Jul 24, 2025

📊 API Changes Report

GraphQL Schema Changes

GraphQL Schema Changes

[log]
Detected the following changes (4) between schemas:

[log] ✖ Field settingsPermissions was removed from object type UserWorkspace
[log] ⚠ Enum value EXPORT_CSV was added to enum PermissionFlagType
[log] ⚠ Enum value IMPORT_CSV was added to enum PermissionFlagType
[log] ✔ Field permissionFlags was added to object type UserWorkspace
[error] Detected 1 breaking change
⚠️ Breaking changes or errors detected in GraphQL schema

[log] 
Detected the following changes (4) between schemas:

[log] ✖  Field settingsPermissions was removed from object type UserWorkspace
[log] ⚠  Enum value EXPORT_CSV was added to enum PermissionFlagType
[log] ⚠  Enum value IMPORT_CSV was added to enum PermissionFlagType
[log] ✔  Field permissionFlags was added to object type UserWorkspace
[error] Detected 1 breaking change
Error generating diff

GraphQL Metadata Schema Changes

GraphQL Metadata Schema Changes

[log]
Detected the following changes (4) between schemas:

[log] ✖ Field settingsPermissions was removed from object type UserWorkspace
[log] ⚠ Enum value EXPORT_CSV was added to enum PermissionFlagType
[log] ⚠ Enum value IMPORT_CSV was added to enum PermissionFlagType
[log] ✔ Field permissionFlags was added to object type UserWorkspace
[error] Detected 1 breaking change
⚠️ Breaking changes or errors detected in GraphQL metadata schema

[log] 
Detected the following changes (4) between schemas:

[log] ✖  Field settingsPermissions was removed from object type UserWorkspace
[log] ⚠  Enum value EXPORT_CSV was added to enum PermissionFlagType
[log] ⚠  Enum value IMPORT_CSV was added to enum PermissionFlagType
[log] ✔  Field permissionFlags was added to object type UserWorkspace
[error] Detected 1 breaking change
Error generating diff

REST Metadata API Analysis Error

⚠️ Error occurred while analyzing REST Metadata API changes

Error Output

[main] ERROR i.s.v.p.reference.ReferenceVisitor - Error resolving schema #/components/schemas/WebhookForResponse
java.lang.RuntimeException: Could not find /components/schemas/WebhookForResponse in contents of #/components/schemas/WebhookForResponse
	at io.swagger.v3.parser.reference.ReferenceVisitor.resolveSchemaRef(ReferenceVisitor.java:253)
	at io.swagger.v3.parser.reference.ReferenceVisitor.visitSchema(ReferenceVisitor.java:141)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverseSchema(OpenAPI31Traverser.java:801)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverseSchema(OpenAPI31Traverser.java:867)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverseSchemaMap(OpenAPI31Traverser.java:960)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverseSchema(OpenAPI31Traverser.java:811)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverseSchemaMap(OpenAPI31Traverser.java:960)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverseSchema(OpenAPI31Traverser.java:811)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverseMediaType(OpenAPI31Traverser.java:603)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverseMap(OpenAPI31Traverser.java:947)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverseResponse(OpenAPI31Traverser.java:299)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverseMap(OpenAPI31Traverser.java:947)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverseResponses(OpenAPI31Traverser.java:270)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverseOperation(OpenAPI31Traverser.java:237)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traversePathItem(OpenAPI31Traverser.java:394)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverseMap(OpenAPI31Traverser.java:947)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traversePaths(OpenAPI31Traverser.java:197)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverseOpenApi(OpenAPI31Traverser.java:124)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverse(OpenAPI31Traverser.java:65)
	at io.swagger.v3.parser.reference.OpenAPIDereferencer31.dereference(OpenAPIDereferencer31.java:74)
	at io.swagger.v3.parser.OpenAPIV3Parser.resolve(OpenAPIV3Parser.java:227)
	at io.swagger.v3.parser.OpenAPIV3Parser.readContents(OpenAPIV3Parser.java:183)
	at io.swagger.v3.parser.OpenAPIV3Parser.readLocation(OpenAPIV3Parser.java:97)
	at io.swagger.parser.OpenAPIParser.readLocation(OpenAPIParser.java:16)
	at org.openapitools.openapidiff.core.OpenApiCompare.readLocation(OpenApiCompare.java:181)
	at org.openapitools.openapidiff.core.OpenApiCompare.fromLocations(OpenApiCompare.java:142)
	at org.openapitools.openapidiff.cli.Main.main(Main.java:233)
[main] ERROR i.s.v.p.reference.ReferenceVisitor - Error resolving schema #/components/schemas/Webhook
java.lang.RuntimeException: Could not find /components/schemas/Webhook in contents of #/components/schemas/Webhook
	at io.swagger.v3.parser.reference.ReferenceVisitor.resolveSchemaRef(ReferenceVisitor.java:253)
	at io.swagger.v3.parser.reference.ReferenceVisitor.visitSchema(ReferenceVisitor.java:141)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverseSchema(OpenAPI31Traverser.java:801)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverseMediaType(OpenAPI31Traverser.java:603)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverseMap(OpenAPI31Traverser.java:947)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverseRequestBody(OpenAPI31Traverser.java:346)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverseOperation(OpenAPI31Traverser.java:229)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traversePathItem(OpenAPI31Traverser.java:424)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverseMap(OpenAPI31Traverser.java:947)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traversePaths(OpenAPI31Traverser.java:197)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverseOpenApi(OpenAPI31Traverser.java:124)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverse(OpenAPI31Traverser.java:65)
	at io.swagger.v3.parser.reference.OpenAPIDereferencer31.dereference(OpenAPIDereferencer31.java:74)
	at io.swagger.v3.parser.OpenAPIV3Parser.resolve(OpenAPIV3Parser.java:227)
	at io.swagger.v3.parser.OpenAPIV3Parser.readContents(OpenAPIV3Parser.java:183)
	at io.swagger.v3.parser.OpenAPIV3Parser.readLocation(OpenAPIV3Parser.java:97)
	at io.swagger.parser.OpenAPIParser.readLocation(OpenAPIParser.java:16)
	at org.openapitools.openapidiff.core.OpenApiCompare.readLocation(OpenApiCompare.java:181)
	at org.openapitools.openapidiff.core.OpenApiCompare.fromLocations(OpenApiCompare.java:142)
	at org.openapitools.openapidiff.cli.Main.main(Main.java:233)
[main] ERROR i.s.v.p.reference.ReferenceVisitor - Error resolving schema #/components/schemas/WebhookForUpdate
java.lang.RuntimeException: Could not find /components/schemas/WebhookForUpdate in contents of #/components/schemas/WebhookForUpdate
	at io.swagger.v3.parser.reference.ReferenceVisitor.resolveSchemaRef(ReferenceVisitor.java:253)
	at io.swagger.v3.parser.reference.ReferenceVisitor.visitSchema(ReferenceVisitor.java:141)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverseSchema(OpenAPI31Traverser.java:801)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverseMediaType(OpenAPI31Traverser.java:603)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverseMap(OpenAPI31Traverser.java:947)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverseRequestBody(OpenAPI31Traverser.java:346)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverseOperation(OpenAPI31Traverser.java:229)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traversePathItem(OpenAPI31Traverser.java:409)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverseMap(OpenAPI31Traverser.java:947)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traversePaths(OpenAPI31Traverser.java:197)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverseOpenApi(OpenAPI31Traverser.java:124)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverse(OpenAPI31Traverser.java:65)
	at io.swagger.v3.parser.reference.OpenAPIDereferencer31.dereference(OpenAPIDereferencer31.java:74)
	at io.swagger.v3.parser.OpenAPIV3Parser.resolve(OpenAPIV3Parser.java:227)
	at io.swagger.v3.parser.OpenAPIV3Parser.readContents(OpenAPIV3Parser.java:183)
	at io.swagger.v3.parser.OpenAPIV3Parser.readLocation(OpenAPIV3Parser.java:97)
	at io.swagger.parser.OpenAPIParser.readLocation(OpenAPIParser.java:16)
	at org.openapitools.openapidiff.core.OpenApiCompare.readLocation(OpenApiCompare.java:181)
	at org.openapitools.openapidiff.core.OpenApiCompare.fromLocations(OpenApiCompare.java:142)
	at org.openapitools.openapidiff.cli.Main.main(Main.java:233)
[main] ERROR i.s.v.p.reference.ReferenceVisitor - Error resolving schema #/components/schemas/ApikeyForResponse
java.lang.RuntimeException: Could not find /components/schemas/ApikeyForResponse in contents of #/components/schemas/ApikeyForResponse
	at io.swagger.v3.parser.reference.ReferenceVisitor.resolveSchemaRef(ReferenceVisitor.java:253)
	at io.swagger.v3.parser.reference.ReferenceVisitor.visitSchema(ReferenceVisitor.java:141)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverseSchema(OpenAPI31Traverser.java:801)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverseSchema(OpenAPI31Traverser.java:867)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverseSchemaMap(OpenAPI31Traverser.java:960)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverseSchema(OpenAPI31Traverser.java:811)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverseSchemaMap(OpenAPI31Traverser.java:960)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverseSchema(OpenAPI31Traverser.java:811)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverseMediaType(OpenAPI31Traverser.java:603)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverseMap(OpenAPI31Traverser.java:947)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverseResponse(OpenAPI31Traverser.java:299)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverseMap(OpenAPI31Traverser.java:947)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverseResponses(OpenAPI31Traverser.java:270)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverseOperation(OpenAPI31Traverser.java:237)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traversePathItem(OpenAPI31Traverser.java:394)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverseMap(OpenAPI31Traverser.java:947)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traversePaths(OpenAPI31Traverser.java:197)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverseOpenApi(OpenAPI31Traverser.java:124)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverse(OpenAPI31Traverser.java:65)
	at io.swagger.v3.parser.reference.OpenAPIDereferencer31.dereference(OpenAPIDereferencer31.java:74)
	at io.swagger.v3.parser.OpenAPIV3Parser.resolve(OpenAPIV3Parser.java:227)
	at io.swagger.v3.parser.OpenAPIV3Parser.readContents(OpenAPIV3Parser.java:183)
	at io.swagger.v3.parser.OpenAPIV3Parser.readLocation(OpenAPIV3Parser.java:97)
	at io.swagger.parser.OpenAPIParser.readLocation(OpenAPIParser.java:16)
	at org.openapitools.openapidiff.core.OpenApiCompare.readLocation(OpenApiCompare.java:181)
	at org.openapitools.openapidiff.core.OpenApiCompare.fromLocations(OpenApiCompare.java:142)
	at org.openapitools.openapidiff.cli.Main.main(Main.java:233)
[main] ERROR i.s.v.p.reference.ReferenceVisitor - Error resolving schema #/components/schemas/Apikey
java.lang.RuntimeException: Could not find /components/schemas/Apikey in contents of #/components/schemas/Apikey
	at io.swagger.v3.parser.reference.ReferenceVisitor.resolveSchemaRef(ReferenceVisitor.java:253)
	at io.swagger.v3.parser.reference.ReferenceVisitor.visitSchema(ReferenceVisitor.java:141)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverseSchema(OpenAPI31Traverser.java:801)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverseMediaType(OpenAPI31Traverser.java:603)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverseMap(OpenAPI31Traverser.java:947)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverseRequestBody(OpenAPI31Traverser.java:346)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverseOperation(OpenAPI31Traverser.java:229)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traversePathItem(OpenAPI31Traverser.java:424)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverseMap(OpenAPI31Traverser.java:947)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traversePaths(OpenAPI31Traverser.java:197)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverseOpenApi(OpenAPI31Traverser.java:124)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverse(OpenAPI31Traverser.java:65)
	at io.swagger.v3.parser.reference.OpenAPIDereferencer31.dereference(OpenAPIDereferencer31.java:74)
	at io.swagger.v3.parser.OpenAPIV3Parser.resolve(OpenAPIV3Parser.java:227)
	at io.swagger.v3.parser.OpenAPIV3Parser.readContents(OpenAPIV3Parser.java:183)
	at io.swagger.v3.parser.OpenAPIV3Parser.readLocation(OpenAPIV3Parser.java:97)
	at io.swagger.parser.OpenAPIParser.readLocation(OpenAPIParser.java:16)
	at org.openapitools.openapidiff.core.OpenApiCompare.readLocation(OpenApiCompare.java:181)
	at org.openapitools.openapidiff.core.OpenApiCompare.fromLocations(OpenApiCompare.java:142)
	at org.openapitools.openapidiff.cli.Main.main(Main.java:233)
[main] ERROR i.s.v.p.reference.ReferenceVisitor - Error resolving schema #/components/schemas/ApikeyForUpdate
java.lang.RuntimeException: Could not find /components/schemas/ApikeyForUpdate in contents of #/components/schemas/ApikeyForUpdate
	at io.swagger.v3.parser.reference.ReferenceVisitor.resolveSchemaRef(ReferenceVisitor.java:253)
	at io.swagger.v3.parser.reference.ReferenceVisitor.visitSchema(ReferenceVisitor.java:141)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverseSchema(OpenAPI31Traverser.java:801)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverseMediaType(OpenAPI31Traverser.java:603)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverseMap(OpenAPI31Traverser.java:947)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverseRequestBody(OpenAPI31Traverser.java:346)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverseOperation(OpenAPI31Traverser.java:229)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traversePathItem(OpenAPI31Traverser.java:409)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverseMap(OpenAPI31Traverser.java:947)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traversePaths(OpenAPI31Traverser.java:197)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverseOpenApi(OpenAPI31Traverser.java:124)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverse(OpenAPI31Traverser.java:65)
	at io.swagger.v3.parser.reference.OpenAPIDereferencer31.dereference(OpenAPIDereferencer31.java:74)
	at io.swagger.v3.parser.OpenAPIV3Parser.resolve(OpenAPIV3Parser.java:227)
	at io.swagger.v3.parser.OpenAPIV3Parser.readContents(OpenAPIV3Parser.java:183)
	at io.swagger.v3.parser.OpenAPIV3Parser.readLocation(OpenAPIV3Parser.java:97)
	at io.swagger.parser.OpenAPIParser.readLocation(OpenAPIParser.java:16)
	at org.openapitools.openapidiff.core.OpenApiCompare.readLocation(OpenApiCompare.java:181)
	at org.openapitools.openapidiff.core.OpenApiCompare.fromLocations(OpenApiCompare.java:142)
	at org.openapitools.openapidiff.cli.Main.main(Main.java:233)
[main] ERROR i.s.v.p.reference.ReferenceVisitor - Error resolving schema #/components/schemas/WebhookForResponse
java.lang.RuntimeException: Could not find /components/schemas/WebhookForResponse in contents of #/components/schemas/WebhookForResponse
	at io.swagger.v3.parser.reference.ReferenceVisitor.resolveSchemaRef(ReferenceVisitor.java:253)
	at io.swagger.v3.parser.reference.ReferenceVisitor.visitSchema(ReferenceVisitor.java:141)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverseSchema(OpenAPI31Traverser.java:801)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverseSchema(OpenAPI31Traverser.java:867)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverseSchemaMap(OpenAPI31Traverser.java:960)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverseSchema(OpenAPI31Traverser.java:811)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverseSchemaMap(OpenAPI31Traverser.java:960)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverseSchema(OpenAPI31Traverser.java:811)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverseMediaType(OpenAPI31Traverser.java:603)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverseMap(OpenAPI31Traverser.java:947)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverseResponse(OpenAPI31Traverser.java:299)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverseMap(OpenAPI31Traverser.java:947)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverseResponses(OpenAPI31Traverser.java:270)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverseOperation(OpenAPI31Traverser.java:237)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traversePathItem(OpenAPI31Traverser.java:394)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverseMap(OpenAPI31Traverser.java:947)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traversePaths(OpenAPI31Traverser.java:197)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverseOpenApi(OpenAPI31Traverser.java:124)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverse(OpenAPI31Traverser.java:65)
	at io.swagger.v3.parser.reference.OpenAPIDereferencer31.dereference(OpenAPIDereferencer31.java:74)
	at io.swagger.v3.parser.OpenAPIV3Parser.resolve(OpenAPIV3Parser.java:227)
	at io.swagger.v3.parser.OpenAPIV3Parser.readContents(OpenAPIV3Parser.java:183)
	at io.swagger.v3.parser.OpenAPIV3Parser.readLocation(OpenAPIV3Parser.java:97)
	at io.swagger.parser.OpenAPIParser.readLocation(OpenAPIParser.java:16)
	at org.openapitools.openapidiff.core.OpenApiCompare.readLocation(OpenApiCompare.java:181)
	at org.openapitools.openapidiff.core.OpenApiCompare.fromLocations(OpenApiCompare.java:142)
	at org.openapitools.openapidiff.cli.Main.main(Main.java:233)
[main] ERROR i.s.v.p.reference.ReferenceVisitor - Error resolving schema #/components/schemas/Webhook
java.lang.RuntimeException: Could not find /components/schemas/Webhook in contents of #/components/schemas/Webhook
	at io.swagger.v3.parser.reference.ReferenceVisitor.resolveSchemaRef(ReferenceVisitor.java:253)
	at io.swagger.v3.parser.reference.ReferenceVisitor.visitSchema(ReferenceVisitor.java:141)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverseSchema(OpenAPI31Traverser.java:801)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverseMediaType(OpenAPI31Traverser.java:603)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverseMap(OpenAPI31Traverser.java:947)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverseRequestBody(OpenAPI31Traverser.java:346)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverseOperation(OpenAPI31Traverser.java:229)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traversePathItem(OpenAPI31Traverser.java:424)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverseMap(OpenAPI31Traverser.java:947)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traversePaths(OpenAPI31Traverser.java:197)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverseOpenApi(OpenAPI31Traverser.java:124)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverse(OpenAPI31Traverser.java:65)
	at io.swagger.v3.parser.reference.OpenAPIDereferencer31.dereference(OpenAPIDereferencer31.java:74)
	at io.swagger.v3.parser.OpenAPIV3Parser.resolve(OpenAPIV3Parser.java:227)
	at io.swagger.v3.parser.OpenAPIV3Parser.readContents(OpenAPIV3Parser.java:183)
	at io.swagger.v3.parser.OpenAPIV3Parser.readLocation(OpenAPIV3Parser.java:97)
	at io.swagger.parser.OpenAPIParser.readLocation(OpenAPIParser.java:16)
	at org.openapitools.openapidiff.core.OpenApiCompare.readLocation(OpenApiCompare.java:181)
	at org.openapitools.openapidiff.core.OpenApiCompare.fromLocations(OpenApiCompare.java:142)
	at org.openapitools.openapidiff.cli.Main.main(Main.java:233)
[main] ERROR i.s.v.p.reference.ReferenceVisitor - Error resolving schema #/components/schemas/WebhookForUpdate
java.lang.RuntimeException: Could not find /components/schemas/WebhookForUpdate in contents of #/components/schemas/WebhookForUpdate
	at io.swagger.v3.parser.reference.ReferenceVisitor.resolveSchemaRef(ReferenceVisitor.java:253)
	at io.swagger.v3.parser.reference.ReferenceVisitor.visitSchema(ReferenceVisitor.java:141)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverseSchema(OpenAPI31Traverser.java:801)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverseMediaType(OpenAPI31Traverser.java:603)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverseMap(OpenAPI31Traverser.java:947)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverseRequestBody(OpenAPI31Traverser.java:346)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverseOperation(OpenAPI31Traverser.java:229)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traversePathItem(OpenAPI31Traverser.java:409)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverseMap(OpenAPI31Traverser.java:947)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traversePaths(OpenAPI31Traverser.java:197)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverseOpenApi(OpenAPI31Traverser.java:124)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverse(OpenAPI31Traverser.java:65)
	at io.swagger.v3.parser.reference.OpenAPIDereferencer31.dereference(OpenAPIDereferencer31.java:74)
	at io.swagger.v3.parser.OpenAPIV3Parser.resolve(OpenAPIV3Parser.java:227)
	at io.swagger.v3.parser.OpenAPIV3Parser.readContents(OpenAPIV3Parser.java:183)
	at io.swagger.v3.parser.OpenAPIV3Parser.readLocation(OpenAPIV3Parser.java:97)
	at io.swagger.parser.OpenAPIParser.readLocation(OpenAPIParser.java:16)
	at org.openapitools.openapidiff.core.OpenApiCompare.readLocation(OpenApiCompare.java:181)
	at org.openapitools.openapidiff.core.OpenApiCompare.fromLocations(OpenApiCompare.java:142)
	at org.openapitools.openapidiff.cli.Main.main(Main.java:233)
[main] ERROR i.s.v.p.reference.ReferenceVisitor - Error resolving schema #/components/schemas/ApikeyForResponse
java.lang.RuntimeException: Could not find /components/schemas/ApikeyForResponse in contents of #/components/schemas/ApikeyForResponse
	at io.swagger.v3.parser.reference.ReferenceVisitor.resolveSchemaRef(ReferenceVisitor.java:253)
	at io.swagger.v3.parser.reference.ReferenceVisitor.visitSchema(ReferenceVisitor.java:141)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverseSchema(OpenAPI31Traverser.java:801)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverseSchema(OpenAPI31Traverser.java:867)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverseSchemaMap(OpenAPI31Traverser.java:960)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverseSchema(OpenAPI31Traverser.java:811)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverseSchemaMap(OpenAPI31Traverser.java:960)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverseSchema(OpenAPI31Traverser.java:811)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverseMediaType(OpenAPI31Traverser.java:603)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverseMap(OpenAPI31Traverser.java:947)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverseResponse(OpenAPI31Traverser.java:299)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverseMap(OpenAPI31Traverser.java:947)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverseResponses(OpenAPI31Traverser.java:270)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverseOperation(OpenAPI31Traverser.java:237)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traversePathItem(OpenAPI31Traverser.java:394)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverseMap(OpenAPI31Traverser.java:947)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traversePaths(OpenAPI31Traverser.java:197)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverseOpenApi(OpenAPI31Traverser.java:124)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverse(OpenAPI31Traverser.java:65)
	at io.swagger.v3.parser.reference.OpenAPIDereferencer31.dereference(OpenAPIDereferencer31.java:74)
	at io.swagger.v3.parser.OpenAPIV3Parser.resolve(OpenAPIV3Parser.java:227)
	at io.swagger.v3.parser.OpenAPIV3Parser.readContents(OpenAPIV3Parser.java:183)
	at io.swagger.v3.parser.OpenAPIV3Parser.readLocation(OpenAPIV3Parser.java:97)
	at io.swagger.parser.OpenAPIParser.readLocation(OpenAPIParser.java:16)
	at org.openapitools.openapidiff.core.OpenApiCompare.readLocation(OpenApiCompare.java:181)
	at org.openapitools.openapidiff.core.OpenApiCompare.fromLocations(OpenApiCompare.java:142)
	at org.openapitools.openapidiff.cli.Main.main(Main.java:233)
[main] ERROR i.s.v.p.reference.ReferenceVisitor - Error resolving schema #/components/schemas/Apikey
java.lang.RuntimeException: Could not find /components/schemas/Apikey in contents of #/components/schemas/Apikey
	at io.swagger.v3.parser.reference.ReferenceVisitor.resolveSchemaRef(ReferenceVisitor.java:253)
	at io.swagger.v3.parser.reference.ReferenceVisitor.visitSchema(ReferenceVisitor.java:141)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverseSchema(OpenAPI31Traverser.java:801)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverseMediaType(OpenAPI31Traverser.java:603)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverseMap(OpenAPI31Traverser.java:947)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverseRequestBody(OpenAPI31Traverser.java:346)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverseOperation(OpenAPI31Traverser.java:229)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traversePathItem(OpenAPI31Traverser.java:424)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverseMap(OpenAPI31Traverser.java:947)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traversePaths(OpenAPI31Traverser.java:197)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverseOpenApi(OpenAPI31Traverser.java:124)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverse(OpenAPI31Traverser.java:65)
	at io.swagger.v3.parser.reference.OpenAPIDereferencer31.dereference(OpenAPIDereferencer31.java:74)
	at io.swagger.v3.parser.OpenAPIV3Parser.resolve(OpenAPIV3Parser.java:227)
	at io.swagger.v3.parser.OpenAPIV3Parser.readContents(OpenAPIV3Parser.java:183)
	at io.swagger.v3.parser.OpenAPIV3Parser.readLocation(OpenAPIV3Parser.java:97)
	at io.swagger.parser.OpenAPIParser.readLocation(OpenAPIParser.java:16)
	at org.openapitools.openapidiff.core.OpenApiCompare.readLocation(OpenApiCompare.java:181)
	at org.openapitools.openapidiff.core.OpenApiCompare.fromLocations(OpenApiCompare.java:142)
	at org.openapitools.openapidiff.cli.Main.main(Main.java:233)
[main] ERROR i.s.v.p.reference.ReferenceVisitor - Error resolving schema #/components/schemas/ApikeyForUpdate
java.lang.RuntimeException: Could not find /components/schemas/ApikeyForUpdate in contents of #/components/schemas/ApikeyForUpdate
	at io.swagger.v3.parser.reference.ReferenceVisitor.resolveSchemaRef(ReferenceVisitor.java:253)
	at io.swagger.v3.parser.reference.ReferenceVisitor.visitSchema(ReferenceVisitor.java:141)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverseSchema(OpenAPI31Traverser.java:801)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverseMediaType(OpenAPI31Traverser.java:603)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverseMap(OpenAPI31Traverser.java:947)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverseRequestBody(OpenAPI31Traverser.java:346)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverseOperation(OpenAPI31Traverser.java:229)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traversePathItem(OpenAPI31Traverser.java:409)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverseMap(OpenAPI31Traverser.java:947)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traversePaths(OpenAPI31Traverser.java:197)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverseOpenApi(OpenAPI31Traverser.java:124)
	at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverse(OpenAPI31Traverser.java:65)
	at io.swagger.v3.parser.reference.OpenAPIDereferencer31.dereference(OpenAPIDereferencer31.java:74)
	at io.swagger.v3.parser.OpenAPIV3Parser.resolve(OpenAPIV3Parser.java:227)
	at io.swagger.v3.parser.OpenAPIV3Parser.readContents(OpenAPIV3Parser.java:183)
	at io.swagger.v3.parser.OpenAPIV3Parser.readLocation(OpenAPIV3Parser.java:97)
	at io.swagger.parser.OpenAPIParser.readLocation(OpenAPIParser.java:16)
	at org.openapitools.openapidiff.core.OpenApiCompare.readLocation(OpenApiCompare.java:181)
	at org.openapitools.openapidiff.core.OpenApiCompare.fromLocations(OpenApiCompare.java:142)
	at org.openapitools.openapidiff.cli.Main.main(Main.java:233)

⚠️ Please review these API changes carefully before merging.

⚠️ Breaking Change Protocol

Breaking changes detected but PR title does not contain "breaking" - CI will pass but action needed.

🔄 Options:

  1. If this IS a breaking change: Add "breaking" to your PR title and add BREAKING CHANGE: to your commit message
  2. If this is NOT a breaking change: The API diff tool may have false positives - please review carefully

For breaking changes, add to commit message:

feat: add new API endpoint

BREAKING CHANGE: removed deprecated field from User schema

Copy link
Contributor

github-actions bot commented Jul 24, 2025

🚀 Preview Environment Ready!

Your preview environment is available at: http://bore.pub:36648

This environment will automatically shut down when the PR is closed or after 5 hours.

- Introduced a new constants file for tool permission flags, including 'SEND_EMAIL_TOOL', 'IMPORT_CSV', and 'EXPORT_CSV'.
- Updated the PermissionsService to incorporate tool permissions, allowing for more granular access control based on the new flags.
- Refactored permission checking logic to utilize the new tool permission flags, improving the overall role-based access control system.
- Added `requiredPermissionFlag` to action configurations for CSV import and export actions.
- Updated `useRegisteredActions` hook to filter actions based on the new permission flags.
- Imported `PermissionFlagType` to manage permissions effectively.

This change improves role-based access control for CSV operations in the action menu.
…with `useHasPermissionFlag` in relevant components

- Updated `useRecordGroupActions` and `SettingsProtectedRouteWrapper` to utilize the new permission hook.
- Introduced `useHasPermissionFlag` to centralize permission checks based on permission flags, enhancing role-based access control.
Copy link
Member

@FelixMalfait FelixMalfait left a comment

Choose a reason for hiding this comment

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

Great!

@FelixMalfait FelixMalfait merged commit 4b95de6 into main Jul 25, 2025
57 checks passed
@FelixMalfait FelixMalfait deleted the add-csv-import-export-permissions branch July 25, 2025 06:07
Copy link
Contributor

Thanks @abdulrahmancodes for your contribution!
This marks your 37th PR on the repo. You're top 2% of all our contributors 🎉
See contributor page - Share on LinkedIn - Share on Twitter

Contributions

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants