fix: ignore userIds form filter segment if no permission#24177
fix: ignore userIds form filter segment if no permission#24177zhyd1997 wants to merge 5 commits intocalcom:mainfrom
Conversation
|
@zhyd1997 is attempting to deploy a commit to the cal Team on Vercel. A member of the Team first needs to authorize it. |
WalkthroughIntroduces an internal helper Possibly related PRs
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing touches
🧪 Generate unit tests
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
packages/trpc/server/routers/viewer/bookings/get.handler.ts (1)
260-273: LGTM: Explicit conditionals improve readability.The conversion from short-circuit boolean guards to explicit
ifblocks maintains the same semantics while improving code clarity. These changes ensure query fragments are only added when the corresponding data arrays are non-empty, making the conditional logic more explicit and easier to follow.Also applies to: 277-291, 296-309, 314-326
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Disabled knowledge base sources:
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (1)
packages/trpc/server/routers/viewer/bookings/get.handler.ts(7 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
**/*.ts
📄 CodeRabbit inference engine (.cursor/rules/review.mdc)
**/*.ts: For Prisma queries, only select data you need; never useinclude, always useselect
Ensure thecredential.keyfield is never returned from tRPC endpoints or APIs
Files:
packages/trpc/server/routers/viewer/bookings/get.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/viewer/bookings/get.handler.ts
**/*.{ts,tsx,js,jsx}
⚙️ CodeRabbit configuration file
Flag default exports and encourage named exports. Named exports provide better tree-shaking, easier refactoring, and clearer imports. Exempt main components like pages, layouts, and components that serve as the primary export of a module.
Files:
packages/trpc/server/routers/viewer/bookings/get.handler.ts
🧠 Learnings (2)
📚 Learning: 2025-08-26T08:08:23.395Z
Learnt from: SinghaAnirban005
PR: calcom/cal.com#23343
File: packages/features/insights/server/trpc-router.ts:1080-1101
Timestamp: 2025-08-26T08:08:23.395Z
Learning: In packages/features/insights/server/trpc-router.ts, when filtering personal event types (userId provided, no teamId, not isAll), the query correctly uses user.id (authenticated user) instead of the input userId parameter for security reasons. This prevents users from accessing other users' personal event types by passing arbitrary user IDs.
Applied to files:
packages/trpc/server/routers/viewer/bookings/get.handler.ts
📚 Learning: 2025-09-03T11:54:05.409Z
Learnt from: supalarry
PR: calcom/cal.com#23514
File: apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts:579-582
Timestamp: 2025-09-03T11:54:05.409Z
Learning: In calcom/cal.com bookings repository methods, when Prisma select uses `eventType: true`, all eventType fields including seatsShowAttendees are automatically included in the selection. Explicit field selection is not required when using `true` for nested relations.
Applied to files:
packages/trpc/server/routers/viewer/bookings/get.handler.ts
There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (1)
packages/trpc/server/routers/viewer/bookings/get.handler.ts (1)
189-219: Security issue: attendee email filter uses original userIds before permission narrowing.
attendeeEmailsFromUserIdsFilteris computed at line 135 using the originalfilters.userIdsbefore the permission-narrowing logic (lines 161-171) executes. This means Queries 2 and 3 (lines 189-202, 205-219) filter by attendee emails of ALL users in the original filter, including those the current user doesn't have permission to view.Attack scenario:
- User creates filter segment with
userIds = [unauthorizedUser.id, currentUser.id].- Permission logic narrows
userIdsto[currentUser.id].- Query 1 correctly uses narrowed
userIds.- Queries 2 and 3 still use
attendeeEmailsFromUserIdsFiltercontainingunauthorizedUser.email.- User can see bookings where
unauthorizedUseris an attendee, bypassing permission checks.Recompute
attendeeEmailsFromUserIdsFilterafter the permission-narrowing block:let userIds = filters.userIds; // Scope depends on `user.orgId`: // - Throw an error if trying to filter by usersIds that are not within your ORG // - Throw an error if trying to filter by usersIds that are not within your TEAM if (!areUserIdsWithinUserOrgOrTeam) { if (!hasCurrentUser) { userIds = []; log.error({ code: "FORBIDDEN", message: "You do not have permissions to fetch bookings for specified userIds", }); + } else { + userIds = [user.id]; } - - userIds = [user.id]; } + + // Recompute attendee emails using narrowed userIds + const attendeeEmailsFromNarrowedUserIds = await prisma.user + .findMany({ + where: { id: { in: userIds } }, + select: { email: true }, + }) + .then((users) => users.map((user) => user.email));Then use
attendeeEmailsFromNarrowedUserIdsin Queries 2 and 3 instead ofattendeeEmailsFromUserIdsFilter.
🧹 Nitpick comments (1)
packages/trpc/server/routers/viewer/bookings/get.handler.ts (1)
263-329: LGTM: Explicit guards improve readability and prevent empty queries.The conversion from inline boolean guards to explicit if-blocks for Queries 4-7 (lines 263-329) improves code clarity and ensures queries are only added to
bookingQuerieswhen relevant data exists. This prevents constructing queries with empty filter arrays and aligns with the refactor pattern applied to Query 1.
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Disabled knowledge base sources:
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (1)
packages/trpc/server/routers/viewer/bookings/get.handler.ts(6 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
**/*.ts
📄 CodeRabbit inference engine (.cursor/rules/review.mdc)
**/*.ts: For Prisma queries, only select data you need; never useinclude, always useselect
Ensure thecredential.keyfield is never returned from tRPC endpoints or APIs
Files:
packages/trpc/server/routers/viewer/bookings/get.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/viewer/bookings/get.handler.ts
**/*.{ts,tsx,js,jsx}
⚙️ CodeRabbit configuration file
Flag default exports and encourage named exports. Named exports provide better tree-shaking, easier refactoring, and clearer imports. Exempt main components like pages, layouts, and components that serve as the primary export of a module.
Files:
packages/trpc/server/routers/viewer/bookings/get.handler.ts
🧠 Learnings (2)
📚 Learning: 2025-08-26T08:08:23.395Z
Learnt from: SinghaAnirban005
PR: calcom/cal.com#23343
File: packages/features/insights/server/trpc-router.ts:1080-1101
Timestamp: 2025-08-26T08:08:23.395Z
Learning: In packages/features/insights/server/trpc-router.ts, when filtering personal event types (userId provided, no teamId, not isAll), the query correctly uses user.id (authenticated user) instead of the input userId parameter for security reasons. This prevents users from accessing other users' personal event types by passing arbitrary user IDs.
Applied to files:
packages/trpc/server/routers/viewer/bookings/get.handler.ts
📚 Learning: 2025-09-03T11:54:05.409Z
Learnt from: supalarry
PR: calcom/cal.com#23514
File: apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts:579-582
Timestamp: 2025-09-03T11:54:05.409Z
Learning: In calcom/cal.com bookings repository methods, when Prisma select uses `eventType: true`, all eventType fields including seatsShowAttendees are automatically included in the selection. Explicit field selection is not required when using `true` for nested relations.
Applied to files:
packages/trpc/server/routers/viewer/bookings/get.handler.ts
🔇 Additional comments (1)
packages/trpc/server/routers/viewer/bookings/get.handler.ts (1)
174-186: LGTM: Query 1 now correctly guards on narrowed userIds length.The explicit if-block ensures Query 1 only executes when
userIdsis non-empty after permission narrowing. This prevents querying with an empty userIds array and aligns with the PR objective of ignoring unauthorized userIds.Note: This depends on fixing the logic error in lines 161-171 to ensure
userIdsis correctly set to empty when the current user is not included in an unauthorized filter.
…dling of permissions
|
Hi @kart1ka How to verify the patch for the team plan users? |
There was a problem hiding this comment.
Actionable comments posted: 1
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Disabled knowledge base sources:
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (1)
packages/trpc/server/routers/viewer/bookings/get.handler.ts(7 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
**/*.ts
📄 CodeRabbit inference engine (.cursor/rules/review.mdc)
**/*.ts: For Prisma queries, only select data you need; never useinclude, always useselect
Ensure thecredential.keyfield is never returned from tRPC endpoints or APIs
Files:
packages/trpc/server/routers/viewer/bookings/get.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/viewer/bookings/get.handler.ts
**/*.{ts,tsx,js,jsx}
⚙️ CodeRabbit configuration file
Flag default exports and encourage named exports. Named exports provide better tree-shaking, easier refactoring, and clearer imports. Exempt main components like pages, layouts, and components that serve as the primary export of a module.
Files:
packages/trpc/server/routers/viewer/bookings/get.handler.ts
🧠 Learnings (2)
📚 Learning: 2025-08-26T08:08:23.395Z
Learnt from: SinghaAnirban005
PR: calcom/cal.com#23343
File: packages/features/insights/server/trpc-router.ts:1080-1101
Timestamp: 2025-08-26T08:08:23.395Z
Learning: In packages/features/insights/server/trpc-router.ts, when filtering personal event types (userId provided, no teamId, not isAll), the query correctly uses user.id (authenticated user) instead of the input userId parameter for security reasons. This prevents users from accessing other users' personal event types by passing arbitrary user IDs.
Applied to files:
packages/trpc/server/routers/viewer/bookings/get.handler.ts
📚 Learning: 2025-09-03T11:54:05.409Z
Learnt from: supalarry
PR: calcom/cal.com#23514
File: apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts:579-582
Timestamp: 2025-09-03T11:54:05.409Z
Learning: In calcom/cal.com bookings repository methods, when Prisma select uses `eventType: true`, all eventType fields including seatsShowAttendees are automatically included in the selection. Explicit field selection is not required when using `true` for nested relations.
Applied to files:
packages/trpc/server/routers/viewer/bookings/get.handler.ts
🔇 Additional comments (3)
packages/trpc/server/routers/viewer/bookings/get.handler.ts (3)
188-194: LGTM: Correctly derives attendee emails from filtered userIds.The refactoring properly uses
getFilteredUserIdsto compute permitted userIds and derivesattendeeEmailsFromUserIdsFilterfrom the result instead of the rawfilters.userIds. This ensures only authorized users' emails are included in the query scope.
197-209: LGTM: Guards prevent empty queries and align with filtering logic.The explicit guards around booking query pushes ensure:
- Queries are only added when data exists (e.g.,
userIds.length > 0).- Empty
inclauses are avoided, improving query efficiency.- Consistent pattern across multiple branches (lines 197, 286, 303, 322, 340).
This approach aligns well with the PR objective to silently ignore unauthorized userIds.
Also applies to: 286-299, 303-317, 322-335, 340-352
63-73: PR objectives met: Unauthorized userIds are now ignored instead of throwing.The refactored logic successfully implements the PR objective:
- Before: Threw
FORBIDDENerror when filter included unauthorized userIds.- After: Logs
FORBIDDEN(line 66-69) but silently filters to either[](no current user) or[user.id](current user included), preventing the error state.This makes the bookings listing resilient to filter segments referencing users the viewer no longer has permission to see.
…ermission validation
|
This PR is being marked as stale due to inactivity. |
What does this PR do?
Visual Demo (For contributors especially)
A visual demonstration is strongly recommended, for both the original and new change (video / image - any one).
Video Demo (if applicable):
Image Demo (if applicable):
Mandatory Tasks (DO NOT REMOVE)
How should this be tested?
Checklist