From 3bdf4a84f8a0d8c5470e96ea08c664b4ccbee4bd Mon Sep 17 00:00:00 2001 From: sean-brydon <55134778+sean-brydon@users.noreply.github.com> Date: Tue, 26 Jul 2022 19:25:42 +0100 Subject: [PATCH] Prevent team members from creating events (#3498) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Delete CreateEventTypeBtn.tsx * Adding Permission to creation router * Disable button if membership role is member * Fix linting error * Update explicit role selection Co-authored-by: Omar López * Type fix Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> Co-authored-by: Omar López --- .../components/eventtype/CreateEventType.tsx | 126 +++++++++++++----- .../trpc/server/routers/viewer/eventTypes.tsx | 2 +- 2 files changed, 92 insertions(+), 36 deletions(-) diff --git a/apps/web/components/eventtype/CreateEventType.tsx b/apps/web/components/eventtype/CreateEventType.tsx index a8c9317a4c..dae51f87b7 100644 --- a/apps/web/components/eventtype/CreateEventType.tsx +++ b/apps/web/components/eventtype/CreateEventType.tsx @@ -1,11 +1,13 @@ import { ChevronDownIcon, PlusIcon } from "@heroicons/react/solid"; import { zodResolver } from "@hookform/resolvers/zod"; import { SchedulingType } from "@prisma/client"; +import { useSession } from "next-auth/react"; import { useRouter } from "next/router"; import { useEffect } from "react"; import { useForm } from "react-hook-form"; import type { z } from "zod"; +import classNames from "@calcom/lib/classNames"; import { WEBAPP_URL } from "@calcom/lib/constants"; import { useLocale } from "@calcom/lib/hooks/useLocale"; import showToast from "@calcom/lib/notification"; @@ -37,7 +39,7 @@ export interface EventTypeParent { image?: string | null; } -interface Props { +interface CreateEventTypeBtnProps { // set true for use on the team settings page canAddEvents: boolean; // set true when in use on the team settings page @@ -46,7 +48,7 @@ interface Props { options: EventTypeParent[]; } -export default function CreateEventTypeButton(props: Props) { +export default function CreateEventTypeButton(props: CreateEventTypeBtnProps) { const { t } = useLocale(); const router = useRouter(); @@ -142,39 +144,13 @@ export default function CreateEventTypeButton(props: Props) { - {!hasTeams || props.isIndividualTeam ? ( - - ) : ( - - - - - - {t("new_event_subtitle")} - - {props.options.map((option) => ( - openModal(option)}> - - {option.name ? option.name : option.slug} - - ))} - - - )} +
@@ -290,3 +266,83 @@ export default function CreateEventTypeButton(props: Props) {
); } + +type CreateEventTypeTrigger = { + isIndividualTeam?: boolean; + // EventTypeParent can be a profile (as first option) or a team for the rest. + options: EventTypeParent[]; + hasTeams: boolean; + // set true for use on the team settings page + canAddEvents: boolean; + openModal: (option: EventTypeParent) => void; +}; + +export function CreateEventTypeTrigger(props: CreateEventTypeTrigger) { + const { t } = useLocale(); + + return ( + <> + {!props.hasTeams || props.isIndividualTeam ? ( + + ) : ( + + + + + + {t("new_event_subtitle")} + + {props.options.map((option) => ( + props.openModal(option)} + /> + ))} + + + )} + + ); +} + +function CreateEventTeamsItem(props: { + openModal: (option: EventTypeParent) => void; + option: EventTypeParent; +}) { + const session = useSession(); + const membershipQuery = trpc.useQuery([ + "viewer.teams.getMembershipbyUser", + { + memberId: session.data?.user.id as number, + teamId: props.option.teamId as number, + }, + ]); + + const isDisabled = membershipQuery.data?.role === "MEMBER"; + + return ( + props.openModal(props.option)}> + + {props.option.name ? props.option.name : props.option.slug} + + ); +} diff --git a/packages/trpc/server/routers/viewer/eventTypes.tsx b/packages/trpc/server/routers/viewer/eventTypes.tsx index 301c384147..05baeb0420 100644 --- a/packages/trpc/server/routers/viewer/eventTypes.tsx +++ b/packages/trpc/server/routers/viewer/eventTypes.tsx @@ -139,7 +139,7 @@ export const eventTypesRouter = createProtectedRouter() }, }); - if (!hasMembership) { + if (!hasMembership?.role || !["ADMIN", "OWNER"].includes(hasMembership.role)) { console.warn(`User ${userId} does not have permission to create this new event type`); throw new TRPCError({ code: "UNAUTHORIZED" }); }