Skip to content

Commit

Permalink
Fixed permission issues
Browse files Browse the repository at this point in the history
  • Loading branch information
Rajat Saxena committed Sep 26, 2024
1 parent 985a16e commit 9fe7db6
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 69 deletions.
3 changes: 3 additions & 0 deletions apps/web/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@ export const { auth, signIn, signOut, handlers } = NextAuth({
email: sanitizedEmail,
});
}
if (!user.active) {
return null;
}
return {
id: user.userId,
email: sanitizedEmail,
Expand Down
2 changes: 1 addition & 1 deletion apps/web/components/admin/users/details.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,7 @@ const Details = ({ userId, address, dispatch }: DetailsProps) => {
/>
</div>
</Section>
<PermissionsEditor user={userData} />
{userData.permissions && <PermissionsEditor user={userData} />}
</div>

{/*
Expand Down
107 changes: 42 additions & 65 deletions apps/web/graphql/users/logic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,63 +25,35 @@ 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 });
}

if (!user) {
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) => {
Expand All @@ -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];
Expand Down
4 changes: 2 additions & 2 deletions apps/web/graphql/users/query.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand Down
2 changes: 1 addition & 1 deletion apps/web/graphql/users/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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) },
Expand Down

0 comments on commit 9fe7db6

Please sign in to comment.