Skip to content

fix: only host can disable cancel meeting#28051

Open
hackice20 wants to merge 1 commit intocalcom:mainfrom
hackice20:fix/host-only-disable-cancel
Open

fix: only host can disable cancel meeting#28051
hackice20 wants to merge 1 commit intocalcom:mainfrom
hackice20:fix/host-only-disable-cancel

Conversation

@hackice20
Copy link
Contributor

What does this PR do?

Allow hosts to cancel even when “Disable cancelling” is on

This PR updates booking actions and cancel logic so that hosts (organizers/event owners) can still cancel bookings even when the event type has disableCancelling enabled, while guests are blocked. It wires isHost through the booking UI, adjusts isActionDisabled("cancel", ...) to permit host cancellations, updates handleCancelBooking to only enforce the “no cancellations” rule for non-hosts, and adds tests covering both host-allowed and guest-blocked scenarios.

Visual Demo (For contributors especially)

Screencast.From.2026-02-18.19-09-22.mp4

Mandatory Tasks (DO NOT REMOVE)

  • I have self-reviewed the code (A decent size PR without self-review might be rejected).
  • I have updated the developer docs in /docs if this PR makes changes that would require a documentation change. If N/A, write N/A here and check the checkbox.
  • I confirm automated tests are in place that prove my fix is effective or that my feature works.

Checklist

  • I have read the contributing guide
  • My code does follow the style guidelines of this project
  • I have commented my code, particularly in hard-to-understand areas
  • I have checked if my changes generate no new warnings
  • My PR is not too large (>500 lines or >10 files)

@hackice20 hackice20 requested a review from a team as a code owner February 18, 2026 18:33
@github-actions github-actions bot added bookings area: bookings, availability, timezones, double booking Medium priority Created by Linear-GitHub Sync 🐛 bug Something isn't working labels Feb 18, 2026
@graphite-app graphite-app bot added the community Created by Linear-GitHub Sync label Feb 18, 2026
Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

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

5 issues found across 6 files

Prompt for AI agents (all issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="packages/features/bookings/lib/handleCancelBooking.ts">

<violation number="1" location="packages/features/bookings/lib/handleCancelBooking.ts:216">
P2: Host check now treats any eventType host as cancellation-authorized, without verifying the host is assigned to the booking’s attendees. This can allow unassigned team hosts to cancel bookings even when disableCancelling is enabled, conflicting with the per-booking host assignment policy used elsewhere.</violation>

<violation number="2" location="packages/features/bookings/lib/handleCancelBooking.ts:225">
P2: Untrusted cancelledBy query param is now used to grant host status, allowing spoofed host cancellations to bypass disableCancelling when userId is absent.</violation>
</file>

<file name="apps/web/components/booking/actions/BookingActionsDropdown.tsx">

<violation number="1" location="apps/web/components/booking/actions/BookingActionsDropdown.tsx:202">
P2: Client-side isHost only checks booking owner; it omits assigned event type hosts (attendee-email match), so non-owner hosts will still be treated as guests and blocked from canceling.</violation>
</file>

<file name="apps/web/components/booking/actions/bookingActions.ts">

<violation number="1" location="apps/web/components/booking/actions/bookingActions.ts:277">
P2: The new cancel bypass trusts `isHost`, but `isHost` is computed only by userId equality with `booking.user.id` and does not verify attendee assignment. This can enable cancellation for non-assigned team members even when guest cancellation is disabled. Host detection should include the attendee-email/assignment check before using it to bypass cancel restrictions.</violation>
</file>

<file name="apps/web/components/booking/BookingListItem.tsx">

<violation number="1" location="apps/web/components/booking/BookingListItem.tsx:208">
P2: Host determination omits attendee-based assignment checks, which can incorrectly treat non-assigned team hosts/owners as hosts and allow cancellation despite disableCancelling.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

if (userId) {
if (bookingToDelete.userId === userId) {
isCancellationUserHost = true;
} else if (bookingToDelete.eventType?.hosts?.some((host) => host.user.id === userId)) {
Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot Feb 18, 2026

Choose a reason for hiding this comment

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

P2: Host check now treats any eventType host as cancellation-authorized, without verifying the host is assigned to the booking’s attendees. This can allow unassigned team hosts to cancel bookings even when disableCancelling is enabled, conflicting with the per-booking host assignment policy used elsewhere.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/features/bookings/lib/handleCancelBooking.ts, line 216:

<comment>Host check now treats any eventType host as cancellation-authorized, without verifying the host is assigned to the booking’s attendees. This can allow unassigned team hosts to cancel bookings even when disableCancelling is enabled, conflicting with the per-booking host assignment policy used elsewhere.</comment>

<file context>
@@ -208,16 +208,33 @@ async function handler(input: CancelBookingInput, dependencies?: Dependencies) {
+  if (userId) {
+    if (bookingToDelete.userId === userId) {
+      isCancellationUserHost = true;
+    } else if (bookingToDelete.eventType?.hosts?.some((host) => host.user.id === userId)) {
+      isCancellationUserHost = true;
+    } else if (bookingToDelete.eventType?.owner?.id === userId) {
</file context>
Suggested change
} else if (bookingToDelete.eventType?.hosts?.some((host) => host.user.id === userId)) {
} else if (
bookingToDelete.eventType?.hosts?.some(
(host) =>
host.user.id === userId &&
bookingToDelete.attendees.some((attendee) => attendee.email === host.user.email)
)
) {
Fix with Cubic

) {
isCancellationUserHost = true;
}
} else if (cancelledBy && bookingToDelete.user.email === cancelledBy) {
Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot Feb 18, 2026

Choose a reason for hiding this comment

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

P2: Untrusted cancelledBy query param is now used to grant host status, allowing spoofed host cancellations to bypass disableCancelling when userId is absent.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/features/bookings/lib/handleCancelBooking.ts, line 225:

<comment>Untrusted cancelledBy query param is now used to grant host status, allowing spoofed host cancellations to bypass disableCancelling when userId is absent.</comment>

<file context>
@@ -208,16 +208,33 @@ async function handler(input: CancelBookingInput, dependencies?: Dependencies) {
+    ) {
+      isCancellationUserHost = true;
+    }
+  } else if (cancelledBy && bookingToDelete.user.email === cancelledBy) {
+    // Also check if cancelledBy email matches the booking owner
+    isCancellationUserHost = true;
</file context>
Fix with Cubic

const isHost =
booking.user?.id != null &&
booking.loggedInUser.userId != null &&
booking.loggedInUser.userId === booking.user.id;
Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot Feb 18, 2026

Choose a reason for hiding this comment

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

P2: Client-side isHost only checks booking owner; it omits assigned event type hosts (attendee-email match), so non-owner hosts will still be treated as guests and blocked from canceling.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At apps/web/components/booking/actions/BookingActionsDropdown.tsx, line 202:

<comment>Client-side isHost only checks booking owner; it omits assigned event type hosts (attendee-email match), so non-owner hosts will still be treated as guests and blocked from canceling.</comment>

<file context>
@@ -195,7 +195,11 @@ export function BookingActionsDropdown({
+  const isHost =
+    booking.user?.id != null &&
+    booking.loggedInUser.userId != null &&
+    booking.loggedInUser.userId === booking.user.id;
 
   const isCalVideoLocation =
</file context>
Fix with Cubic

}
case "cancel":
// Allow hosts to cancel even when cancellation is disabled for guests
if (isHost && !isBookingInPast && !isCancelled && !isRejected) {
Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot Feb 18, 2026

Choose a reason for hiding this comment

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

P2: The new cancel bypass trusts isHost, but isHost is computed only by userId equality with booking.user.id and does not verify attendee assignment. This can enable cancellation for non-assigned team members even when guest cancellation is disabled. Host detection should include the attendee-email/assignment check before using it to bypass cancel restrictions.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At apps/web/components/booking/actions/bookingActions.ts, line 277:

<comment>The new cancel bypass trusts `isHost`, but `isHost` is computed only by userId equality with `booking.user.id` and does not verify attendee assignment. This can enable cancellation for non-assigned team members even when guest cancellation is disabled. Host detection should include the attendee-email/assignment check before using it to bypass cancel restrictions.</comment>

<file context>
@@ -270,7 +271,12 @@ export function isActionDisabled(actionId: string, context: BookingActionContext
+    }
     case "cancel":
+      // Allow hosts to cancel even when cancellation is disabled for guests
+      if (isHost && !isBookingInPast && !isCancelled && !isRejected) {
+        return false;
+      }
</file context>
Fix with Cubic

const cardCharged = booking?.payment[0]?.success;

// Check if the logged-in user is the host/owner of the booking
const isHost =
Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot Feb 18, 2026

Choose a reason for hiding this comment

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

P2: Host determination omits attendee-based assignment checks, which can incorrectly treat non-assigned team hosts/owners as hosts and allow cancellation despite disableCancelling.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At apps/web/components/booking/BookingListItem.tsx, line 208:

<comment>Host determination omits attendee-based assignment checks, which can incorrectly treat non-assigned team hosts/owners as hosts and allow cancellation despite disableCancelling.</comment>

<file context>
@@ -207,6 +204,12 @@ function BookingListItem(booking: BookingItemProps) {
   const cardCharged = booking?.payment[0]?.success;
 
+  // Check if the logged-in user is the host/owner of the booking
+  const isHost =
+    booking.user?.id != null &&
+    booking.loggedInUser.userId != null &&
</file context>
Fix with Cubic

@hackice20
Copy link
Contributor Author

hackice20 commented Feb 19, 2026

@sean-brydon @Udit-takkar can you guys please review my PR :)
Also I have doubts regarding these cubic bot comments let me know which ones to address
Thanking you in anticipation

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

Labels

bookings area: bookings, availability, timezones, double booking 🐛 bug Something isn't working community Created by Linear-GitHub Sync Medium priority Created by Linear-GitHub Sync size/L

Projects

None yet

Development

Successfully merging this pull request may close these issues.

When the cancelation is disable for the guest in the event definition, the host is also unable to cancel the event from the reservation dashboard

1 participant

Comments