diff --git a/README.md b/README.md index ad6c3a78ab..009ac0dd0d 100644 --- a/README.md +++ b/README.md @@ -180,7 +180,15 @@ See { + const { + query: { key }, + }: { query: { key?: string } } = req; + // If no custom api Id is provided, attach to request the regular cal.com prisma client. + if (!key) { + req.prisma = prisma; + await next(); + } else { + // If we have a key, we check if the deployment matching the key, has a databaseUrl value set. + const databaseUrl = await fetch( + `${process.env.NEXT_PUBLIC_CONSOLE_URL || CONSOLE_URL}/api/deployments/database?key=${key}` + ) + .then((res) => res.json()) + .then((res) => res.databaseUrl); + + if (!databaseUrl) { + res.status(400).json({ error: "no databaseUrl set up at your instance yet" }); + return; + } + // FIXME: Add some checks for the databaseUrl to make sure it is valid. (e.g. not a localhost) + const hashedUrl = await hash(databaseUrl, 12); + + const cachedPrisma = cache.get(hashedUrl); + /* We cache each cusotm prisma client for 24h to avoid too many requests to the database. */ + if (!cachedPrisma) { + cache.put( + hashedUrl, + customPrisma({ datasources: { db: { url: databaseUrl } } }), + PRISMA_CLIENT_CACHING_TIME // Cache the prisma client for 24 hours + ); + } + req.prisma = customPrisma({ datasources: { db: { url: databaseUrl } } }); + /* @note: + In order to skip verifyApiKey for customPrisma requests, + we pass isAdmin true, and userId 0, if we detect them later, + we skip verifyApiKey logic and pass onto next middleware instead. + */ + req.isAdmin = true; + req.userId = 0; + } + await next(); +}; diff --git a/lib/helpers/extendRequest.ts b/lib/helpers/extendRequest.ts new file mode 100644 index 0000000000..8ed3ee0571 --- /dev/null +++ b/lib/helpers/extendRequest.ts @@ -0,0 +1,22 @@ +import type { IncomingMessage } from "http"; +import { NextMiddleware } from "next-api-middleware"; + +import type { PrismaClient } from "@calcom/prisma/client"; + +/** @todo figure how to use the one from `@calcom/types` */ +/** @todo: remove once `@calcom/types` is updated with it.*/ +declare module "next" { + export interface NextApiRequest extends IncomingMessage { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + body: any; + userId: number; + method: string; + prisma: PrismaClient; + session: { user: { id: number } }; + query: { [key: string]: string | string[] }; + isAdmin: boolean; + } +} +export const extendRequest: NextMiddleware = async (req, res, next) => { + await next(); +}; diff --git a/lib/helpers/verifyApiKey.ts b/lib/helpers/verifyApiKey.ts index 08c0216737..4a375aee26 100644 --- a/lib/helpers/verifyApiKey.ts +++ b/lib/helpers/verifyApiKey.ts @@ -1,24 +1,9 @@ -import type { IncomingMessage } from "http"; import { NextMiddleware } from "next-api-middleware"; import { hashAPIKey } from "@calcom/ee/lib/api/apiKeys"; -import prisma from "@calcom/prisma"; import { isAdminGuard } from "@lib/utils/isAdmin"; -/** @todo figure how to use the one from `@calcom/types`fi */ -/** @todo: remove once `@calcom/types` is updated with it.*/ -declare module "next" { - export interface NextApiRequest extends IncomingMessage { - userId: number; - method: string; - isAdmin: boolean; - query: { [key: string]: string | string[] }; - // eslint-disable-next-line @typescript-eslint/no-explicit-any - session: any; - } -} - // Used to check if the apiKey is not expired, could be extracted if reused. but not for now. export const dateNotInPast = function (date: Date) { const now = new Date(); @@ -29,23 +14,30 @@ export const dateNotInPast = function (date: Date) { // This verifies the apiKey and sets the user if it is valid. export const verifyApiKey: NextMiddleware = async (req, res, next) => { + const { prisma, userId, isAdmin } = req; + // If the user is an admin and using a license key (from customPrisma), skip the apiKey check. + if (userId === 0 && isAdmin) { + await next(); + return; + } + // Check if the apiKey query param is provided. if (!req.query.apiKey) return res.status(401).json({ message: "No apiKey provided" }); - // We remove the prefix from the user provided api_key. If no env set default to "cal_" + // remove the prefix from the user provided api_key. If no env set default to "cal_" const strippedApiKey = `${req.query.apiKey}`.replace(process.env.API_KEY_PREFIX || "cal_", ""); // Hash the key again before matching against the database records. const hashedKey = hashAPIKey(strippedApiKey); // Check if the hashed api key exists in database. const apiKey = await prisma.apiKey.findUnique({ where: { hashedKey } }); - // If we cannot find any api key. Throw a 401 Unauthorized. + // If cannot find any api key. Throw a 401 Unauthorized. if (!apiKey) return res.status(401).json({ error: "Your apiKey is not valid" }); if (apiKey.expiresAt && dateNotInPast(apiKey.expiresAt)) { return res.status(401).json({ error: "This apiKey is expired" }); } if (!apiKey.userId) return res.status(404).json({ error: "No user found for this apiKey" }); - /* We save the user id in the request for later use */ + // save the user id in the request for later use req.userId = apiKey.userId; - /* We save the isAdmin boolean here for later use */ - req.isAdmin = await isAdminGuard(req.userId); + // save the isAdmin boolean here for later use + req.isAdmin = await isAdminGuard(req.userId, prisma); await next(); }; diff --git a/lib/helpers/withMiddleware.ts b/lib/helpers/withMiddleware.ts index c926eff4ec..ab6d5cb79e 100644 --- a/lib/helpers/withMiddleware.ts +++ b/lib/helpers/withMiddleware.ts @@ -2,6 +2,8 @@ import { label } from "next-api-middleware"; import { addRequestId } from "./addRequestid"; import { captureErrors } from "./captureErrors"; +import { customPrismaClient } from "./customPrisma"; +import { extendRequest } from "./extendRequest"; import { HTTP_POST, HTTP_DELETE, @@ -22,9 +24,12 @@ const withMiddleware = label( HTTP_DELETE, addRequestId, verifyApiKey, + customPrismaClient, + extendRequest, sentry: captureErrors, }, - ["sentry", "verifyApiKey", "addRequestId"] // <-- Provide a list of middleware to call automatically + // The order here, determines the order of execution, put customPrismaClient before verifyApiKey always. + ["extendRequest", "sentry", "customPrismaClient", "verifyApiKey", "addRequestId"] // <-- Provide a list of middleware to call automatically ); export { withMiddleware }; diff --git a/lib/utils/isAdmin.ts b/lib/utils/isAdmin.ts index 64af37367f..aab1454b62 100644 --- a/lib/utils/isAdmin.ts +++ b/lib/utils/isAdmin.ts @@ -1,8 +1,6 @@ -import { UserPermissionRole } from "@prisma/client"; +import { PrismaClient, UserPermissionRole } from "@prisma/client"; -import prisma from "@calcom/prisma"; - -export const isAdminGuard = async (userId: number) => { +export const isAdminGuard = async (userId: number, prisma: PrismaClient) => { const user = await prisma.user.findUnique({ where: { id: userId } }); return user?.role === UserPermissionRole.ADMIN; }; diff --git a/lib/utils/webhookSubscriptions.ts b/lib/utils/webhookSubscriptions.ts index bdf9d95576..e53b15e7c5 100644 --- a/lib/utils/webhookSubscriptions.ts +++ b/lib/utils/webhookSubscriptions.ts @@ -7,7 +7,7 @@ export type GetSubscriberOptions = { eventTypeId: number; triggerEvent: WebhookTriggerEvents; }; - +/** @note will this not work with custom prisma? since we're importing prisma directly and not passing it from request here **/ const getWebhooks = async (options: GetSubscriberOptions) => { const { userId, eventTypeId } = options; const allWebhooks = await prisma.webhook.findMany({ diff --git a/package.json b/package.json index efd55309d7..c806055f00 100644 --- a/package.json +++ b/package.json @@ -18,6 +18,7 @@ }, "devDependencies": { "@calcom/tsconfig": "*", + "@calcom/types": "*", "babel-jest": "^28.1.0", "jest": "^28.1.0", "node-mocks-http": "^1.11.0" @@ -26,6 +27,8 @@ "@calcom/app-store-cli": "*", "@calcom/prisma": "*", "@sentry/nextjs": "^6.19.7", + "bcryptjs": "^2.4.3", + "memory-cache": "^0.2.0", "modify-response-middleware": "^1.1.0", "next": "^12.1.6", "next-api-middleware": "^1.0.1", diff --git a/pages/api/attendees/[id].ts b/pages/api/attendees/[id].ts index a72dbf5812..d7e927e36e 100644 --- a/pages/api/attendees/[id].ts +++ b/pages/api/attendees/[id].ts @@ -1,7 +1,5 @@ import type { NextApiRequest, NextApiResponse } from "next"; -import prisma from "@calcom/prisma"; - import { withMiddleware } from "@lib/helpers/withMiddleware"; import type { AttendeeResponse } from "@lib/types"; import { schemaAttendeeEditBodyParams, schemaAttendeeReadPublic } from "@lib/validations/attendee"; @@ -11,7 +9,7 @@ import { } from "@lib/validations/shared/queryIdTransformParseInt"; export async function attendeeById( - { method, query, body, userId, isAdmin }: NextApiRequest, + { method, query, body, userId, isAdmin, prisma }: NextApiRequest, res: NextApiResponse ) { const safeQuery = schemaQueryIdParseInt.safeParse(query); diff --git a/pages/api/attendees/index.ts b/pages/api/attendees/index.ts index e4f3e54f79..880c8d4d4b 100644 --- a/pages/api/attendees/index.ts +++ b/pages/api/attendees/index.ts @@ -1,13 +1,11 @@ import type { NextApiRequest, NextApiResponse } from "next"; -import prisma from "@calcom/prisma"; - import { withMiddleware } from "@lib/helpers/withMiddleware"; -import { AttendeeResponse, AttendeesResponse } from "@lib/types"; +import type { AttendeeResponse, AttendeesResponse } from "@lib/types"; import { schemaAttendeeCreateBodyParams, schemaAttendeeReadPublic } from "@lib/validations/attendee"; async function createOrlistAllAttendees( - { method, userId, body, isAdmin }: NextApiRequest, + { method, userId, body, prisma, isAdmin }: NextApiRequest, res: NextApiResponse ) { let attendees; @@ -138,13 +136,7 @@ async function createOrlistAllAttendees( attendee, message: "Attendee created successfully", }); - } else { - (error: Error) => - res.status(400).json({ - message: "Could not create new attendee", - error, - }); - } + } else (error: Error) => res.status(400).json({ error }); } } else res.status(405).json({ message: `Method ${method} not allowed` }); } diff --git a/pages/api/availabilities/[id].ts b/pages/api/availabilities/[id].ts index 0b6a58c338..1d4b6ed4a1 100644 --- a/pages/api/availabilities/[id].ts +++ b/pages/api/availabilities/[id].ts @@ -1,7 +1,5 @@ import type { NextApiRequest, NextApiResponse } from "next"; -import prisma from "@calcom/prisma"; - import { withMiddleware } from "@lib/helpers/withMiddleware"; import type { AvailabilityResponse } from "@lib/types"; import { @@ -14,7 +12,7 @@ import { } from "@lib/validations/shared/queryIdTransformParseInt"; export async function availabilityById( - { method, query, body, userId }: NextApiRequest, + { method, query, body, userId, prisma }: NextApiRequest, res: NextApiResponse ) { const safeQuery = schemaQueryIdParseInt.safeParse(query); diff --git a/pages/api/availabilities/index.ts b/pages/api/availabilities/index.ts index bf17bd1ede..ab4ae8f73b 100644 --- a/pages/api/availabilities/index.ts +++ b/pages/api/availabilities/index.ts @@ -1,7 +1,5 @@ import type { NextApiRequest, NextApiResponse } from "next"; -import prisma from "@calcom/prisma"; - import { withMiddleware } from "@lib/helpers/withMiddleware"; import { AvailabilityResponse, AvailabilitiesResponse } from "@lib/types"; import { @@ -10,7 +8,7 @@ import { } from "@lib/validations/availability"; async function createOrlistAllAvailabilities( - { method, body, userId }: NextApiRequest, + { method, body, userId, prisma }: NextApiRequest, res: NextApiResponse ) { if (method === "GET") { diff --git a/pages/api/booking-references/[id].ts b/pages/api/booking-references/[id].ts index f7a14056eb..17e444d717 100644 --- a/pages/api/booking-references/[id].ts +++ b/pages/api/booking-references/[id].ts @@ -1,7 +1,5 @@ import type { NextApiRequest, NextApiResponse } from "next"; -import prisma from "@calcom/prisma"; - import { withMiddleware } from "@lib/helpers/withMiddleware"; import type { BookingReferenceResponse } from "@lib/types"; import { @@ -14,7 +12,7 @@ import { } from "@lib/validations/shared/queryIdTransformParseInt"; export async function bookingReferenceById( - { method, query, body, userId }: NextApiRequest, + { method, query, body, userId, prisma }: NextApiRequest, res: NextApiResponse ) { const safeQuery = schemaQueryIdParseInt.safeParse(query); @@ -64,7 +62,6 @@ export async function bookingReferenceById( .then((data) => schemaBookingReferenceReadPublic.parse(data)) .then((booking_reference) => res.status(200).json({ booking_reference })) .catch((error: Error) => { - console.log(error); res.status(404).json({ message: `BookingReference with id: ${safeQuery.data.id} not found`, error, diff --git a/pages/api/booking-references/index.ts b/pages/api/booking-references/index.ts index 58e45d5c9e..5c63a605b7 100644 --- a/pages/api/booking-references/index.ts +++ b/pages/api/booking-references/index.ts @@ -1,7 +1,5 @@ import type { NextApiRequest, NextApiResponse } from "next"; -import prisma from "@calcom/prisma"; - import { withMiddleware } from "@lib/helpers/withMiddleware"; import { BookingReferenceResponse, BookingReferencesResponse } from "@lib/types"; import { @@ -10,7 +8,7 @@ import { } from "@lib/validations/booking-reference"; async function createOrlistAllBookingReferences( - { method, userId, body }: NextApiRequest, + { method, userId, body, prisma }: NextApiRequest, res: NextApiResponse ) { const userWithBookings = await prisma.user.findUnique({ diff --git a/pages/api/bookings/[id].ts b/pages/api/bookings/[id].ts index 8603af73c8..f4f11b143f 100644 --- a/pages/api/bookings/[id].ts +++ b/pages/api/bookings/[id].ts @@ -1,7 +1,5 @@ import type { NextApiRequest, NextApiResponse } from "next"; -import prisma from "@calcom/prisma"; - import { withMiddleware } from "@lib/helpers/withMiddleware"; import type { BookingResponse } from "@lib/types"; import { schemaBookingEditBodyParams, schemaBookingReadPublic } from "@lib/validations/booking"; @@ -11,7 +9,7 @@ import { } from "@lib/validations/shared/queryIdTransformParseInt"; export async function bookingById( - { method, query, body, userId, isAdmin }: NextApiRequest, + { method, query, body, userId, prisma, isAdmin }: NextApiRequest, res: NextApiResponse ) { const safeQuery = schemaQueryIdParseInt.safeParse(query); diff --git a/pages/api/bookings/index.ts b/pages/api/bookings/index.ts index 560bca7b8e..fb1fd347aa 100644 --- a/pages/api/bookings/index.ts +++ b/pages/api/bookings/index.ts @@ -2,8 +2,6 @@ import { WebhookTriggerEvents } from "@prisma/client"; import type { NextApiRequest, NextApiResponse } from "next"; import { v4 as uuidv4 } from "uuid"; -import prisma from "@calcom/prisma"; - import { withMiddleware } from "@lib/helpers/withMiddleware"; import { BookingResponse, BookingsResponse } from "@lib/types"; import sendPayload from "@lib/utils/sendPayload"; @@ -12,10 +10,9 @@ import { schemaBookingCreateBodyParams, schemaBookingReadPublic } from "@lib/val import { schemaEventTypeReadPublic } from "@lib/validations/event-type"; async function createOrlistAllBookings( - { method, body, userId, isAdmin }: NextApiRequest, + { method, body, userId, isAdmin, prisma }: NextApiRequest, res: NextApiResponse ) { - console.log("userIduserId", userId); if (method === "GET") { /** * @swagger diff --git a/pages/api/custom-inputs/[id].ts b/pages/api/custom-inputs/[id].ts index 7423a10b99..5b778714ad 100644 --- a/pages/api/custom-inputs/[id].ts +++ b/pages/api/custom-inputs/[id].ts @@ -1,7 +1,5 @@ import type { NextApiRequest, NextApiResponse } from "next"; -import prisma from "@calcom/prisma"; - import { withMiddleware } from "@lib/helpers/withMiddleware"; import type { EventTypeCustomInputResponse } from "@lib/types"; import { @@ -72,7 +70,7 @@ import { * description: Authorization information is missing or invalid. */ async function eventTypeById( - { method, query, body, userId }: NextApiRequest, + { method, query, body, userId, prisma }: NextApiRequest, res: NextApiResponse ) { const safeQuery = schemaQueryIdParseInt.safeParse(query); diff --git a/pages/api/custom-inputs/index.ts b/pages/api/custom-inputs/index.ts index e1c2d484ed..17500249aa 100644 --- a/pages/api/custom-inputs/index.ts +++ b/pages/api/custom-inputs/index.ts @@ -1,7 +1,5 @@ import type { NextApiRequest, NextApiResponse } from "next"; -import prisma from "@calcom/prisma"; - import { withMiddleware } from "@lib/helpers/withMiddleware"; import { EventTypeCustomInputResponse, EventTypeCustomInputsResponse } from "@lib/types"; import { @@ -10,7 +8,7 @@ import { } from "@lib/validations/event-type-custom-input"; async function createOrlistAllEventTypeCustomInputs( - { userId, method, body }: NextApiRequest, + { userId, method, body, prisma }: NextApiRequest, res: NextApiResponse ) { const data = await prisma.eventType.findMany({ where: { userId } }); diff --git a/pages/api/destination-calendars/[id].ts b/pages/api/destination-calendars/[id].ts index 528b9e5f2d..307e2634ba 100644 --- a/pages/api/destination-calendars/[id].ts +++ b/pages/api/destination-calendars/[id].ts @@ -1,7 +1,5 @@ import type { NextApiRequest, NextApiResponse } from "next"; -import prisma from "@calcom/prisma"; - import { withMiddleware } from "@lib/helpers/withMiddleware"; import type { DestinationCalendarResponse } from "@lib/types"; import { @@ -14,7 +12,7 @@ import { } from "@lib/validations/shared/queryIdTransformParseInt"; export async function destionationCalendarById( - { method, query, body, userId }: NextApiRequest, + { method, query, body, userId, prisma }: NextApiRequest, res: NextApiResponse ) { const safeQuery = schemaQueryIdParseInt.safeParse(query); diff --git a/pages/api/destination-calendars/index.ts b/pages/api/destination-calendars/index.ts index bfd7df6d89..5fced320d9 100644 --- a/pages/api/destination-calendars/index.ts +++ b/pages/api/destination-calendars/index.ts @@ -1,7 +1,5 @@ import type { NextApiRequest, NextApiResponse } from "next"; -import prisma from "@calcom/prisma"; - import { withMiddleware } from "@lib/helpers/withMiddleware"; import { DestinationCalendarResponse, DestinationCalendarsResponse } from "@lib/types"; import { @@ -10,7 +8,7 @@ import { } from "@lib/validations/destination-calendar"; async function createOrlistAllDestinationCalendars( - { method, body, userId }: NextApiRequest, + { method, body, userId, prisma }: NextApiRequest, res: NextApiResponse ) { if (method === "GET") { diff --git a/pages/api/event-references/[id].ts b/pages/api/event-references/[id].ts index 7a72fea4c7..58bc27599d 100644 --- a/pages/api/event-references/[id].ts +++ b/pages/api/event-references/[id].ts @@ -1,7 +1,5 @@ import type { NextApiRequest, NextApiResponse } from "next"; -import prisma from "@calcom/prisma"; - import { withMiddleware } from "@lib/helpers/withMiddleware"; import type { DailyEventReferenceResponse } from "@lib/types"; import { @@ -14,7 +12,7 @@ import { } from "@lib/validations/shared/queryIdTransformParseInt"; export async function dailyEventReferenceById( - { method, query, body, userId }: NextApiRequest, + { method, query, body, userId, prisma }: NextApiRequest, res: NextApiResponse ) { const safeQuery = schemaQueryIdParseInt.safeParse(query); diff --git a/pages/api/event-references/index.ts b/pages/api/event-references/index.ts index 48a438e321..449737cd06 100644 --- a/pages/api/event-references/index.ts +++ b/pages/api/event-references/index.ts @@ -1,7 +1,5 @@ import type { NextApiRequest, NextApiResponse } from "next"; -import prisma from "@calcom/prisma"; - import { withMiddleware } from "@lib/helpers/withMiddleware"; import { DailyEventReferenceResponse, DailyEventReferencesResponse } from "@lib/types"; import { @@ -10,7 +8,7 @@ import { } from "@lib/validations/event-reference"; async function createOrlistAllDailyEventReferences( - { method, body, userId }: NextApiRequest, + { method, body, userId, prisma }: NextApiRequest, res: NextApiResponse ) { const userBookings = await prisma.booking.findMany({ where: { userId } }); diff --git a/pages/api/event-types/[id].ts b/pages/api/event-types/[id].ts index 013f9909be..dd9ac1a4d9 100644 --- a/pages/api/event-types/[id].ts +++ b/pages/api/event-types/[id].ts @@ -1,7 +1,5 @@ import type { NextApiRequest, NextApiResponse } from "next"; -import prisma from "@calcom/prisma"; - import { withMiddleware } from "@lib/helpers/withMiddleware"; import type { EventTypeResponse } from "@lib/types"; import { schemaEventTypeEditBodyParams, schemaEventTypeReadPublic } from "@lib/validations/event-type"; @@ -11,7 +9,7 @@ import { } from "@lib/validations/shared/queryIdTransformParseInt"; export async function eventTypeById( - { method, query, body, userId, isAdmin }: NextApiRequest, + { method, query, body, userId, isAdmin, prisma }: NextApiRequest, res: NextApiResponse ) { const safeQuery = schemaQueryIdParseInt.safeParse(query); diff --git a/pages/api/event-types/index.ts b/pages/api/event-types/index.ts index dc6844e039..b3a9d74138 100644 --- a/pages/api/event-types/index.ts +++ b/pages/api/event-types/index.ts @@ -1,13 +1,11 @@ import type { NextApiRequest, NextApiResponse } from "next"; -import prisma from "@calcom/prisma"; - import { withMiddleware } from "@lib/helpers/withMiddleware"; import { EventTypeResponse, EventTypesResponse } from "@lib/types"; import { schemaEventTypeCreateBodyParams, schemaEventTypeReadPublic } from "@lib/validations/event-type"; async function createOrlistAllEventTypes( - { method, body, userId, isAdmin }: NextApiRequest, + { method, body, userId, isAdmin, prisma }: NextApiRequest, res: NextApiResponse ) { if (method === "GET") { diff --git a/pages/api/hooks/[id].ts b/pages/api/hooks/[id].ts index 8f81fc62d1..4c0e51ab69 100644 --- a/pages/api/hooks/[id].ts +++ b/pages/api/hooks/[id].ts @@ -1,14 +1,12 @@ import type { NextApiRequest, NextApiResponse } from "next"; -import prisma from "@calcom/prisma"; - import { withMiddleware } from "@lib/helpers/withMiddleware"; import type { WebhookResponse } from "@lib/types"; import { schemaQueryIdAsString } from "@lib/validations/shared/queryIdString"; import { schemaWebhookEditBodyParams, schemaWebhookReadPublic } from "@lib/validations/webhook"; export async function WebhookById( - { method, query, body, userId }: NextApiRequest, + { method, query, body, userId, prisma }: NextApiRequest, res: NextApiResponse ) { const safeQuery = schemaQueryIdAsString.safeParse(query); diff --git a/pages/api/hooks/index.ts b/pages/api/hooks/index.ts index ec85ab13df..0bdb7470bf 100644 --- a/pages/api/hooks/index.ts +++ b/pages/api/hooks/index.ts @@ -1,14 +1,12 @@ import type { NextApiRequest, NextApiResponse } from "next"; import { v4 as uuidv4 } from "uuid"; -import prisma from "@calcom/prisma"; - import { withMiddleware } from "@lib/helpers/withMiddleware"; import { WebhookResponse, WebhooksResponse } from "@lib/types"; import { schemaWebhookCreateBodyParams } from "@lib/validations/webhook"; async function createOrlistAllWebhooks( - { method, body, userId }: NextApiRequest, + { method, body, userId, prisma }: NextApiRequest, res: NextApiResponse ) { if (method === "GET") { diff --git a/pages/api/memberships/[id].ts b/pages/api/memberships/[id].ts index ea99860d14..b6050ebbe9 100644 --- a/pages/api/memberships/[id].ts +++ b/pages/api/memberships/[id].ts @@ -1,14 +1,12 @@ import type { NextApiRequest, NextApiResponse } from "next"; -import prisma from "@calcom/prisma"; - import { withMiddleware } from "@lib/helpers/withMiddleware"; import type { MembershipResponse } from "@lib/types"; import { schemaMembershipBodyParams, schemaMembershipPublic } from "@lib/validations/membership"; import { schemaQueryIdAsString, withValidQueryIdString } from "@lib/validations/shared/queryIdString"; export async function membershipById( - { method, query, body, userId }: NextApiRequest, + { method, query, body, userId, prisma }: NextApiRequest, res: NextApiResponse ) { const safeQuery = schemaQueryIdAsString.safeParse(query); diff --git a/pages/api/memberships/index.ts b/pages/api/memberships/index.ts index efd3fb278c..5aaa36f6db 100644 --- a/pages/api/memberships/index.ts +++ b/pages/api/memberships/index.ts @@ -1,13 +1,11 @@ import type { NextApiRequest, NextApiResponse } from "next"; -import prisma from "@calcom/prisma"; - import { withMiddleware } from "@lib/helpers/withMiddleware"; import { MembershipResponse, MembershipsResponse } from "@lib/types"; import { schemaMembershipBodyParams, schemaMembershipPublic } from "@lib/validations/membership"; async function createOrlistAllMemberships( - { method, body, userId }: NextApiRequest, + { method, body, userId, prisma }: NextApiRequest, res: NextApiResponse ) { if (method === "GET") { diff --git a/pages/api/payments/[id].ts b/pages/api/payments/[id].ts index 99d515fe45..26f2138536 100644 --- a/pages/api/payments/[id].ts +++ b/pages/api/payments/[id].ts @@ -1,7 +1,5 @@ import type { NextApiRequest, NextApiResponse } from "next"; -import prisma from "@calcom/prisma"; - import { withMiddleware } from "@lib/helpers/withMiddleware"; import type { PaymentResponse } from "@lib/types"; import { schemaPaymentPublic } from "@lib/validations/payment"; @@ -33,7 +31,7 @@ import { * description: Payment was not found */ export async function paymentById( - { method, query, userId }: NextApiRequest, + { method, query, userId, prisma }: NextApiRequest, res: NextApiResponse ) { const safeQuery = schemaQueryIdParseInt.safeParse(query); diff --git a/pages/api/payments/index.ts b/pages/api/payments/index.ts index d758421f46..829d24681d 100644 --- a/pages/api/payments/index.ts +++ b/pages/api/payments/index.ts @@ -1,7 +1,5 @@ import type { NextApiRequest, NextApiResponse } from "next"; -import prisma from "@calcom/prisma"; - import { withMiddleware } from "@lib/helpers/withMiddleware"; import { PaymentsResponse } from "@lib/types"; import { schemaPaymentPublic } from "@lib/validations/payment"; @@ -21,7 +19,7 @@ import { schemaPaymentPublic } from "@lib/validations/payment"; * 404: * description: No payments were found */ -async function allPayments({ userId }: NextApiRequest, res: NextApiResponse) { +async function allPayments({ userId, prisma }: NextApiRequest, res: NextApiResponse) { const userWithBookings = await prisma.user.findUnique({ where: { id: userId }, include: { bookings: true }, diff --git a/pages/api/schedules/[id].ts b/pages/api/schedules/[id].ts index 305cc5c51b..593f9d7846 100644 --- a/pages/api/schedules/[id].ts +++ b/pages/api/schedules/[id].ts @@ -1,7 +1,5 @@ import type { NextApiRequest, NextApiResponse } from "next"; -import prisma from "@calcom/prisma"; - import { withMiddleware } from "@lib/helpers/withMiddleware"; import type { ScheduleResponse } from "@lib/types"; import { schemaScheduleBodyParams, schemaSchedulePublic } from "@lib/validations/schedule"; @@ -11,7 +9,7 @@ import { } from "@lib/validations/shared/queryIdTransformParseInt"; export async function scheduleById( - { method, query, body, userId }: NextApiRequest, + { method, query, body, userId, prisma }: NextApiRequest, res: NextApiResponse ) { const safeQuery = schemaQueryIdParseInt.safeParse(query); diff --git a/pages/api/schedules/index.ts b/pages/api/schedules/index.ts index 4421844047..81964f4030 100644 --- a/pages/api/schedules/index.ts +++ b/pages/api/schedules/index.ts @@ -1,13 +1,11 @@ import type { NextApiRequest, NextApiResponse } from "next"; -import prisma from "@calcom/prisma"; - import { withMiddleware } from "@lib/helpers/withMiddleware"; import { ScheduleResponse, SchedulesResponse } from "@lib/types"; import { schemaScheduleBodyParams, schemaSchedulePublic } from "@lib/validations/schedule"; async function createOrlistAllSchedules( - { method, body, userId }: NextApiRequest, + { method, body, userId, prisma }: NextApiRequest, res: NextApiResponse ) { if (method === "GET") { diff --git a/pages/api/selected-calendars/[id].ts b/pages/api/selected-calendars/[id].ts index 88dca61806..ea2037fba3 100644 --- a/pages/api/selected-calendars/[id].ts +++ b/pages/api/selected-calendars/[id].ts @@ -1,7 +1,5 @@ import type { NextApiRequest, NextApiResponse } from "next"; -import prisma from "@calcom/prisma"; - import { withMiddleware } from "@lib/helpers/withMiddleware"; import type { SelectedCalendarResponse } from "@lib/types"; import { @@ -11,7 +9,7 @@ import { import { schemaQueryIdAsString, withValidQueryIdString } from "@lib/validations/shared/queryIdString"; export async function selectedCalendarById( - { method, query, body, userId }: NextApiRequest, + { method, query, body, userId, prisma }: NextApiRequest, res: NextApiResponse ) { const safeQuery = schemaQueryIdAsString.safeParse(query); diff --git a/pages/api/selected-calendars/index.ts b/pages/api/selected-calendars/index.ts index f0021f9f0e..3ab69494a8 100644 --- a/pages/api/selected-calendars/index.ts +++ b/pages/api/selected-calendars/index.ts @@ -1,7 +1,5 @@ import type { NextApiRequest, NextApiResponse } from "next"; -import prisma from "@calcom/prisma"; - import { withMiddleware } from "@lib/helpers/withMiddleware"; import { SelectedCalendarResponse, SelectedCalendarsResponse } from "@lib/types"; import { @@ -10,7 +8,7 @@ import { } from "@lib/validations/selected-calendar"; async function createOrlistAllSelectedCalendars( - { method, body, userId }: NextApiRequest, + { method, body, userId, prisma }: NextApiRequest, res: NextApiResponse ) { if (method === "GET") { diff --git a/pages/api/teams/[id].ts b/pages/api/teams/[id].ts index 2cfd371749..65dd8d116e 100644 --- a/pages/api/teams/[id].ts +++ b/pages/api/teams/[id].ts @@ -1,7 +1,5 @@ import type { NextApiRequest, NextApiResponse } from "next"; -import prisma from "@calcom/prisma"; - import { withMiddleware } from "@lib/helpers/withMiddleware"; import type { TeamResponse } from "@lib/types"; import { @@ -72,7 +70,7 @@ import { schemaTeamBodyParams, schemaTeamPublic } from "@lib/validations/team"; * description: Authorization information is missing or invalid. */ export async function teamById( - { method, query, body, userId }: NextApiRequest, + { method, query, body, userId, prisma }: NextApiRequest, res: NextApiResponse ) { const safeQuery = schemaQueryIdParseInt.safeParse(query); diff --git a/pages/api/teams/index.ts b/pages/api/teams/index.ts index e5f870cef6..1dcc046f6e 100644 --- a/pages/api/teams/index.ts +++ b/pages/api/teams/index.ts @@ -1,14 +1,12 @@ import type { NextApiRequest, NextApiResponse } from "next"; -import prisma from "@calcom/prisma"; - import { withMiddleware } from "@lib/helpers/withMiddleware"; import { TeamResponse, TeamsResponse } from "@lib/types"; import { schemaMembershipPublic } from "@lib/validations/membership"; import { schemaTeamBodyParams, schemaTeamPublic } from "@lib/validations/team"; async function createOrlistAllTeams( - { method, body, userId }: NextApiRequest, + { method, body, userId, prisma }: NextApiRequest, res: NextApiResponse ) { if (method === "GET") { diff --git a/pages/api/users/[userId]/_delete.ts b/pages/api/users/[userId]/_delete.ts index c2d8d5db29..ac15975931 100644 --- a/pages/api/users/[userId]/_delete.ts +++ b/pages/api/users/[userId]/_delete.ts @@ -33,7 +33,7 @@ import { schemaQueryUserId } from "@lib/validations/shared/queryUserId"; */ export async function deleteHandler(req: NextApiRequest) { const query = schemaQueryUserId.parse(req.query); - const isAdmin = await isAdminGuard(req.userId); + const isAdmin = await isAdminGuard(req.userId, req.prisma); // Here we only check for ownership of the user if the user is not admin, otherwise we let ADMIN's edit any user if (!isAdmin && query.userId !== req.userId) throw new HttpError({ statusCode: 401, message: "Unauthorized" }); diff --git a/pages/api/users/[userId]/_get.ts b/pages/api/users/[userId]/_get.ts index 5c76c4e315..2fda8ddc91 100644 --- a/pages/api/users/[userId]/_get.ts +++ b/pages/api/users/[userId]/_get.ts @@ -34,7 +34,7 @@ import { schemaUserReadPublic } from "@lib/validations/user"; */ export async function getHandler(req: NextApiRequest) { const query = schemaQueryUserId.parse(req.query); - const isAdmin = await isAdminGuard(req.userId); + const isAdmin = await isAdminGuard(req.userId, req.prisma); // Here we only check for ownership of the user if the user is not admin, otherwise we let ADMIN's edit any user if (!isAdmin && query.userId !== req.userId) throw new HttpError({ statusCode: 401, message: "Unauthorized" }); diff --git a/pages/api/users/[userId]/_patch.ts b/pages/api/users/[userId]/_patch.ts index 9f32e920c4..58efa5773b 100644 --- a/pages/api/users/[userId]/_patch.ts +++ b/pages/api/users/[userId]/_patch.ts @@ -55,7 +55,7 @@ import { schemaUserEditBodyParams, schemaUserReadPublic } from "@lib/validations */ export async function patchHandler(req: NextApiRequest) { const query = schemaQueryUserId.parse(req.query); - const isAdmin = await isAdminGuard(req.userId); + const isAdmin = await isAdminGuard(req.userId, req.prisma); // Here we only check for ownership of the user if the user is not admin, otherwise we let ADMIN's edit any user if (!isAdmin && query.userId !== req.userId) throw new HttpError({ statusCode: 401, message: "Unauthorized" }); diff --git a/pages/api/users/_get.ts b/pages/api/users/_get.ts index 4c4aadaecd..7f90ba8a27 100644 --- a/pages/api/users/_get.ts +++ b/pages/api/users/_get.ts @@ -24,8 +24,8 @@ import { Prisma } from ".prisma/client"; * 404: * description: No users were found */ -async function getHandler({ userId }: NextApiRequest) { - const isAdmin = await isAdminGuard(userId); +async function getHandler({ userId, prisma }: NextApiRequest) { + const isAdmin = await isAdminGuard(userId, prisma); const where: Prisma.UserWhereInput = {}; // If user is not ADMIN, return only his data. if (!isAdmin) where.id = userId; diff --git a/pages/api/users/_post.ts b/pages/api/users/_post.ts index 908a9c4bcc..2217c49127 100644 --- a/pages/api/users/_post.ts +++ b/pages/api/users/_post.ts @@ -8,7 +8,7 @@ import { isAdminGuard } from "@lib/utils/isAdmin"; import { schemaUserCreateBodyParams } from "@lib/validations/user"; async function postHandler(req: NextApiRequest) { - const isAdmin = await isAdminGuard(req.userId); + const isAdmin = await isAdminGuard(req.userId, req.prisma); // If user is not ADMIN, return unauthorized. if (!isAdmin) throw new HttpError({ statusCode: 401, message: "You are not authorized" }); const data = schemaUserCreateBodyParams.parse(req.body);