From 9fe7db6bf42526261fb21ae3276b847d6dd6aeb9 Mon Sep 17 00:00:00 2001 From: Rajat Saxena Date: Fri, 27 Sep 2024 00:01:50 +0530 Subject: [PATCH] Fixed permission issues --- apps/web/auth.ts | 3 + apps/web/components/admin/users/details.tsx | 2 +- apps/web/graphql/users/logic.ts | 107 ++++++++------------ apps/web/graphql/users/query.ts | 4 +- apps/web/graphql/users/types.ts | 2 +- 5 files changed, 49 insertions(+), 69 deletions(-) diff --git a/apps/web/auth.ts b/apps/web/auth.ts index 6b6abe35a..d5c9e9c4e 100644 --- a/apps/web/auth.ts +++ b/apps/web/auth.ts @@ -59,6 +59,9 @@ export const { auth, signIn, signOut, handlers } = NextAuth({ email: sanitizedEmail, }); } + if (!user.active) { + return null; + } return { id: user.userId, email: sanitizedEmail, diff --git a/apps/web/components/admin/users/details.tsx b/apps/web/components/admin/users/details.tsx index d45e7b98a..02c4cdce5 100644 --- a/apps/web/components/admin/users/details.tsx +++ b/apps/web/components/admin/users/details.tsx @@ -258,7 +258,7 @@ const Details = ({ userId, address, dispatch }: DetailsProps) => { /> - + {userData.permissions && } {/* diff --git a/apps/web/graphql/users/logic.ts b/apps/web/graphql/users/logic.ts index 829b9067b..e1fc1b615 100644 --- a/apps/web/graphql/users/logic.ts +++ b/apps/web/graphql/users/logic.ts @@ -25,46 +25,20 @@ import { import { recordActivity } from "../../lib/record-activity"; import { triggerSequences } from "../../lib/trigger-sequences"; -const removeAdminFieldsFromUserObject = ({ - id, - name, - userId, - bio, - email, - avatar, -}: { - id: string; - name: string; - userId: string; - bio: string; - email: string; - avatar: Media; -}) => ({ - id, - name, - userId, - bio, - email, - avatar, +const removeAdminFieldsFromUserObject = (user: User) => ({ + id: user._id, + name: user.name, + userId: user.userId, + bio: user.bio, + email: user.email, + avatar: user.avatar, }); -export const getUser = async (email = null, userId = null, ctx: GQLContext) => { - const { user: loggedInUser } = ctx; - const loggedUserEmail = loggedInUser && loggedInUser.email; - const loggedUserId = loggedInUser && loggedInUser.userId; +export const getUser = async (userId = null, ctx: GQLContext) => { + let user: User | undefined | null; + user = ctx.user; - if (!email && !userId && !loggedInUser) { - throw new Error(responses.invalid_user_id); - } - - if (!email && !userId && loggedInUser) { - email = loggedUserEmail; - } - - let user; - if (email) { - user = await UserModel.findOne({ email, domain: ctx.subdomain._id }); - } else { + if (userId) { user = await UserModel.findOne({ userId, domain: ctx.subdomain._id }); } @@ -72,16 +46,14 @@ export const getUser = async (email = null, userId = null, ctx: GQLContext) => { throw new Error(responses.item_not_found); } - user.userId = user.userId || -1; // Set -1 for empty userIds; Backward compatibility; - - return loggedInUser && - (loggedUserEmail === email || - loggedUserId === userId || - checkPermission(loggedInUser.permissions, [ - permissions.manageUsers, - ])) - ? user - : removeAdminFieldsFromUserObject(user); + if ( + user.userId === ctx.user.userId || + checkPermission(ctx.user.permissions, [permissions.manageUsers]) + ) { + return user; + } else { + return removeAdminFieldsFromUserObject(user); + } }; const validateUserProperties = (user) => { @@ -97,36 +69,41 @@ const checkForInvalidPermissions = (user) => { } }; -export const updateUser = async (userData: any, ctx: GQLContext) => { +interface UserData { + id: string; + name?: string; + active?: boolean; + bio?: string; + permissions?: string[]; + subscribedToUpdates?: boolean; + tags?: string[]; + avatar?: Media; +} + +export const updateUser = async (userData: UserData, ctx: GQLContext) => { checkIfAuthenticated(ctx); const { id } = userData; + const keys = Object.keys(userData); const hasPermissionToManageUser = checkPermission(ctx.user.permissions, [ permissions.manageUsers, ]); - if (!hasPermissionToManageUser) { - if (id !== ctx.user._id.toString()) { - throw new Error(responses.action_not_allowed); - } + const isModifyingSelf = id === ctx.user._id.toString(); + const restrictedKeys = ["permissions", "active"]; + + if ( + (isModifyingSelf && keys.some((key) => restrictedKeys.includes(key))) || + (!isModifyingSelf && !hasPermissionToManageUser) + ) { + throw new Error(responses.action_not_allowed); } let user = await UserModel.findOne({ _id: id, domain: ctx.subdomain._id }); if (!user) throw new Error(responses.item_not_found); - for (const key of Object.keys(userData)) { - if (key === "id") { - continue; - } - - // if ( - // !["subscribedToUpdates"].includes(key) && - // id === ctx.user._id.toString() - // ) { - // throw new Error(responses.action_not_allowed); - // } - + for (const key of keys.filter((key) => key !== "id")) { if (key === "tags") { - addTags(userData["tags"], ctx); + addTags(userData["tags"]!, ctx); } user[key] = userData[key]; diff --git a/apps/web/graphql/users/query.ts b/apps/web/graphql/users/query.ts index a821a7f07..2d1d4d13e 100644 --- a/apps/web/graphql/users/query.ts +++ b/apps/web/graphql/users/query.ts @@ -22,8 +22,8 @@ const queries = { email: { type: GraphQLString }, userId: { type: GraphQLString }, }, - resolve: (_: any, { email, userId }: any, context: GQLContext) => - getUser(email, userId, context), + resolve: (_: any, { userId }: any, context: GQLContext) => + getUser(userId, context), }, getUsers: { type: new GraphQLList(types.userType), diff --git a/apps/web/graphql/users/types.ts b/apps/web/graphql/users/types.ts index 288aa25d7..00e47deeb 100644 --- a/apps/web/graphql/users/types.ts +++ b/apps/web/graphql/users/types.ts @@ -27,7 +27,7 @@ const userType = new GraphQLObjectType({ email: { type: new GraphQLNonNull(GraphQLString) }, name: { type: GraphQLString }, purchases: { type: new GraphQLList(progress) }, - active: { type: new GraphQLNonNull(GraphQLBoolean) }, + active: { type: GraphQLBoolean }, userId: { type: new GraphQLNonNull(GraphQLString) }, bio: { type: GraphQLString }, permissions: { type: new GraphQLList(GraphQLString) },