fix: api v2 - platform users can disable emails and display their links (#14604)

* fix: disable emails with oauthCLient settings and hide empty links

* fixup! fix: disable emails with oauthCLient settings and hide empty links

* feat: enable to display booking success page link in emails

* fixup! feat: enable to display booking success page link in emails

* fixup! Merge branch 'fix-no-email-booking-hide-empty-links' of github.com:calcom/cal.com into fix-no-email-booking-hide-empty-links

* fixup! fixup! Merge branch 'fix-no-email-booking-hide-empty-links' of github.com:calcom/cal.com into fix-no-email-booking-hide-empty-links

* fixup! Merge branch 'main' into fix-no-email-booking-hide-empty-links

* fixup! Merge branch 'main' into fix-no-email-booking-hide-empty-links

* fixup! Merge branch 'fix-no-email-booking-hide-empty-links' of github.com:calcom/cal.com into fix-no-email-booking-hide-empty-links

---------

Co-authored-by: Lauris Skraucis <lauris.skraucis@gmail.com>
This commit is contained in:
Morgan
2024-04-18 12:43:17 +00:00
committed by GitHub
co-authored by Lauris Skraucis
parent 8b2e46a6fa
commit 480977c2b5
4 changed files with 86 additions and 33 deletions
@@ -58,6 +58,7 @@ type OAuthRequestParams = {
platformCancelUrl: string;
platformBookingUrl: string;
platformBookingLocation?: string;
arePlatformEmailsEnabled: boolean;
};
const DEFAULT_PLATFORM_PARAMS = {
@@ -65,7 +66,7 @@ const DEFAULT_PLATFORM_PARAMS = {
platformCancelUrl: "",
platformRescheduleUrl: "",
platformBookingUrl: "",
areEmailsEnabled: true,
arePlatformEmailsEnabled: false,
platformBookingLocation: undefined,
};
@@ -172,6 +173,7 @@ export class BookingsController {
const oAuthClientId = clientId?.toString();
if (bookingId) {
try {
req.body.id = parseInt(bookingId);
await handleCancelBooking(await this.createNextApiBookingRequest(req, oAuthClientId));
return {
status: SUCCESS_STATUS,
@@ -239,10 +241,7 @@ export class BookingsController {
}
}
async getOAuthClientsParams(
req: BookingRequest,
clientId: string
): Promise<OAuthRequestParams & { areEmailsEnabled: boolean }> {
async getOAuthClientsParams(req: BookingRequest, clientId: string): Promise<OAuthRequestParams> {
const res = DEFAULT_PLATFORM_PARAMS;
try {
const client = await this.oAuthClientRepository.getOAuthClient(clientId);
@@ -252,7 +251,7 @@ export class BookingsController {
res.platformCancelUrl = client.bookingCancelRedirectUri ?? "";
res.platformRescheduleUrl = client.bookingRescheduleRedirectUri ?? "";
res.platformBookingUrl = client.bookingRedirectUri ?? "";
res.areEmailsEnabled = client.areEmailsEnabled;
res.arePlatformEmailsEnabled = client.areEmailsEnabled ?? false;
}
return res;
} catch (err) {
@@ -271,7 +270,7 @@ export class BookingsController {
? await this.getOAuthClientsParams(req, oAuthClientId)
: DEFAULT_PLATFORM_PARAMS;
Object.assign(req, { userId, ...oAuthParams, platformBookingLocation });
req.body = { ...req.body, areEmailsEnabled: oAuthParams.areEmailsEnabled };
req.body = { ...req.body, noEmail: !oAuthParams.arePlatformEmailsEnabled };
return req as unknown as NextApiRequest & { userId?: number } & OAuthRequestParams;
}
}
+54 -18
View File
@@ -1,13 +1,25 @@
import { getCancelLink, getRescheduleLink } from "@calcom/lib/CalEventParser";
import { getCancelLink, getRescheduleLink, getBookingUrl } from "@calcom/lib/CalEventParser";
import type { CalendarEvent, Person } from "@calcom/types/Calendar";
export function ManageLink(props: { calEvent: CalendarEvent; attendee: Person }) {
// Only the original attendee can make changes to the event
// Guests cannot
const t = props.attendee.language.translate;
const cancelLink = getCancelLink(props.calEvent);
const rescheduleLink = getRescheduleLink(props.calEvent);
const bookingLink = getBookingUrl(props.calEvent);
const isOriginalAttendee = props.attendee.email === props.calEvent.attendees[0]?.email;
const isOrganizer = props.calEvent.organizer.email === props.attendee.email;
const hasCancelLink = Boolean(cancelLink);
const hasRescheduleLink = Boolean(rescheduleLink);
const hasBookingLink = Boolean(bookingLink);
const isRecurringEvent = props.calEvent.recurringEvent;
const shouldDisplayRescheduleLink = Boolean(hasRescheduleLink && !isRecurringEvent);
if (
props.attendee.email === props.calEvent.attendees[0]?.email ||
props.calEvent.organizer.email === props.attendee.email
(isOriginalAttendee || isOrganizer) &&
(hasCancelLink || (!isRecurringEvent && hasRescheduleLink) || hasBookingLink)
) {
return (
<div
@@ -28,10 +40,10 @@ export function ManageLink(props: { calEvent: CalendarEvent; attendee: Person })
}}>
<>{t("need_to_make_a_change")}</>
{!props.calEvent.recurringEvent && (
{shouldDisplayRescheduleLink && (
<span>
<a
href={getRescheduleLink(props.calEvent)}
href={rescheduleLink}
style={{
color: "#374151",
marginLeft: "5px",
@@ -40,25 +52,49 @@ export function ManageLink(props: { calEvent: CalendarEvent; attendee: Person })
}}>
<>{t("reschedule")}</>
</a>
<>{t("or_lowercase")}</>
{hasCancelLink && <>{t("or_lowercase")}</>}
</span>
)}
{hasCancelLink && (
<span>
<a
href={cancelLink}
style={{
color: "#374151",
marginLeft: "5px",
textDecoration: "underline",
}}>
<>{t("cancel")}</>
</a>
</span>
)}
{props.calEvent.platformClientId && hasBookingLink && (
<span>
{(hasCancelLink || shouldDisplayRescheduleLink) && (
<span
style={{
marginLeft: "5px",
}}>
{t("or_lowercase")}
</span>
)}
<a
href={bookingLink}
style={{
color: "#374151",
marginLeft: "5px",
textDecoration: "underline",
}}>
<>{t("check_here")}</>
</a>
</span>
)}
<span>
<a
href={getCancelLink(props.calEvent)}
style={{
color: "#374151",
marginLeft: "5px",
textDecoration: "underline",
}}>
<>{t("cancel")}</>
</a>
</span>
</p>
</div>
);
}
// Dont have the rights to the manage link
// Don't have the rights to the manage link
return null;
}
@@ -129,6 +129,7 @@ export type CustomRequest = NextApiRequest & {
platformRescheduleUrl?: string;
platformCancelUrl?: string;
platformBookingUrl?: string;
arePlatformEmailsEnabled?: boolean;
};
async function handler(req: CustomRequest) {
@@ -142,6 +143,7 @@ async function handler(req: CustomRequest) {
platformCancelUrl,
platformClientId,
platformRescheduleUrl,
arePlatformEmailsEnabled,
} = req;
if (!bookingToDelete || !bookingToDelete.user) {
@@ -559,7 +561,8 @@ async function handler(req: CustomRequest) {
}
// TODO: if emails fail try to requeue them
await sendCancelledEmails(evt, { eventName: bookingToDelete?.eventType?.eventName });
if (!platformClientId || (platformClientId && arePlatformEmailsEnabled))
await sendCancelledEmails(evt, { eventName: bookingToDelete?.eventType?.eventName });
} catch (error) {
console.error("Error deleting event", error);
}
+22 -7
View File
@@ -154,18 +154,33 @@ const getSeatReferenceId = (calEvent: CalendarEvent): string => {
return calEvent.attendeeSeatId ? calEvent.attendeeSeatId : "";
};
export const getPlatformManageLink = (calEvent: CalendarEvent, t: TFunction) => {
if (calEvent.platformBookingUrl) {
return `${t("need_to_reschedule_or_cancel")} ${calEvent.platformBookingUrl}/${getUid(calEvent)}?slug=${
calEvent.type
}&username=${calEvent.organizer.username}&changes=true`;
export const getBookingUrl = (calEvent: CalendarEvent) => {
if (calEvent.platformClientId) {
if (!calEvent.platformBookingUrl) return "";
return `${calEvent.platformBookingUrl}/${getUid(calEvent)}?slug=${calEvent.type}&username=${
calEvent.organizer.username
}&changes=true`;
}
return `${calEvent.bookerUrl ?? WEBAPP_URL}/booking/${getUid(calEvent)}?changes=true`;
};
export const getPlatformManageLink = (calEvent: CalendarEvent, t: TFunction) => {
const shouldDisplayReschedule = !calEvent.recurringEvent && calEvent.platformRescheduleUrl;
let res =
calEvent.platformBookingUrl || shouldDisplayReschedule || calEvent.platformCancelUrl
? `${t("need_to_reschedule_or_cancel")} `
: ``;
if (calEvent.platformBookingUrl) {
res += `Check Here: ${calEvent.platformBookingUrl}/${getUid(calEvent)}?slug=${calEvent.type}&username=${
calEvent.organizer.username
}&changes=true${calEvent.platformCancelUrl || shouldDisplayReschedule ? ` ${t("or_lowercase")} ` : ""}`;
}
let res = "";
if (calEvent.platformCancelUrl) {
res += `${t("cancel")}: ${getCancelLink(calEvent)}`;
}
if (calEvent.platformRescheduleUrl) {
if (!calEvent.recurringEvent && calEvent.platformRescheduleUrl) {
res += `${calEvent.platformCancelUrl ? ` ${t("or_lowercase")} ` : ""}${t(
"reschedule"
)}: ${getRescheduleLink(calEvent)}`;