diff --git a/.env.example b/.env.example new file mode 100644 index 0000000000..f3271e560c --- /dev/null +++ b/.env.example @@ -0,0 +1 @@ +API_KEY_PREFIX=cal_ \ No newline at end of file diff --git a/lib/helpers/addRequestid.ts b/lib/helpers/addRequestid.ts index af151e00cc..263c7aacc1 100644 --- a/lib/helpers/addRequestid.ts +++ b/lib/helpers/addRequestid.ts @@ -2,7 +2,7 @@ import { nanoid } from "nanoid"; import { NextMiddleware } from "next-api-middleware"; export const addRequestId: NextMiddleware = async (_req, res, next) => { - // Apply header + // Apply header with unique ID to every request res.setHeader("Calcom-Response-ID", nanoid()); // Let remaining middleware and API route execute await next(); diff --git a/lib/helpers/captureErrors.ts b/lib/helpers/captureErrors.ts index 109e4e2254..ff35ee3c89 100644 --- a/lib/helpers/captureErrors.ts +++ b/lib/helpers/captureErrors.ts @@ -6,10 +6,9 @@ export const captureErrors: NextMiddleware = async (_req, res, next) => { // Catch any errors that are thrown in remaining // middleware and the API route handler await next(); - } catch (err) { - Sentry.captureException(err); - console.log(err); - res.status(400).json({ message: "Something went wrong", error: err }); - // res.json({ error: err }); + } catch (error) { + Sentry.captureException(error); + console.log(error); + res.status(400).json({ message: "Something went wrong", error }); } }; diff --git a/lib/helpers/verifyApiKey.ts b/lib/helpers/verifyApiKey.ts index 275457d12c..694de73593 100644 --- a/lib/helpers/verifyApiKey.ts +++ b/lib/helpers/verifyApiKey.ts @@ -1,29 +1,34 @@ import { NextMiddleware } from "next-api-middleware"; import { hashAPIKey } from "@calcom/ee/lib/api/apiKeys"; -// import { nanoid } from "nanoid"; import prisma from "@calcom/prisma"; -const dateInPast = function (firstDate: Date, secondDate: Date) { +// Used to check if the API key is not expired, could be extracted if reused. but not for now. +export const dateInPast = function (firstDate: Date, secondDate: Date) { if (firstDate.setHours(0, 0, 0, 0) <= secondDate.setHours(0, 0, 0, 0)) { return true; } }; const today = new Date(); +// This verifies the API key and sets the user if it is valid. export const verifyApiKey: NextMiddleware = async (req, res, next) => { if (!req.query.apiKey) res.status(401).json({ message: "No API key provided" }); - const strippedApiKey = `${req.query.apiKey}`.replace("cal_", ""); + + const strippedApiKey = `${req.query.apiKey}`.replace(process.env.API_KEY_PREFIX || "cal_", ""); const hashedKey = hashAPIKey(strippedApiKey); - const apiKey = await prisma.apiKey.findUnique({ where: { hashedKey } }); - if (!apiKey) { - res.status(401).json({ error: "Your api key is not valid" }); - throw new Error("No api key found"); - } - if (apiKey.userId) { - res.setHeader("X-Calcom-User-ID", apiKey.userId); - } - if (apiKey.expiresAt && apiKey.userId && dateInPast(today, apiKey.expiresAt)) { - await next(); - } else res.status(401).json({ error: "Your api key is not valid" }); + + await prisma.apiKey + .findUnique({ where: { hashedKey } }) + .then(async (apiKey) => { + if (!apiKey) { + res.status(401).json({ error: "You did not provide an api key" }); + throw new Error("No api key found"); + } + if (apiKey.userId) res.setHeader("X-Calcom-User-ID", apiKey?.userId); + if (apiKey.expiresAt && apiKey.userId && dateInPast(today, apiKey.expiresAt)) await next(); + }) + .catch((error) => { + res.status(401).json({ error: "Your api key is not valid" }); + }); }; diff --git a/lib/helpers/withCost.ts b/lib/helpers/withCost.ts deleted file mode 100644 index d462536956..0000000000 --- a/lib/helpers/withCost.ts +++ /dev/null @@ -1,23 +0,0 @@ -// Make a middleware that adds a cost to running the request -// by calling stripeSubscription addCost() * pricePerBooking -// Initially to test out 0,5 cent per booking via API call -// withCost(5)(endpoint) -// Should add a charge of 0.5 cent per booking to the subscription of the user making the request -import { NextMiddleware } from "next-api-middleware"; - -export const withCost = (priceInCents: number): NextMiddleware => { - return async function (req, res, next) { - console.log(req.headers); - if ( - priceInCents > 0 - // && stripeCustomerId && stripeSubscriptionId - ) { - console.log(priceInCents); - // if (req.method === allowedHttpMethod || req.method == "OPTIONS") { - await next(); - } else { - res.status(405).json({ message: `We weren't able to process the payment for this transaction` }); - res.end(); - } - }; -}; diff --git a/lib/utils/getCalcomUserId.ts b/lib/utils/getCalcomUserId.ts new file mode 100644 index 0000000000..8670bc8759 --- /dev/null +++ b/lib/utils/getCalcomUserId.ts @@ -0,0 +1,3 @@ +import { NextApiResponse } from "next"; + +export const getCalcomUserId = (res: NextApiResponse): number => res.getHeader("x-calcom-user-id") as number; diff --git a/lib/utils/getUserFromHeader.ts b/lib/utils/getUserFromHeader.ts deleted file mode 100644 index fc2e524954..0000000000 --- a/lib/utils/getUserFromHeader.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { NextApiResponse } from "next"; - -export const getCalcomUserId = (res: NextApiResponse) => res.getHeader("x-calcom-user-id") as number; diff --git a/pages/api/attendees/index.ts b/pages/api/attendees/index.ts index 644bba575c..e15a3af0e0 100644 --- a/pages/api/attendees/index.ts +++ b/pages/api/attendees/index.ts @@ -4,7 +4,7 @@ import prisma from "@calcom/prisma"; import { withMiddleware } from "@lib/helpers/withMiddleware"; import { AttendeeResponse, AttendeesResponse } from "@lib/types"; -import { getCalcomUserId } from "@lib/utils/getUserFromHeader"; +import { getCalcomUserId } from "@lib/utils/getCalcomUserId"; import { schemaAttendeeBodyParams, schemaAttendeePublic, withValidAttendee } from "@lib/validations/attendee"; /**