Skip to content

Conversation

sean-brydon
Copy link
Member

@sean-brydon sean-brydon commented Jul 31, 2025

feat: add Workflow resource to PBAC system with permission enforcement

Video Demo: https://cap.so/s/zn4pka3ta4yra7x

Summary

This PR adds the missing Workflow resource to the PBAC (Permission-Based Access Control) system and enforces permissions when creating/updating workflows on team events. The implementation follows the established patterns used by other resources like EventType and Team.

Key Changes:

  • Added Workflow to the Resource enum and complete CRUD permissions to PERMISSION_REGISTRY
  • Created database migration to grant workflow manage permissions to admin role
  • Updated workflow create/update tRPC handlers to use PBAC permission checking instead of basic team membership
  • Added i18n keys for workflow permission descriptions
  • Uses fallback roles (ADMIN, OWNER) when PBAC is disabled to maintain backward compatibility

Review & Testing Checklist for Human

⚠️ HIGH PRIORITY - Authorization Logic Change

  • Test workflow creation with different user roles: Verify members are blocked while admins/owners can create workflows
  • Test workflow updates with different user roles: Ensure only authorized users can modify existing workflows
  • Verify migration runs successfully: Apply the migration on a test database to ensure it doesn't fail
  • Test PBAC enabled vs disabled modes: Verify fallback behavior matches previous authorization logic when PBAC is disabled
  • Check existing workflows remain accessible: Ensure current workflows aren't broken by the permission changes

Recommended Test Plan:

  1. Set up test teams with users in different roles (member, admin, owner)
  2. Attempt to create workflows as each role type and verify expected access patterns
  3. Test updating existing workflows with different user permissions
  4. Verify the workflow permissions appear correctly in the PBAC UI
  5. Test with PBAC feature flag both enabled and disabled

Diagram

%%{ init : { "theme" : "default" }}%%
graph TD
    A["permission-registry.ts<br/>Resource enum + PERMISSION_REGISTRY"]:::major-edit
    B["create.handler.ts<br/>Workflow creation tRPC endpoint"]:::major-edit  
    C["update.handler.ts<br/>Workflow update tRPC endpoint"]:::major-edit
    D["migration.sql<br/>Add admin workflow permissions"]:::major-edit
    E["common.json<br/>i18n keys for workflow permissions"]:::minor-edit
    F["PermissionCheckService"]:::context
    G["Database<br/>RolePermission table"]:::context
    
    A -->|"defines workflow permissions"| F
    F -->|"checkPermission('workflow.create')"| B
    F -->|"checkPermission('workflow.update')"| C
    D -->|"INSERT workflow manage permissions"| G
    F -->|"queries role permissions"| G
    A -->|"references i18n keys"| E
    
    subgraph Legend
        L1[Major Edit]:::major-edit
        L2[Minor Edit]:::minor-edit  
        L3[Context/No Edit]:::context
    end

classDef major-edit fill:#90EE90
classDef minor-edit fill:#87CEEB  
classDef context fill:#FFFFFF
Loading

Notes

  • Session Info: Requested by @sean-brydon, Devin session: https://app.devin.ai/sessions/880c3b99dda049d3b532c4c1dccbf614
  • Migration Dependency: The migration assumes 'admin_role' exists in the database - verify this matches your role structure
  • Backward Compatibility: Fallback roles [ADMIN, OWNER] should maintain the same access patterns as the previous team membership checks that excluded MEMBER roles
  • PBAC Feature Flag: This change works with both PBAC enabled and disabled modes, but thorough testing of both scenarios is recommended
  • Type Safety: All changes passed yarn type-check:ci and lint checks, but runtime behavior needs verification

- Add Workflow to Resource enum in permission-registry.ts
- Add complete workflow CRUD permissions to PERMISSION_REGISTRY
- Create migration to add workflow manage permissions to admin role
- Update workflow create/update handlers to use PBAC permission checks
- Add i18n keys for workflow permission descriptions
- Enforce workflow.create permission for team workflow creation
- Use fallback roles (ADMIN, OWNER) when PBAC is disabled

Fixes workflow creation authorization for team events using PBAC

Co-Authored-By: sean@cal.com <Sean@brydon.io>
Copy link
Contributor

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR that start with 'DevinAI'.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment and CI monitoring

Copy link
Contributor

coderabbitai bot commented Jul 31, 2025

Walkthrough

This set of changes introduces a comprehensive permission system for workflow-related resources. It adds workflow-specific permission keys and descriptions to the English localization file and extends the permission registry to include workflows, defining standard CRUD and management actions. A new module implements logic for calculating user permissions on workflows, supporting both personal and team-based workflows, with caching and batch processing. The workflow-related TRPC handlers and UI components are updated to leverage these new permissions, replacing previous role-based checks with permission-based checks throughout. Schema and query interfaces are updated to support permission-aware filtering. Test coverage is added for the new authorization logic. Additionally, minor refactors improve permission check consistency and centralize authorization logic via the PermissionCheckService.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20–25 minutes

  • Complexity: Moderate. The changes are spread across backend, frontend, schema, and localization files. They introduce new abstractions, update data flow, and refactor logic to use a new permission model.
  • Volume: Multiple files updated and a new module added, with both logic and type/interface changes.
  • Review Scope: Requires careful review of permission logic correctness, backward compatibility, and integration points, as well as validation of new test coverage.

Possibly related PRs

  • fix: (PBAC) Add organization fallback on resources  #22733: Adds workflow-related permission keys and descriptions, integrates workflow permissions into UI components and backend permission checks, and introduces a workflow permission builder and utilities; related through permission system enhancements but focuses on different aspects than this PR.

📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between dcd1f60 and c9a4662.

📒 Files selected for processing (1)
  • apps/web/public/static/locales/en/common.json (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • apps/web/public/static/locales/en/common.json
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Install dependencies / Yarn install & cache
✨ Finishing Touches
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch devin/1753972318-add-workflows-pbac-resource

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ 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>, please review it.
    • Explain this complex logic.
    • 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 explain this code block.
  • 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 gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

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 generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai generate unit tests to generate unit tests for this 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 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.

@github-actions github-actions bot added the ❗️ migrations contains migration files label Jul 31, 2025
@keithwillcode keithwillcode added consumer core area: core, team members only labels Jul 31, 2025
…dy exist in main migration

Co-Authored-By: sean@cal.com <Sean@brydon.io>
Copy link

vercel bot commented Jul 31, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

2 Skipped Deployments
Name Status Preview Comments Updated (UTC)
cal ⬜️ Ignored (Inspect) Aug 8, 2025 8:25am
cal-eu ⬜️ Ignored (Inspect) Aug 8, 2025 8:25am

Copy link
Contributor

github-actions bot commented Jul 31, 2025

E2E results are ready!

Co-Authored-By: sean@cal.com <Sean@brydon.io>
Copy link
Member Author

Choose a reason for hiding this comment

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

Builder class to easily add permissions to a workflow from the Repository OR workflows. See usage of this here https://github.com/calcom/cal.com/pull/22845/files#diff-4ab0b5800b7c3159eb32d82ee40a61e985764f2b7fb136b06407030c9e1ecd6bR67

}

interface TeamPermissionsCache {
[teamId: string]: WorkflowPermissions;
Copy link
Member Author

Choose a reason for hiding this comment

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

Not a true cache. Just for this RUN of fetching workflows. we cache by teamId what permissions the user has access too instead of querying every time

@sean-brydon sean-brydon marked this pull request as ready for review August 6, 2025 09:04
@graphite-app graphite-app bot requested review from a team August 6, 2025 09:04
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

🧹 Nitpick comments (1)
packages/features/ee/workflows/components/WorkflowDetailsPage.tsx (1)

26-32: Consider removing duplicate interface definition.

The WorkflowPermissions interface is already defined in packages/lib/server/repository/workflow-permissions.ts (lines 4-10). Having duplicate interface definitions can lead to maintenance issues if they diverge over time.

Import the interface from the existing location:

+import type { WorkflowPermissions } from "@calcom/lib/server/repository/workflow-permissions";

-interface WorkflowPermissions {
-  canView: boolean;
-  canUpdate: boolean;
-  canDelete: boolean;
-  canManage: boolean;
-  readOnly: boolean; // Keep for backward compatibility
-}
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 52a5c70 and 86741a1.

📒 Files selected for processing (2)
  • packages/features/ee/workflows/components/WorkflowDetailsPage.tsx (3 hunks)
  • packages/features/ee/workflows/pages/workflow.tsx (6 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/features/ee/workflows/pages/workflow.tsx
🧰 Additional context used
📓 Path-based instructions (2)
**/*.tsx

📄 CodeRabbit Inference Engine (.cursor/rules/review.mdc)

Always use t() for text localization in frontend code; direct text embedding should trigger a warning

Files:

  • packages/features/ee/workflows/components/WorkflowDetailsPage.tsx
**/*.{ts,tsx}

📄 CodeRabbit Inference Engine (.cursor/rules/review.mdc)

Flag excessive Day.js use in performance-critical code; prefer native Date or Day.js .utc() in hot paths like loops

Files:

  • packages/features/ee/workflows/components/WorkflowDetailsPage.tsx
🧬 Code Graph Analysis (1)
packages/features/ee/workflows/components/WorkflowDetailsPage.tsx (1)
packages/lib/server/repository/workflow-permissions.ts (1)
  • WorkflowPermissions (5-11)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Install dependencies / Yarn install & cache
🔇 Additional comments (1)
packages/features/ee/workflows/components/WorkflowDetailsPage.tsx (1)

44-44: LGTM!

The addition of the permissions property to the Props interface correctly integrates the new permission system.

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: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 07aec7a and b23799d.

📒 Files selected for processing (2)
  • packages/features/ee/workflows/components/WorkflowDetailsPage.tsx (3 hunks)
  • packages/features/ee/workflows/pages/workflow.tsx (6 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/features/ee/workflows/pages/workflow.tsx
🧰 Additional context used
📓 Path-based instructions (2)
**/*.tsx

📄 CodeRabbit Inference Engine (.cursor/rules/review.mdc)

Always use t() for text localization in frontend code; direct text embedding should trigger a warning

Files:

  • packages/features/ee/workflows/components/WorkflowDetailsPage.tsx
**/*.{ts,tsx}

📄 CodeRabbit Inference Engine (.cursor/rules/review.mdc)

Flag excessive Day.js use in performance-critical code; prefer native Date or Day.js .utc() in hot paths like loops

Files:

  • packages/features/ee/workflows/components/WorkflowDetailsPage.tsx
🧠 Learnings (1)
📚 Learning: in the failedbookingsbyfield component (packages/features/insights/components/failedbookingsbyfield....
Learnt from: eunjae-lee
PR: calcom/cal.com#22106
File: packages/features/insights/components/FailedBookingsByField.tsx:65-71
Timestamp: 2025-07-15T12:59:34.389Z
Learning: In the FailedBookingsByField component (packages/features/insights/components/FailedBookingsByField.tsx), although routingFormId is typed as optional in useInsightsParameters, the system automatically enforces a routing form filter, so routingFormId is always present in practice. This means the data always contains only one entry, making the single-entry destructuring approach safe.

Applied to files:

  • packages/features/ee/workflows/components/WorkflowDetailsPage.tsx
🧬 Code Graph Analysis (1)
packages/features/ee/workflows/components/WorkflowDetailsPage.tsx (1)
packages/lib/server/repository/workflow-permissions.ts (1)
  • WorkflowPermissions (5-11)
🪛 Biome (2.1.2)
packages/features/ee/workflows/components/WorkflowDetailsPage.tsx

[error] 61-61: This variable is used before its declaration.

The variable is declared here:

(lint/correctness/noInvalidUseBeforeDeclaration)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Install dependencies / Yarn install & cache
🔇 Additional comments (3)
packages/features/ee/workflows/components/WorkflowDetailsPage.tsx (3)

26-32: LGTM! Well-structured permission interface.

The WorkflowPermissions interface correctly defines granular permission flags and maintains backward compatibility with the readOnly flag. This aligns well with the broader permission model being introduced across the workflows feature.


44-44: Good addition for permission-aware rendering.

The optional permissions property enables parent components to pass down computed permissions while maintaining backward compatibility through the fallback logic.


189-189: Delete button permission check is correctly implemented.

The condition properly checks permissions.canDelete to control delete button visibility, which addresses the issue mentioned in the PR comments about unauthorized delete button access.

…esQuery.handler.ts

Co-authored-by: Carina Wollendorfer <30310907+CarinaWolli@users.noreply.github.com>
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: 0

♻️ Duplicate comments (2)
packages/trpc/server/routers/loggedInViewer/teamsAndUserProfilesQuery.handler.ts (2)

95-116: Critical logic error in permission filtering.

This is the same issue identified in previous reviews. The permission result handling has a significant flaw:

Line 113 filters permissionChecks to only include true values, losing the positional correspondence with teams. This causes incorrect readOnly values in the returned data (lines 136-138).

Apply this fix to correctly handle permission results:

  // Filter teams based on permission if provided
- let hasPermissionForFiltered: boolean[] = [];
  if (input?.withPermission) {
    const permissionService = new PermissionCheckService();
    const { permission, fallbackRoles } = input.withPermission;

    const permissionChecks = await Promise.all(
      teamsData.map((membership) =>
        permissionService.checkPermission({
          userId: ctx.user.id,
          teamId: membership.team.id,
          permission: permission as PermissionString,
          fallbackRoles: fallbackRoles ? (fallbackRoles as MembershipRole[]) : [],
        })
      )
    );

-   // Store permission results for teams that passed the filter
-   hasPermissionForFiltered = permissionChecks.filter((hasPermission) => hasPermission);
    teamsData = teamsData.filter((_, index) => permissionChecks[index]);
  }

136-138: Fix readOnly logic to handle filtered teams correctly.

Since teams are now filtered based on permissions, all remaining teams have the required permission. The current logic references an incorrect index due to the filtering issue above.

Update the readOnly logic:

      readOnly: input?.withPermission
-       ? !hasPermissionForFiltered[index]
+       ? false // All remaining teams have permission since they passed the filter
        : !withRoleCanCreateEntity(membership.role),
🧹 Nitpick comments (1)
packages/trpc/server/routers/loggedInViewer/teamsAndUserProfilesQuery.handler.ts (1)

101-110: Consider performance optimization for permission checks.

The current implementation makes individual permission checks for each team. Consider batching these operations if the PermissionCheckService supports it, especially for users with many team memberships.

Check if PermissionCheckService has batch checking capabilities:

// If batch checking is available:
const permissionChecks = await permissionService.checkPermissions({
  userId: ctx.user.id,
  checks: teamsData.map(membership => ({
    teamId: membership.team.id,
    permission: permission as PermissionString,
    fallbackRoles: fallbackRoles ? (fallbackRoles as MembershipRole[]) : [],
  }))
});
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1b00abc and be805bd.

📒 Files selected for processing (1)
  • packages/trpc/server/routers/loggedInViewer/teamsAndUserProfilesQuery.handler.ts (3 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
**/*.ts

📄 CodeRabbit Inference Engine (.cursor/rules/review.mdc)

**/*.ts: For Prisma queries, only select data you need; never use include, always use select
Ensure the credential.key field is never returned from tRPC endpoints or APIs

Files:

  • packages/trpc/server/routers/loggedInViewer/teamsAndUserProfilesQuery.handler.ts
**/*.{ts,tsx}

📄 CodeRabbit Inference Engine (.cursor/rules/review.mdc)

Flag excessive Day.js use in performance-critical code; prefer native Date or Day.js .utc() in hot paths like loops

Files:

  • packages/trpc/server/routers/loggedInViewer/teamsAndUserProfilesQuery.handler.ts
🧠 Learnings (6)
📚 Learning: in signup-view.tsx, when checking if redirecturl contains certain strings, using explicit && checks ...
Learnt from: Anshumancanrock
PR: calcom/cal.com#22570
File: apps/web/modules/signup-view.tsx:253-253
Timestamp: 2025-07-21T21:33:23.371Z
Learning: In signup-view.tsx, when checking if redirectUrl contains certain strings, using explicit && checks (redirectUrl && redirectUrl.includes()) is preferred over optional chaining (redirectUrl?.includes()) to ensure the result is always a boolean rather than potentially undefined. This approach provides cleaner boolean contracts for downstream conditional logic.

Applied to files:

  • packages/trpc/server/routers/loggedInViewer/teamsAndUserProfilesQuery.handler.ts
📚 Learning: applies to **/*.ts : ensure the `credential.key` field is never returned from trpc endpoints or apis...
Learnt from: CR
PR: calcom/cal.com#0
File: .cursor/rules/review.mdc:0-0
Timestamp: 2025-07-28T11:50:23.946Z
Learning: Applies to **/*.ts : Ensure the `credential.key` field is never returned from tRPC endpoints or APIs

Applied to files:

  • packages/trpc/server/routers/loggedInViewer/teamsAndUserProfilesQuery.handler.ts
📚 Learning: the filterhostsbysameroundrobinhost function in packages/lib/bookings/filterhostsbysameroundrobinhos...
Learnt from: CarinaWolli
PR: calcom/cal.com#22296
File: packages/lib/bookings/filterHostsBySameRoundRobinHost.ts:41-42
Timestamp: 2025-07-22T11:42:47.623Z
Learning: The filterHostsBySameRoundRobinHost function in packages/lib/bookings/filterHostsBySameRoundRobinHost.ts has a known limitation where it doesn't work correctly with fixed hosts or round robin groups. This is pre-existing technical debt that was already broken before the round robin groups feature. CarinaWolli has documented this in Linear issue CAL-6134 for future fix.

Applied to files:

  • packages/trpc/server/routers/loggedInViewer/teamsAndUserProfilesQuery.handler.ts
📚 Learning: in cal.com's getusereventgroups handler refactor (pr #22618), the membershipcount field for team eve...
Learnt from: sean-brydon
PR: calcom/cal.com#22618
File: packages/trpc/server/routers/viewer/eventTypes/utils/transformUtils.ts:113-113
Timestamp: 2025-08-05T07:42:06.335Z
Learning: In Cal.com's getUserEventGroups handler refactor (PR #22618), the membershipCount field for team event groups is intentionally set to 0 in the new createTeamEventGroup function, as confirmed by sean-brydon (PR author). This preserves the same behavior as the old implementation that was being refactored, maintaining backward compatibility. While other parts of the codebase may use actual member counts, this specific implementation maintains the previous behavior.

Applied to files:

  • packages/trpc/server/routers/loggedInViewer/teamsAndUserProfilesQuery.handler.ts
📚 Learning: in the insightsroutingservice (packages/lib/server/service/insightsrouting.ts), multi-select filter ...
Learnt from: eunjae-lee
PR: calcom/cal.com#22106
File: packages/lib/server/service/insightsRouting.ts:367-368
Timestamp: 2025-07-15T13:02:17.403Z
Learning: In the InsightsRoutingService (packages/lib/server/service/insightsRouting.ts), multi-select filter data is already validated by zod before reaching the buildFormFieldSqlCondition method, so null/undefined values are not present in filterValue.data arrays and don't need to be filtered out.

Applied to files:

  • packages/trpc/server/routers/loggedInViewer/teamsAndUserProfilesQuery.handler.ts
📚 Learning: in cal.com's event type system, the membershipcount field for team event groups is intentionally set...
Learnt from: sean-brydon
PR: calcom/cal.com#22618
File: packages/trpc/server/routers/viewer/eventTypes/utils/transformUtils.ts:113-113
Timestamp: 2025-08-05T07:42:06.335Z
Learning: In Cal.com's event type system, the membershipCount field for team event groups is intentionally set to 0, as confirmed by sean-brydon (PR author). This behavior was preserved during the refactor from the old getUserEventGroups.handler.ts implementation to the new createTeamEventGroup function in transformUtils.ts. This is not a bug but the intended behavior that maintains consistency with the previous implementation.

Applied to files:

  • packages/trpc/server/routers/loggedInViewer/teamsAndUserProfilesQuery.handler.ts
🧬 Code Graph Analysis (1)
packages/trpc/server/routers/loggedInViewer/teamsAndUserProfilesQuery.handler.ts (3)
packages/features/pbac/services/permission-check.service.ts (2)
  • PermissionCheckService (19-369)
  • hasPermission (204-233)
packages/platform/libraries/index.ts (1)
  • MembershipRole (98-98)
packages/lib/entityPermissionUtils.server.ts (1)
  • withRoleCanCreateEntity (119-121)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Install dependencies / Yarn install & cache
🔇 Additional comments (2)
packages/trpc/server/routers/loggedInViewer/teamsAndUserProfilesQuery.handler.ts (2)

1-2: LGTM: Proper imports for PBAC system integration.

The new imports correctly bring in the necessary types and services for permission-based access control functionality.


26-66: LGTM: Proper Prisma select usage.

The query correctly uses select instead of include and only retrieves the necessary fields, adhering to the coding guidelines. The credential.key field is not exposed in this query.

@@ -99,6 +103,10 @@ function WorkflowsPage({ filteredList }: PageProps) {
disableMobileButton={true}
onlyShowWithTeams={true}
includeOrg={true}
withPermission={{
Copy link
Member

Choose a reason for hiding this comment

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

The user should still be able to create individual workflows even when the team doesn't allow it

@@ -6,6 +6,7 @@ import { useState } from "react";

import { getPlaceholderAvatar } from "@calcom/lib/defaultAvatarImage";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import type { WorkflowPermissions } from "@calcom/lib/server/repository/workflow-permissions";
Copy link
Member

Choose a reason for hiding this comment

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

This user has no permission to see the team's workflows, but they are still shown as "readonly":
Screenshot 2025-08-07 at 12 33 02 PM

When clicking on the workflow to see the details it throws unauthorized

@sean-brydon sean-brydon enabled auto-merge (squash) August 8, 2025 08:38
@sean-brydon sean-brydon merged commit 3ea73e7 into main Aug 8, 2025
35 of 36 checks passed
@sean-brydon sean-brydon deleted the devin/1753972318-add-workflows-pbac-resource branch August 8, 2025 08:48
Pallava-Joshi pushed a commit to Pallava-Joshi/cal.com that referenced this pull request Aug 8, 2025
calcom#22845)

Co-authored-by: sean@cal.com <Sean@brydon.io>
Co-authored-by: Carina Wollendorfer <30310907+CarinaWolli@users.noreply.github.com>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: CarinaWolli <wollencarina@gmail.com>
@coderabbitai coderabbitai bot mentioned this pull request Sep 2, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
consumer core area: core, team members only ✨ feature New feature or request ❗️ migrations contains migration files ready-for-e2e
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants