Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { shouldHideBrandingForEvent } from "@calcom/lib/hideBranding";
import { parseRecurringEvent } from "@calcom/lib/isRecurringEvent";
import { markdownToSafeHTML } from "@calcom/lib/markdownToSafeHTML";
import { maybeGetBookingUidFromSeat } from "@calcom/lib/server/maybeGetBookingUidFromSeat";
import { isTeamAdmin } from "@calcom/lib/server/queries/teams";
import { BookingRepository } from "@calcom/lib/server/repository/booking";
import prisma from "@calcom/prisma";
import { customInputSchema } from "@calcom/prisma/zod-utils";
Expand Down Expand Up @@ -176,6 +177,14 @@ export async function getServerSideProps(context: GetServerSidePropsContext) {

const isLoggedInUserHost = checkIfUserIsHost(userId);

const isLoggedInUserTeamAdmin = !!(
userId &&
((eventType.team?.id && (await isTeamAdmin(userId, eventType.team.id))) ||
(eventType.parent?.teamId && (await isTeamAdmin(userId, eventType.parent.teamId))))
);

const canViewHiddenData = isLoggedInUserHost || isLoggedInUserTeamAdmin;

if (bookingInfo !== null && eventType.seatsPerTimeSlot) {
await handleSeatsEventTypeOnBooking(eventType, bookingInfo, seatReferenceUid, isLoggedInUserHost);
}
Expand All @@ -194,8 +203,7 @@ export async function getServerSideProps(context: GetServerSidePropsContext) {
},
});

if (!isLoggedInUserHost) {
// Removing hidden fields from responses
if (!canViewHiddenData) {
for (const key in bookingInfo.responses) {
const field = eventTypeRaw.bookingFields.find((field) => field.name === key);
if (field && !!field.hidden) {
Expand All @@ -207,7 +215,7 @@ export async function getServerSideProps(context: GetServerSidePropsContext) {
const { currentOrgDomain } = orgDomainConfig(context.req);

async function getInternalNotePresets(teamId: number | null) {
if (!teamId || !isLoggedInUserHost) return [];
if (!teamId || !canViewHiddenData) return [];
return await prisma.internalNotePreset.findMany({
where: {
teamId,
Expand Down Expand Up @@ -256,6 +264,7 @@ export async function getServerSideProps(context: GetServerSidePropsContext) {
requiresLoginToUpdate,
rescheduledToUid,
isLoggedInUserHost,
canViewHiddenData,
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

🧩 Analysis chain

LGTM: Exposing canViewHiddenData in SSR props

Matches server-side sanitization flow; just ensure all client UIs use this flag instead of isHost for hidden fields/UTMs.

To double-check client usage:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Call sites of canViewHiddenData:"
rg -nP -C2 '\bcanViewHiddenData\b' --type=ts --type=tsx || true

echo
echo "Leftover UI gates using isLoggedInUserHost:"
rg -nP -C2 '\bisLoggedInUserHost\b' apps/web || true

Length of output: 2508


Use canViewHiddenData in client UI (replace isLoggedInUserHost)

SSR now returns canViewHiddenData, but the client still reads props.isLoggedInUserHost — update UI gates to use props.canViewHiddenData for hidden fields/UTMs.

Locations:

  • apps/web/modules/bookings/views/bookings-single-view.tsx — ~line 162 (const isHost = props.isLoggedInUserHost)
  • apps/web/modules/bookings/views/bookings-single-view.getServerSideProps.tsx — ~lines 266–267 (returns isLoggedInUserHost and canViewHiddenData)
🤖 Prompt for AI Agents
In apps/web/modules/bookings/views/bookings-single-view.tsx around line ~162 and
apps/web/modules/bookings/views/bookings-single-view.getServerSideProps.tsx
around lines 266–267, the UI still reads props.isLoggedInUserHost to gate hidden
fields/UTMs even though SSR now returns canViewHiddenData; update the component
to derive isHost (or any gate variable) from props.canViewHiddenData instead of
props.isLoggedInUserHost, and remove/stop returning/using isLoggedInUserHost
where it's deprecated — ensure all conditional checks that previously used
isLoggedInUserHost now use canViewHiddenData so hidden fields render according
to the new SSR prop.

internalNotePresets: internalNotes,
},
};
Expand Down
19 changes: 13 additions & 6 deletions apps/web/modules/bookings/views/bookings-single-view.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,14 @@ export default function Success(props: PageProps) {
const pathname = usePathname();
const searchParams = useCompatSearchParams();

const { eventType, bookingInfo, previousBooking, requiresLoginToUpdate, rescheduledToUid } = props;
const {
eventType,
bookingInfo,
previousBooking,
requiresLoginToUpdate,
rescheduledToUid,
canViewHiddenData,
} = props;

const {
allRemainingBookings,
Expand Down Expand Up @@ -378,7 +385,7 @@ export default function Success(props: PageProps) {
const isRescheduled = bookingInfo?.rescheduled;

const canCancelOrReschedule = !eventType?.disableCancelling || !eventType?.disableRescheduling;
const canCancelAndReschedule = !eventType?.disableCancelling && !eventType?.disableRescheduling;
const _canCancelAndReschedule = !eventType?.disableCancelling && !eventType?.disableRescheduling;

const canCancel = !eventType?.disableCancelling;
const canReschedule = !eventType?.disableRescheduling;
Expand Down Expand Up @@ -464,7 +471,7 @@ export default function Success(props: PageProps) {
{!isFeedbackMode && (
<>
<div
className={classNames(isRoundRobin && "min-w-32 min-h-24 relative mx-auto h-24 w-32")}>
className={classNames(isRoundRobin && "min-w-22 w-22 relative mx-auto h-24 min-h-24")}>
{isRoundRobin && bookingInfo.user && (
<Avatar
className="mx-auto flex items-center justify-center"
Expand Down Expand Up @@ -550,7 +557,7 @@ export default function Success(props: PageProps) {
</h4>
)}

<div className="border-subtle text-default mt-8 grid grid-cols-3 gap-x-4 border-t pt-8 text-left rtl:text-right sm:gap-x-0">
<div className="border-subtle text-default mt-2 grid grid-cols-2 gap-x-4 border-t pt-2 text-left rtl:text-right">
{(isCancelled || reschedule) && cancellationReason && (
<>
<div className="font-medium">
Expand Down Expand Up @@ -700,7 +707,7 @@ export default function Success(props: PageProps) {
</div>
</>
)}
{!!utmParams && isHost && (
{!!utmParams && canViewHiddenData && (
<>
<div className="mt-9 pr-2 font-medium sm:pr-0">{t("utm_params")}</div>
<div className="col-span-2 mb-2 ml-3 mt-9 sm:ml-0">
Expand Down Expand Up @@ -1074,7 +1081,7 @@ export default function Success(props: PageProps) {
</div>
{isGmail && !isFeedbackMode && (
<Alert
className="main -mb-20 mt-4 inline-block ltr:text-left rtl:text-right sm:-mt-4 sm:mb-4 sm:w-full sm:max-w-xl sm:align-middle"
className="main -mb-20 mt-4 inline-block ltr:text-left rtl:text-right"
severity="warning"
message={
<div>
Expand Down
Loading