Merge pull request #103 from calcom/feat/admin-users
feat: Admin API users manegement endpointspull/9078/head
commit
767f170cae
|
@ -0,0 +1,7 @@
|
|||
import prisma from "@calcom/prisma";
|
||||
import { UserPermissionRole } from "@calcom/prisma/client";
|
||||
|
||||
export const isAdminGuard = async (userId: number) => {
|
||||
const user = await prisma.user.findUnique({ where: { id: userId } });
|
||||
return user?.role === UserPermissionRole.ADMIN;
|
||||
};
|
|
@ -85,19 +85,45 @@ const schemaUserEditParams = z.object({
|
|||
bufferTime: z.number().min(0).max(86400).optional(),
|
||||
startTime: z.number().min(0).max(86400).optional(),
|
||||
endTime: z.number().min(0).max(86400).optional(),
|
||||
theme: z.nativeEnum(theme).optional(),
|
||||
theme: z.nativeEnum(theme).optional().nullable(),
|
||||
timeFormat: z.nativeEnum(timeFormat).optional(),
|
||||
defaultScheduleId: z
|
||||
.number()
|
||||
.refine((id: number) => id > 0)
|
||||
.optional(),
|
||||
locale: z.nativeEnum(locales).optional(),
|
||||
.optional()
|
||||
.nullable(),
|
||||
locale: z.nativeEnum(locales).optional().nullable(),
|
||||
metadata: jsonSchema,
|
||||
});
|
||||
|
||||
// @note: These are the values that are editable via PATCH method on the user Model,
|
||||
// merging both BaseBodyParams with RequiredParams, and omiting whatever we want at the end.
|
||||
|
||||
const schemaUserCreateParams = z.object({
|
||||
email: z.string().email(),
|
||||
weekStart: z.nativeEnum(weekdays).optional(),
|
||||
brandColor: z.string().min(4).max(9).regex(/^#/).optional(),
|
||||
darkBrandColor: z.string().min(4).max(9).regex(/^#/).optional(),
|
||||
timeZone: timeZone.optional(),
|
||||
bufferTime: z.number().min(0).max(86400).optional(),
|
||||
startTime: z.number().min(0).max(86400).optional(),
|
||||
endTime: z.number().min(0).max(86400).optional(),
|
||||
theme: z.nativeEnum(theme).optional().nullable(),
|
||||
timeFormat: z.nativeEnum(timeFormat).optional(),
|
||||
defaultScheduleId: z
|
||||
.number()
|
||||
.refine((id: number) => id > 0)
|
||||
.optional()
|
||||
.nullable(),
|
||||
locale: z.nativeEnum(locales).optional(),
|
||||
metadata: jsonSchema,
|
||||
createdDate: z.string().or(z.date()).optional(),
|
||||
});
|
||||
|
||||
// @note: These are the values that are editable via PATCH method on the user Model,
|
||||
// merging both BaseBodyParams with RequiredParams, and omiting whatever we want at the end.
|
||||
export const schemaUserEditBodyParams = schemaUserBaseBodyParams.merge(schemaUserEditParams).omit({});
|
||||
export const schemaUserCreateBodyParams = schemaUserBaseBodyParams.merge(schemaUserCreateParams).omit({});
|
||||
|
||||
// @note: These are the values that are always returned when reading a user
|
||||
export const schemaUserReadPublic = User.pick({
|
||||
|
@ -124,4 +150,4 @@ export const schemaUserReadPublic = User.pick({
|
|||
createdDate: true,
|
||||
verified: true,
|
||||
invitedTo: true,
|
||||
});
|
||||
}).merge(schemaUserEditBodyParams);
|
||||
|
|
|
@ -4,6 +4,7 @@ import prisma from "@calcom/prisma";
|
|||
|
||||
import { withMiddleware } from "@lib/helpers/withMiddleware";
|
||||
import type { UserResponse } from "@lib/types";
|
||||
import { isAdminGuard } from "@lib/utils/isAdmin";
|
||||
import {
|
||||
schemaQueryIdParseInt,
|
||||
withValidQueryIdTransformParseInt,
|
||||
|
@ -20,8 +21,11 @@ export async function userById(
|
|||
res.status(400).json({ message: "Your query was invalid" });
|
||||
return;
|
||||
}
|
||||
if (safeQuery.data.id !== userId) res.status(401).json({ message: "Unauthorized" });
|
||||
else {
|
||||
const isAdmin = await isAdminGuard(userId);
|
||||
// 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) {
|
||||
if (safeQuery.data.id !== userId) res.status(401).json({ message: "Unauthorized" });
|
||||
} else {
|
||||
switch (method) {
|
||||
case "GET":
|
||||
/**
|
||||
|
|
|
@ -4,7 +4,8 @@ import prisma from "@calcom/prisma";
|
|||
|
||||
import { withMiddleware } from "@lib/helpers/withMiddleware";
|
||||
import { UserResponse, UsersResponse } from "@lib/types";
|
||||
import { schemaUserReadPublic } from "@lib/validations/user";
|
||||
import { isAdminGuard } from "@lib/utils/isAdmin";
|
||||
import { schemaUserReadPublic, schemaUserCreateBodyParams } from "@lib/validations/user";
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
|
@ -26,34 +27,34 @@ async function getAllorCreateUser(
|
|||
{ userId, method, body }: NextApiRequest,
|
||||
res: NextApiResponse<UsersResponse | UserResponse>
|
||||
) {
|
||||
const isAdmin = await isAdminGuard(userId);
|
||||
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,
|
||||
});
|
||||
if (!isAdmin) {
|
||||
// If user is not ADMIN, return only his data.
|
||||
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 {
|
||||
// If user is admin, return all users.
|
||||
const data = await prisma.user.findMany({});
|
||||
const users = data.map((user) => schemaUserReadPublic.parse(user));
|
||||
if (users) res.status(200).json({ users });
|
||||
}
|
||||
} else if (method === "POST") {
|
||||
// If user is not ADMIN, return unauthorized.
|
||||
if (!isAdmin) res.status(401).json({ message: "You are not authorized" });
|
||||
else {
|
||||
const safeBody = schemaUserCreateBodyParams.safeParse(body);
|
||||
if (!safeBody.success) {
|
||||
res.status(400).json({ message: "Your body was invalid" });
|
||||
return;
|
||||
}
|
||||
const user = await prisma.user.create({
|
||||
data: safeBody.data,
|
||||
});
|
||||
res.status(201).json({ user });
|
||||
}
|
||||
}
|
||||
// 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_OR_POST")(getAllorCreateUser);
|
||||
|
|
Loading…
Reference in New Issue