Skip to content

Commit 943c1a3

Browse files
authored
fix: events not removed from the previous host calendar due to wrong credentials usage (calcom#23756)
* fix: events not removed from the previous host claendar * fix test * Update roundRobinManualReassignment.test.ts
1 parent 9156848 commit 943c1a3

7 files changed

Lines changed: 106 additions & 6 deletions

packages/features/ee/round-robin/handleRescheduleEventManager.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@ export const handleRescheduleEventManager = async ({
5353
prefix: ["handleRescheduleEventManager", `${bookingId}`],
5454
});
5555

56+
const skipDeleteEventsAndMeetings = changedOrganizer;
57+
5658
const allCredentials = await getAllCredentialsIncludeServiceAccountKey(
5759
initParams.user,
5860
initParams?.eventType
@@ -68,7 +70,9 @@ export const handleRescheduleEventManager = async ({
6870
rescheduleUid,
6971
newBookingId,
7072
changedOrganizer,
71-
previousHostDestinationCalendar
73+
previousHostDestinationCalendar,
74+
undefined,
75+
skipDeleteEventsAndMeetings
7276
);
7377

7478
const results = updateManager.results ?? [];

packages/features/ee/round-robin/roundRobinDeleteEvents.test.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,14 +115,16 @@ describe("roundRobinReassignment test", () => {
115115

116116
await roundRobinReassignment({
117117
bookingId: 123,
118+
reassignedById: 101,
119+
orgId: null,
118120
});
119121

120122
// Verify that calendar deletion occurred (may be called multiple times due to duplicate references)
121123
expect(calendarMock.deleteEventCalls.length).toBeGreaterThanOrEqual(1);
122124
const deleteCall = calendarMock.deleteEventCalls[0];
123125
expect(deleteCall.args.uid).toBe("ORIGINAL_EVENT_ID");
124126
expect(deleteCall.args.externalCalendarId).toBe("MOCK_EXTERNAL_CALENDAR_ID");
125-
expect(deleteCall.args.event.organizer.email).toBe(newHost.email); // Current implementation uses new host credentials
127+
expect(deleteCall.args.event.organizer.email).toBe(originalHost.email);
126128
expect(deleteCall.args.event.uid).toBe(bookingToReassignUid);
127129

128130
// Verify that creation occurred with new host credentials

packages/features/ee/round-robin/roundRobinManualReassignment.test.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,9 @@ const expectEventManagerCalledWith = (
154154
expectedParams.uid,
155155
undefined,
156156
expectedParams.changedOrganizer,
157-
expectedParams.destinationCalendars ?? expect.any(Array)
157+
expectedParams.destinationCalendars ?? expect.any(Array),
158+
undefined,
159+
expectedParams.changedOrganizer
158160
);
159161
};
160162

packages/features/ee/round-robin/roundRobinManualReassignment.ts

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {
77
sendRoundRobinScheduledEmailsAndSMS,
88
sendRoundRobinUpdatedEmailsAndSMS,
99
} from "@calcom/emails";
10+
import { getAllCredentialsIncludeServiceAccountKey } from "@calcom/features/bookings/lib/getAllCredentialsForUsersOnEvent/getAllCredentials";
1011
import getBookingResponsesSchema from "@calcom/features/bookings/lib/getBookingResponsesSchema";
1112
import { getCalEventResponses } from "@calcom/features/bookings/lib/getCalEventResponses";
1213
import { getEventTypesFromDB } from "@calcom/features/bookings/lib/handleNewBooking/getEventTypesFromDB";
@@ -21,6 +22,7 @@ import {
2122
import { scheduleWorkflowReminders } from "@calcom/features/ee/workflows/lib/reminders/reminderScheduler";
2223
import { getEventName } from "@calcom/features/eventtypes/lib/eventNaming";
2324
import { getVideoCallUrlFromCalEvent } from "@calcom/lib/CalEventParser";
25+
import EventManager from "@calcom/lib/EventManager";
2426
import { SENDER_NAME } from "@calcom/lib/constants";
2527
import { enrichUserWithDelegationCredentialsIncludeServiceAccountKey } from "@calcom/lib/delegationCredential/server";
2628
import { getBookerBaseUrl } from "@calcom/lib/getBookerUrl/server";
@@ -32,6 +34,7 @@ import { getTimeFormatStringFromUserTimeFormat } from "@calcom/lib/timeFormat";
3234
import { prisma } from "@calcom/prisma";
3335
import { WorkflowActions, WorkflowMethods, WorkflowTriggerEvents } from "@calcom/prisma/enums";
3436
import type { EventTypeMetadata, PlatformClientParams } from "@calcom/prisma/zod-utils";
37+
import { eventTypeAppMetadataOptionalSchema } from "@calcom/prisma/zod-utils";
3538
import type { CalendarEvent } from "@calcom/types/Calendar";
3639

3740
import { handleRescheduleEventManager } from "./handleRescheduleEventManager";
@@ -324,6 +327,41 @@ export const roundRobinManualReassignment = async ({
324327
})
325328
: null;
326329

330+
const apps = eventTypeAppMetadataOptionalSchema.parse(eventType?.metadata?.apps);
331+
332+
// remove the event and meeting using the old host's credentials
333+
if (hasOrganizerChanged && originalOrganizer.id !== newUser.id) {
334+
const previousHostCredentials = await getAllCredentialsIncludeServiceAccountKey(
335+
originalOrganizer,
336+
eventType
337+
);
338+
339+
const originalHostEventManager = new EventManager(
340+
{ ...originalOrganizer, credentials: previousHostCredentials },
341+
apps
342+
);
343+
344+
const deletionEvent: CalendarEvent = {
345+
...evt,
346+
organizer: {
347+
id: originalOrganizer.id,
348+
name: originalOrganizer.name || "",
349+
email: originalOrganizer.email,
350+
username: originalOrganizer.username || undefined,
351+
timeZone: originalOrganizer.timeZone,
352+
language: { translate: originalOrganizerT, locale: originalOrganizer.locale ?? "en" },
353+
timeFormat: getTimeFormatStringFromUserTimeFormat(originalOrganizer.timeFormat),
354+
},
355+
destinationCalendar: previousHostDestinationCalendar ? [previousHostDestinationCalendar] : [],
356+
title: booking.title,
357+
};
358+
359+
await originalHostEventManager.deleteEventsAndMeetings({
360+
event: deletionEvent,
361+
bookingReferences: booking.references,
362+
});
363+
}
364+
327365
const { evtWithAdditionalInfo } = await handleRescheduleEventManager({
328366
evt,
329367
rescheduleUid: booking.uid,

packages/features/ee/round-robin/roundRobinReassignment.test.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,9 @@ describe("roundRobinReassignment test", () => {
171171
bookingToReassignUid,
172172
undefined,
173173
true,
174-
expect.arrayContaining([expect.objectContaining(testDestinationCalendar)])
174+
expect.arrayContaining([expect.objectContaining(testDestinationCalendar)]),
175+
undefined,
176+
true
175177
);
176178

177179
// Use equal fairness rr algorithm
@@ -279,7 +281,9 @@ describe("roundRobinReassignment test", () => {
279281
bookingToReassignUid,
280282
undefined,
281283
false,
282-
[]
284+
[],
285+
undefined,
286+
false
283287
);
284288

285289
// Ensure organizer stays the same

packages/features/ee/round-robin/roundRobinReassignment.ts

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {
88
sendRoundRobinScheduledEmailsAndSMS,
99
sendRoundRobinUpdatedEmailsAndSMS,
1010
} from "@calcom/emails";
11+
import { getAllCredentialsIncludeServiceAccountKey } from "@calcom/features/bookings/lib/getAllCredentialsForUsersOnEvent/getAllCredentials";
1112
import getBookingResponsesSchema from "@calcom/features/bookings/lib/getBookingResponsesSchema";
1213
import { getCalEventResponses } from "@calcom/features/bookings/lib/getCalEventResponses";
1314
import { ensureAvailableUsers } from "@calcom/features/bookings/lib/handleNewBooking/ensureAvailableUsers";
@@ -17,6 +18,7 @@ import AssignmentReasonRecorder, {
1718
RRReassignmentType,
1819
} from "@calcom/features/ee/round-robin/assignmentReason/AssignmentReasonRecorder";
1920
import { getEventName } from "@calcom/features/eventtypes/lib/eventNaming";
21+
import EventManager from "@calcom/lib/EventManager";
2022
import {
2123
enrichHostsWithDelegationCredentials,
2224
enrichUserWithDelegationCredentialsIncludeServiceAccountKey,
@@ -31,6 +33,7 @@ import { getTimeFormatStringFromUserTimeFormat } from "@calcom/lib/timeFormat";
3133
import { prisma } from "@calcom/prisma";
3234
import { userMetadata as userMetadataSchema } from "@calcom/prisma/zod-utils";
3335
import type { EventTypeMetadata, PlatformClientParams } from "@calcom/prisma/zod-utils";
36+
import { eventTypeAppMetadataOptionalSchema } from "@calcom/prisma/zod-utils";
3437
import type { CalendarEvent } from "@calcom/types/Calendar";
3538

3639
import { handleRescheduleEventManager } from "./handleRescheduleEventManager";
@@ -355,6 +358,42 @@ export const roundRobinReassignment = async ({
355358
user: { ...organizer, credentials },
356359
});
357360

361+
const apps = eventTypeAppMetadataOptionalSchema.parse(eventType?.metadata?.apps);
362+
363+
// remove the event and meeting using the old host's credentials
364+
if (hasOrganizerChanged && originalOrganizer.id !== reassignedRRHost.id) {
365+
const previousHostCredentials = await getAllCredentialsIncludeServiceAccountKey(
366+
originalOrganizer,
367+
eventType
368+
);
369+
const originalHostEventManager = new EventManager(
370+
{ ...originalOrganizer, credentials: previousHostCredentials },
371+
apps
372+
);
373+
374+
const originalOrganizerT = await getTranslation(originalOrganizer.locale || "en", "common");
375+
376+
const deletionEvent: CalendarEvent = {
377+
...evt,
378+
organizer: {
379+
id: originalOrganizer.id,
380+
name: originalOrganizer.name || "",
381+
email: originalOrganizer.email,
382+
username: originalOrganizer.username || undefined,
383+
timeZone: originalOrganizer.timeZone,
384+
language: { translate: originalOrganizerT, locale: originalOrganizer.locale ?? "en" },
385+
timeFormat: getTimeFormatStringFromUserTimeFormat(originalOrganizer.timeFormat),
386+
},
387+
destinationCalendar: previousHostDestinationCalendar ? [previousHostDestinationCalendar] : [],
388+
title: booking.title,
389+
};
390+
391+
await originalHostEventManager.deleteEventsAndMeetings({
392+
event: deletionEvent,
393+
bookingReferences: booking.references,
394+
});
395+
}
396+
358397
const { evtWithAdditionalInfo } = await handleRescheduleEventManager({
359398
evt,
360399
rescheduleUid: booking.uid,

packages/features/ee/round-robin/utils/bookingSelect.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import type { Prisma } from "@calcom/prisma/client";
2+
import { credentialForCalendarServiceSelect } from "@calcom/prisma/selects/credential";
23

34
export const bookingSelect = {
45
uid: true,
@@ -13,8 +14,18 @@ export const bookingSelect = {
1314
eventTypeId: true,
1415
destinationCalendar: true,
1516
user: {
16-
include: {
17+
select: {
18+
id: true,
19+
name: true,
20+
username: true,
21+
email: true,
22+
locale: true,
23+
timeZone: true,
24+
timeFormat: true,
1725
destinationCalendar: true,
26+
credentials: {
27+
select: credentialForCalendarServiceSelect,
28+
},
1829
},
1930
},
2031
attendees: true,

0 commit comments

Comments
 (0)