fix: Invalid 403 forbidden for event-types GET (#14528)

This commit is contained in:
Keith Williams authored and GitHub committed 2024-04-11 19:15:21 +00:00
1 parent 711aceba0e
commit ac77fe360d
5 files changed
+165 -22

No files matched your search

@@ -1,18 +0,0 @@
import type { NextApiRequest } from "next";
import { HttpError } from "@calcom/lib/http-error";
import prisma from "@calcom/prisma";
import { schemaQueryIdParseInt } from "~/lib/validations/shared/queryIdTransformParseInt";
async function authMiddleware(req: NextApiRequest) {
const { userId, isAdmin } = req;
const { id } = schemaQueryIdParseInt.parse(req.query);
if (isAdmin) return;
const eventType = await prisma.eventType.findFirst({
where: { id, users: { some: { id: userId } } },
});
if (!eventType) throw new HttpError({ statusCode: 403, message: "Forbidden" });
}
export default authMiddleware;
@@ -4,11 +4,8 @@ import { defaultHandler, defaultResponder } from "@calcom/lib/server";
import { withMiddleware } from "~/lib/helpers/withMiddleware";
import authMiddleware from "./_auth-middleware";
export default withMiddleware()(
defaultResponder(async (req: NextApiRequest, res: NextApiResponse) => {
await authMiddleware(req);
return defaultHandler({
GET: import("./_get"),
PATCH: import("./_patch"),
@@ -26,7 +26,7 @@ export default async function checkTeamEventEditPermission(
if (!membership?.role || !["ADMIN", "OWNER"].includes(membership.role)) {
throw new HttpError({
statusCode: 401,
statusCode: 403,
message: "No permission to operate on event-type for this team",
});
}
@@ -0,0 +1,143 @@
import prismaMock from "../../../../../../../tests/libs/__mocks__/prismaMock";
import type { Request, Response } from "express";
import type { NextApiRequest, NextApiResponse } from "next";
import { createMocks } from "node-mocks-http";
import { describe, expect, test } from "vitest";
import { buildEventType } from "@calcom/lib/test/builder";
import { MembershipRole } from "@calcom/prisma/enums";
import handler from "../../../../pages/api/event-types/[id]/_get";
type CustomNextApiRequest = NextApiRequest & Request;
type CustomNextApiResponse = NextApiResponse & Response;
describe("GET /api/event-types/[id]", () => {
describe("Errors", () => {
test("Returns 403 if user not admin/team member/event owner", async () => {
const { req, res } = createMocks<CustomNextApiRequest, CustomNextApiResponse>({
method: "GET",
body: {},
query: {
id: 123456,
},
});
prismaMock.eventType.findUnique.mockResolvedValue(
buildEventType({
id: 123456,
userId: 444444,
})
);
req.userId = 333333;
await handler(req, res);
expect(res.statusCode).toBe(403);
});
});
describe("Success", async () => {
test("Returns event type if user is admin", async () => {
const eventTypeId = 123456;
const { req, res } = createMocks<CustomNextApiRequest, CustomNextApiResponse>({
method: "GET",
body: {},
query: {
id: eventTypeId,
},
});
prismaMock.eventType.findUnique.mockResolvedValue(
buildEventType({
id: eventTypeId,
})
);
req.isAdmin = true;
req.userId = 333333;
await handler(req, res);
expect(res.statusCode).toBe(200);
expect(JSON.parse(res._getData()).event_type.id).toEqual(eventTypeId);
});
test("Returns event type if user is in team associated with event type", async () => {
const eventTypeId = 123456;
const teamId = 9999;
const userId = 333333;
const { req, res } = createMocks<CustomNextApiRequest, CustomNextApiResponse>({
method: "GET",
body: {},
query: {
id: eventTypeId,
},
});
prismaMock.eventType.findUnique.mockResolvedValue(
buildEventType({
id: eventTypeId,
teamId,
})
);
prismaMock.team.findFirst.mockResolvedValue({
id: teamId,
members: [
{
userId,
},
],
});
req.isAdmin = false;
req.userId = userId;
await handler(req, res);
expect(res.statusCode).toBe(200);
expect(JSON.parse(res._getData()).event_type.id).toEqual(eventTypeId);
expect(prismaMock.team.findFirst).toHaveBeenCalledWith({
where: {
id: teamId,
members: {
some: {
userId: req.userId,
role: {
in: [MembershipRole.OWNER, MembershipRole.ADMIN, MembershipRole.MEMBER],
},
},
},
},
});
});
test("Returns event type if user is the event type owner", async () => {
const eventTypeId = 123456;
const userId = 333333;
const { req, res } = createMocks<CustomNextApiRequest, CustomNextApiResponse>({
method: "GET",
body: {},
query: {
id: eventTypeId,
},
});
prismaMock.eventType.findUnique.mockResolvedValue(
buildEventType({
id: eventTypeId,
userId,
scheduleId: 1111,
})
);
req.isAdmin = false;
req.userId = userId;
await handler(req, res);
expect(res.statusCode).toBe(200);
expect(JSON.parse(res._getData()).event_type.id).toEqual(eventTypeId);
expect(prismaMock.team.findFirst).not.toHaveBeenCalled();
});
});
});