Skip to content

Commit

Permalink
fix: always allow users to unshare another user's tag from themselves
Browse files Browse the repository at this point in the history
- due to race-conditions after the tag is unshared, `useHasPermission` must not throw – reduced to logging an error and returning false
  • Loading branch information
neopostmodern committed Apr 12, 2023
1 parent cc0c0e9 commit 490c1c0
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 7 deletions.
15 changes: 15 additions & 0 deletions client/src/renderer/components/TagSharingDelete.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,13 @@ import { gql, useMutation } from '@apollo/client';
import { Delete } from '@mui/icons-material';
import { CircularProgress, IconButton, Tooltip } from '@mui/material';
import { useCallback } from 'react';
import { useDispatch } from 'react-redux';
import { goBack } from 'redux-first-history';
import {
UnshareTagMutation,
UnshareTagMutationVariables,
} from '../generated/graphql';
import useUserId from '../hooks/useUserId';
import ErrorSnackbar from './ErrorSnackbar';

const UNSHARE_TAG_MUTATION = gql`
Expand Down Expand Up @@ -39,6 +42,8 @@ const TagSharingDelete = ({
tagId: string;
userId: string;
}) => {
const loggedInUserId = useUserId();
const dispatch = useDispatch();
const [unshareTag, unshareTagMutation] = useMutation<
UnshareTagMutation,
UnshareTagMutationVariables
Expand All @@ -47,6 +52,16 @@ const TagSharingDelete = ({
tagId,
userId,
},
onCompleted({ unshareTag: updatedTag }) {
if (!updatedTag) {
return;
}
if (
!updatedTag.permissions.some(({ user }) => user._id === loggedInUserId)
) {
dispatch(goBack());
}
},
});

const handleClick = useCallback(() => {
Expand Down
7 changes: 5 additions & 2 deletions client/src/renderer/components/TagSharingTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import {
UpdatePermissionOnTagMutation,
UpdatePermissionOnTagMutationVariables,
} from '../generated/graphql';
import useUserId from '../hooks/useUserId';
import ErrorSnackbar from './ErrorSnackbar';
import { FORM_SUBHEADER_STYLES } from './formComponents';
import TagSharingDelete from './TagSharingDelete';
Expand Down Expand Up @@ -93,6 +94,8 @@ const TagSharingTable = ({
tag: TagType;
readOnly?: boolean;
}) => {
const userId = useUserId();

const [updatePermissionOnTag, updatePermissionOnTagMutation] = useMutation<
UpdatePermissionOnTagMutation,
UpdatePermissionOnTagMutationVariables
Expand Down Expand Up @@ -214,8 +217,8 @@ const TagSharingTable = ({
{mutationActiveOnUserId === permission.user._id ? (
<CircularProgress size="1.2em" disableShrink />
) : (
!readOnly &&
tag.user._id !== permission.user._id && (
tag.user._id !== permission.user._id &&
(!readOnly || userId === permission.user._id) && (
<TagSharingDelete
tagId={tag._id}
userId={permission.user._id}
Expand Down
10 changes: 6 additions & 4 deletions client/src/renderer/hooks/useHasPermission.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,18 @@ export const hasPermission = (
);

if (!userPermissions) {
throw Error(
console.error(
`[useHasPermissions] User '${userId}' has no permissions on entity.`
);
return false;
}

if (!(mode in userPermissions[resource])) {
console.error(userPermissions[resource]);
throw Error(
`[useHasPermissions] No such mode '${mode}' on resource '${resource}'`
console.error(
`[useHasPermissions] No such mode '${mode}' on resource '${resource}'`,
userPermissions[resource]
);
return false;
}

return userPermissions[resource][mode] as boolean;
Expand Down
3 changes: 2 additions & 1 deletion server/lib/resolvers.js
Original file line number Diff line number Diff line change
Expand Up @@ -390,7 +390,8 @@ const rootResolvers = {

const tag = await Tag.findOne({
_id: tagId,
...baseTagsQuery(user, 'share'),
// always allow unsharing from yourself
...(user._id === userId ? {} : baseTagsQuery(user, 'share')),
})
if (!tag) {
throw new Error('No such tag or no sufficient privileges.')
Expand Down

0 comments on commit 490c1c0

Please sign in to comment.