From 1f2b59c18d21d9dec9b8ef81edecc6cfda6f6dec Mon Sep 17 00:00:00 2001 From: Agusti Fernandez Pardo Date: Thu, 5 May 2022 05:02:59 +0200 Subject: [PATCH] feat: adds users post endpoint for admin only --- pages/api/users/[id].ts | 176 ++++++++++++++++++++++++--------------- pages/api/users/index.ts | 48 +++++++---- 2 files changed, 140 insertions(+), 84 deletions(-) diff --git a/pages/api/users/[id].ts b/pages/api/users/[id].ts index 3093b43cfc..ffaabcbf4f 100644 --- a/pages/api/users/[id].ts +++ b/pages/api/users/[id].ts @@ -10,68 +10,10 @@ import { } from "@lib/validations/shared/queryIdTransformParseInt"; import { schemaUserEditBodyParams, schemaUserReadPublic } from "@lib/validations/user"; -/** - * @swagger - * /users/{id}: - * get: - * summary: Find a user, returns your user if regular user. - * operationId: getUserById - * parameters: - * - in: path - * name: id - * schema: - * type: integer - * required: true - * description: Numeric ID of the user to get - * tags: - * - users - * responses: - * 200: - * description: OK - * 401: - * description: Authorization information is missing or invalid. - * 404: - * description: User was not found - * patch: - * summary: Edit an existing user - * operationId: editUserById - * parameters: - * - in: path - * name: id - * schema: - * type: integer - * required: true - * description: Numeric ID of the user to edit - * tags: - * - users - * responses: - * 201: - * description: OK, user edited successfuly - * 400: - * description: Bad request. User body is invalid. - * 401: - * description: Authorization information is missing or invalid. - * delete: - * summary: Remove an existing user - * operationId: deleteUserById - * parameters: - * - in: path - * name: id - * schema: - * type: integer - * required: true - * description: Numeric ID of the user to delete - * tags: - * - users - * responses: - * 201: - * description: OK, user removed successfuly - * 400: - * description: Bad request. User id is invalid. - * 401: - * description: Authorization information is missing or invalid. - */ -export async function userById({ method, query, body, userId }: NextApiRequest, res: NextApiResponse) { +export async function userById( + { method, query, body, userId }: NextApiRequest, + res: NextApiResponse +) { const safeQuery = schemaQueryIdParseInt.safeParse(query); console.log(body); if (!safeQuery.success) throw new Error("Invalid request query", safeQuery.error); @@ -79,6 +21,31 @@ export async function userById({ method, query, body, userId }: NextApiRequest, else { switch (method) { case "GET": + /** + * @swagger + * /users/{id}: + * get: + * summary: Find a user, returns your user if regular user. + * operationId: getUserById + * parameters: + * - in: path + * name: id + * example: 4 + * schema: + * type: integer + * required: true + * description: ID of the user to get + * tags: + * - users + * responses: + * 200: + * description: OK + * 401: + * description: Authorization information is missing or invalid. + * 404: + * description: User was not found + */ + await prisma.user .findUnique({ where: { id: safeQuery.data.id } }) .then((data) => schemaUserReadPublic.parse(data)) @@ -87,24 +54,72 @@ export async function userById({ method, query, body, userId }: NextApiRequest, res.status(404).json({ message: `User with id: ${safeQuery.data.id} not found`, error }) ); break; - case "PATCH": + /** + * @swagger + * /users/{id}: + * patch: + * summary: Edit an existing user + * operationId: editUserById + * requestBody: + * description: Edit an existing attendee related to one of your bookings + * required: true + * content: + * application/json: + * schema: + * type: object + * properties: + * weekStart: + * type: string + * enum: [Monday, Sunday, Saturday] + * example: Monday + * brandColor: + * type: string + * example: "#FF000F" + * darkBrandColor: + * type: string + * example: "#000000" + * timeZone: + * type: string + * example: Europe/London + * parameters: + * - in: path + * name: id + * example: 4 + * schema: + * type: integer + * required: true + * description: ID of the user to edit + * tags: + * - users + * responses: + * 201: + * description: OK, user edited successfuly + * 400: + * description: Bad request. User body is invalid. + * 401: + * description: Authorization information is missing or invalid. + */ + const safeBody = schemaUserEditBodyParams.safeParse(body); if (!safeBody.success) { res.status(400).json({ message: "Bad request", error: safeBody.error }); - throw new Error("Invalid request body"); + // throw new Error("Invalid request body"); + return; } const userSchedules = await prisma.schedule.findMany({ where: { userId }, }); const userSchedulesIds = userSchedules.map((schedule) => schedule.id); // @note: here we make sure user can only make as default his own scheudles - if (!userSchedulesIds.includes(Number(safeBody?.data?.defaultScheduleId))) { + if ( + safeBody?.data?.defaultScheduleId && + !userSchedulesIds.includes(Number(safeBody?.data?.defaultScheduleId)) + ) { res.status(400).json({ - message: "Bad request", - error: "Invalid default schedule id", + message: "Bad request: Invalid default schedule id", }); - throw new Error("Invalid request body value: defaultScheduleId"); + return; } await prisma.user .update({ @@ -118,6 +133,31 @@ export async function userById({ method, query, body, userId }: NextApiRequest, ); break; + /** + * @swagger + * /users/{id}: + * delete: + * summary: Remove an existing user + * operationId: removeUserById + * parameters: + * - in: path + * name: id + * example: 1 + * schema: + * type: integer + * required: true + * description: ID of the user to delete + * tags: + * - users + * responses: + * 201: + * description: OK, user removed successfuly + * 400: + * description: Bad request. User id is invalid. + * 401: + * description: Authorization information is missing or invalid. + */ + case "DELETE": await prisma.user .delete({ where: { id: safeQuery.data.id } }) diff --git a/pages/api/users/index.ts b/pages/api/users/index.ts index 046d456de9..6eea24cb3b 100644 --- a/pages/api/users/index.ts +++ b/pages/api/users/index.ts @@ -3,17 +3,17 @@ import type { NextApiRequest, NextApiResponse } from "next"; import prisma from "@calcom/prisma"; import { withMiddleware } from "@lib/helpers/withMiddleware"; -import { UsersResponse } from "@lib/types"; +import { UserResponse, UsersResponse } from "@lib/types"; import { schemaUserReadPublic } from "@lib/validations/user"; /** * @swagger * /users: * get: + * operationId: listUsers * summary: Find all users. * tags: * - users - * operationId: listUsers * responses: * 200: * description: OK @@ -22,21 +22,37 @@ import { schemaUserReadPublic } from "@lib/validations/user"; * 404: * description: No users were found */ -async function allUsers({ userId }: NextApiRequest, res: NextApiResponse) { - const data = await prisma.user.findMany({ - where: { - id: userId, - }, - }); - const users = data.map((user) => schemaUserReadPublic.parse(user)); - if (users) res.status(200).json({ users }); - else - (error: Error) => - res.status(404).json({ - message: "No Users were found", - error, +async function getAllorCreateUser( + { userId, method, body }: NextApiRequest, + res: NextApiResponse +) { + if (method === "GET") { + const data = await prisma.user.findMany({ + where: { + id: userId, + }, + }); + const users = data.map((user) => schemaUserReadPublic.parse(user)); + if (users) res.status(200).json({ users }); + else + (error: Error) => + res.status(404).json({ + message: "No Users were found", + error, + }); + } else if (method === "POST") { + const isAdmin = await prisma.user + .findUnique({ where: { id: userId } }) + .then((user) => user?.role === "ADMIN"); + if (!isAdmin) res.status(401).json({ message: "You are not authorized" }); + else { + const user = await prisma.user.create({ + data: schemaUserReadPublic.parse(body), }); + res.status(201).json({ user }); + } + } } // No POST endpoint for users for now as a regular user you're expected to signup. -export default withMiddleware("HTTP_GET")(allUsers); +export default withMiddleware("HTTP_GET_OR_POST")(getAllorCreateUser);