Skip to content

Commit

Permalink
fix(ProjectAccess): correct access check
Browse files Browse the repository at this point in the history
  • Loading branch information
LamaEats committed Jan 13, 2025
1 parent 71367bb commit fe93844
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 35 deletions.
9 changes: 9 additions & 0 deletions src/utils/anyEntityCheck.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export const oneOf =
<T>(...funcs: Array<(arg: T) => boolean>) =>
(arg: T) =>
funcs.some((f) => f(arg));

export const and =
<T>(...funcs: Array<(arg: T) => boolean>) =>
(arg: T) =>
funcs.every((f) => f(arg));
77 changes: 42 additions & 35 deletions trpc/queries/project.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Role } from '@prisma/client';

import { QueryWithFilters } from '../../src/schema/common';
import { oneOf, and } from '../../src/utils/anyEntityCheck';

import { goalsFilter } from './goals';
import { getProjectAccessFilter } from './access';
Expand Down Expand Up @@ -41,45 +42,51 @@ export const addCalculatedProjectFields = <
};
};

export const checkProjectAccess = <
T extends {
accessUsers: WithId[];
activityId: string;
archived?: boolean | null;
personal: boolean | null;
goalAccessIds?: string[];
},
>(
project: T,
activityId: string,
role: Role,
) => {
if (role === 'ADMIN') {
return !project.archived;
}

if (project.archived) {
return false;
}
interface ProjectAccessEntity {
accessUsers: WithId[];
activityId: string;
archived?: boolean | null;
personal: boolean | null;
goalAccessIds?: string[];
}

if (project.personal) {
if (project.goalAccessIds?.length) {
return project.goalAccessIds.includes(activityId);
}
type ProjectEntityTuple = [ProjectAccessEntity, string, Role];

if (project.accessUsers.length) {
return project.accessUsers.some(({ id }) => id === activityId);
const accessCheck = oneOf<ProjectEntityTuple>(
([p, activityId]) => p.activityId === activityId,
([p, activityId]) => {
if (p.accessUsers.length) {
return p.accessUsers.some(({ id }) => id === activityId);
}

return project.activityId === activityId;
}

if (project.accessUsers.length) {
return project.accessUsers.some(({ id }) => id === activityId);
}

return true;
};
return false;
},
);

const notArchivedProject = ([project]: ProjectEntityTuple) => project.archived !== true;

const checkProjectEntity = oneOf<ProjectEntityTuple>(
and((args) => args[2] === 'ADMIN', notArchivedProject),
and(
notArchivedProject,
oneOf(
and(
([{ personal }]) => !!personal,
oneOf(([p, activityId]) => {
if (p.goalAccessIds?.length) {
return p.goalAccessIds.includes(activityId);
}

return false;
}, accessCheck),
),
accessCheck,
),
),
);

export const checkProjectAccess = <T extends ProjectAccessEntity>(project: T, activityId: string, role: Role) =>
checkProjectEntity([project, activityId, role]);

export const getProjectSchema = ({
role,
Expand Down

0 comments on commit fe93844

Please sign in to comment.