fix: Admins should be able to add and remove themselves from collections

This commit is contained in:
Tom Moor
2023-05-04 21:52:59 -04:00
parent 0504e91aa6
commit ac8946f0c5
7 changed files with 30 additions and 18 deletions

View File

@@ -377,15 +377,29 @@ class WebsocketProvider extends React.Component<Props> {
// or otherwise just remove any membership state we have for that user.
this.socket.on(
"collections.remove_user",
action((event: WebsocketCollectionUserEvent) => {
async (event: WebsocketCollectionUserEvent) => {
if (auth.user && event.userId === auth.user.id) {
collections.remove(event.collectionId);
memberships.removeCollectionMemberships(event.collectionId);
// check if we still have access to the collection
try {
await collections.fetch(event.collectionId, {
force: true,
});
} catch (err) {
if (
err instanceof AuthorizationError ||
err instanceof NotFoundError
) {
collections.remove(event.collectionId);
memberships.remove(`${event.userId}-${event.collectionId}`);
return;
}
}
documents.removeCollectionDocuments(event.collectionId);
} else {
memberships.remove(`${event.userId}-${event.collectionId}`);
}
})
}
);
this.socket.on(

View File

@@ -1,19 +1,24 @@
import * as React from "react";
import { useTranslation } from "react-i18next";
import { useMenuState } from "reakit/Menu";
import User from "~/models/User";
import ContextMenu from "~/components/ContextMenu";
import OverflowMenuButton from "~/components/ContextMenu/OverflowMenuButton";
import Template from "~/components/ContextMenu/Template";
import useCurrentUser from "~/hooks/useCurrentUser";
type Props = {
user: User;
onRemove: () => void;
};
function MemberMenu({ onRemove }: Props) {
function MemberMenu({ user, onRemove }: Props) {
const { t } = useTranslation();
const currentUser = useCurrentUser();
const menu = useMenuState({
modal: true,
});
return (
<>
<OverflowMenuButton aria-label={t("Show menu")} {...menu} />
@@ -23,7 +28,7 @@ function MemberMenu({ onRemove }: Props) {
items={[
{
type: "button",
title: t("Remove"),
title: currentUser.id === user.id ? t("Leave") : t("Remove"),
dangerous: true,
onClick: onRemove,
},

View File

@@ -13,7 +13,6 @@ import PaginatedList from "~/components/PaginatedList";
import Text from "~/components/Text";
import useBoolean from "~/hooks/useBoolean";
import useCurrentTeam from "~/hooks/useCurrentTeam";
import useCurrentUser from "~/hooks/useCurrentUser";
import useDebouncedCallback from "~/hooks/useDebouncedCallback";
import useStores from "~/hooks/useStores";
import useToasts from "~/hooks/useToasts";
@@ -26,7 +25,6 @@ type Props = {
function AddPeopleToCollection({ collection }: Props) {
const { memberships, users } = useStores();
const { showToast } = useToasts();
const user = useCurrentUser();
const team = useCurrentTeam();
const { t } = useTranslation();
const [
@@ -99,9 +97,7 @@ function AddPeopleToCollection({ collection }: Props) {
<Empty>{t("No people left to add")}</Empty>
)
}
items={users
.notInCollection(collection.id, query)
.filter((member) => member.id !== user.id)}
items={users.notInCollection(collection.id, query)}
fetch={query ? undefined : users.fetchPage}
renderItem={(item: User) => (
<MemberListItem

View File

@@ -60,7 +60,7 @@ const MemberListItem = ({
)}
{canEdit && (
<>
{onRemove && <MemberMenu onRemove={onRemove} />}
{onRemove && <MemberMenu user={user} onRemove={onRemove} />}
{onAdd && (
<Button onClick={onAdd} neutral>
{t("Add")}

View File

@@ -318,7 +318,7 @@ function CollectionPermissions({ collectionId }: Props) {
key={item.id}
user={item}
membership={memberships.get(`${item.id}-${collection.id}`)}
canEdit={item.id !== user.id}
canEdit={item.id !== user.id || user.isAdmin}
onRemove={() => handleRemoveUser(item)}
onUpdate={(permission) => handleUpdateUser(item, permission)}
/>

View File

@@ -13,7 +13,7 @@ import { colorPalette } from "@shared/utils/collections";
import collectionExporter from "@server/commands/collectionExporter";
import teamUpdater from "@server/commands/teamUpdater";
import { sequelize } from "@server/database/sequelize";
import { AuthorizationError, ValidationError } from "@server/errors";
import { ValidationError } from "@server/errors";
import auth from "@server/middlewares/authentication";
import { rateLimiter } from "@server/middlewares/rateLimiter";
import { transaction } from "@server/middlewares/transaction";
@@ -406,10 +406,6 @@ router.post(
lock: transaction.LOCK.UPDATE,
});
if (userId === actor.id) {
throw AuthorizationError("You cannot add yourself to a collection");
}
if (permission) {
assertCollectionPermission(permission);
}

View File

@@ -346,6 +346,7 @@
"Delete group": "Delete group",
"Group options": "Group options",
"Member options": "Member options",
"Leave": "Leave",
"New child document": "New child document",
"New document in <em>{{ collectionName }}</em>": "New document in <em>{{ collectionName }}</em>",
"New template": "New template",