feat: Collection admins (#5273
* Split permissions for reading documents from updating collection * fix: Admins should have collection read permission, tests * tsc * Add admin option to permission selector * Combine publish and create permissions, update -> createDocuments where appropriate * Plural -> singular * wip * Quick version of collection structure loading, will revisit * Remove documentIds method * stash * fixing tests to account for admin creation * Add self-hosted migration * fix: Allow groups to have admin permission * Prefetch collection documents * fix: Document explorer (move/publish) not working with async documents * fix: Cannot re-parent document to collection by drag and drop * fix: Cannot drag to import into collection item without admin permission * Remove unused isEditor getter
This commit is contained in:
@@ -16,7 +16,10 @@ allow(User, ["read", "comment"], Document, (user, document) => {
|
||||
}
|
||||
|
||||
// existence of collection option is not required here to account for share tokens
|
||||
if (document.collection && cannot(user, "read", document.collection)) {
|
||||
if (
|
||||
document.collection &&
|
||||
cannot(user, "readDocument", document.collection)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -29,7 +32,10 @@ allow(User, "download", Document, (user, document) => {
|
||||
}
|
||||
|
||||
// existence of collection option is not required here to account for share tokens
|
||||
if (document.collection && cannot(user, "read", document.collection)) {
|
||||
if (
|
||||
document.collection &&
|
||||
cannot(user, "readDocument", document.collection)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -44,16 +50,7 @@ allow(User, "download", Document, (user, document) => {
|
||||
});
|
||||
|
||||
allow(User, "star", Document, (user, document) => {
|
||||
if (!document) {
|
||||
return false;
|
||||
}
|
||||
if (document.archivedAt) {
|
||||
return false;
|
||||
}
|
||||
if (document.deletedAt) {
|
||||
return false;
|
||||
}
|
||||
if (document.template) {
|
||||
if (!document || !document.isActive || document.template) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -62,7 +59,7 @@ allow(User, "star", Document, (user, document) => {
|
||||
document.collection,
|
||||
"collection is missing, did you forget to include in the query scope?"
|
||||
);
|
||||
if (cannot(user, "read", document.collection)) {
|
||||
if (cannot(user, "readDocument", document.collection)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -83,7 +80,7 @@ allow(User, "unstar", Document, (user, document) => {
|
||||
document.collection,
|
||||
"collection is missing, did you forget to include in the query scope?"
|
||||
);
|
||||
if (cannot(user, "read", document.collection)) {
|
||||
if (cannot(user, "readDocument", document.collection)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -114,13 +111,7 @@ allow(User, "share", Document, (user, document) => {
|
||||
});
|
||||
|
||||
allow(User, "update", Document, (user, document) => {
|
||||
if (!document) {
|
||||
return false;
|
||||
}
|
||||
if (document.archivedAt) {
|
||||
return false;
|
||||
}
|
||||
if (document.deletedAt) {
|
||||
if (!document || !document.isActive) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -130,7 +121,7 @@ allow(User, "update", Document, (user, document) => {
|
||||
"collection is missing, did you forget to include in the query scope?"
|
||||
);
|
||||
|
||||
if (cannot(user, "update", document.collection)) {
|
||||
if (cannot(user, "updateDocument", document.collection)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -139,63 +130,42 @@ allow(User, "update", Document, (user, document) => {
|
||||
});
|
||||
|
||||
allow(User, "createChildDocument", Document, (user, document) => {
|
||||
if (!document) {
|
||||
return false;
|
||||
}
|
||||
if (document.archivedAt) {
|
||||
return false;
|
||||
}
|
||||
if (document.deletedAt) {
|
||||
if (!document || !document.isActive || document.isDraft) {
|
||||
return false;
|
||||
}
|
||||
if (document.template) {
|
||||
return false;
|
||||
}
|
||||
if (!document.publishedAt) {
|
||||
return false;
|
||||
}
|
||||
invariant(
|
||||
document.collection,
|
||||
"collection is missing, did you forget to include in the query scope?"
|
||||
);
|
||||
if (cannot(user, "update", document.collection)) {
|
||||
if (cannot(user, "updateDocument", document.collection)) {
|
||||
return false;
|
||||
}
|
||||
return user.teamId === document.teamId;
|
||||
});
|
||||
|
||||
allow(User, "move", Document, (user, document) => {
|
||||
if (!document) {
|
||||
if (!document || !document.isActive) {
|
||||
return false;
|
||||
}
|
||||
if (document.archivedAt) {
|
||||
return false;
|
||||
}
|
||||
if (document.deletedAt) {
|
||||
return false;
|
||||
}
|
||||
if (document.collection && cannot(user, "update", document.collection)) {
|
||||
if (
|
||||
document.collection &&
|
||||
cannot(user, "updateDocument", document.collection)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
return user.teamId === document.teamId;
|
||||
});
|
||||
|
||||
allow(User, ["pin", "unpin"], Document, (user, document) => {
|
||||
if (!document) {
|
||||
return false;
|
||||
}
|
||||
if (document.archivedAt) {
|
||||
return false;
|
||||
}
|
||||
if (document.deletedAt) {
|
||||
if (!document || !document.isActive || document.isDraft) {
|
||||
return false;
|
||||
}
|
||||
if (document.template) {
|
||||
return false;
|
||||
}
|
||||
if (!document.publishedAt) {
|
||||
return false;
|
||||
}
|
||||
invariant(
|
||||
document.collection,
|
||||
"collection is missing, did you forget to include in the query scope?"
|
||||
@@ -207,46 +177,30 @@ allow(User, ["pin", "unpin"], Document, (user, document) => {
|
||||
});
|
||||
|
||||
allow(User, ["subscribe", "unsubscribe"], Document, (user, document) => {
|
||||
if (!document) {
|
||||
return false;
|
||||
}
|
||||
if (document.archivedAt) {
|
||||
return false;
|
||||
}
|
||||
if (document.deletedAt) {
|
||||
if (!document || !document.isActive || document.isDraft) {
|
||||
return false;
|
||||
}
|
||||
if (document.template) {
|
||||
return false;
|
||||
}
|
||||
if (!document.publishedAt) {
|
||||
return false;
|
||||
}
|
||||
invariant(
|
||||
document.collection,
|
||||
"collection is missing, did you forget to include in the query scope?"
|
||||
);
|
||||
if (cannot(user, "read", document.collection)) {
|
||||
if (cannot(user, "readDocument", document.collection)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return user.teamId === document.teamId;
|
||||
});
|
||||
|
||||
allow(User, ["pinToHome"], Document, (user, document) => {
|
||||
if (!document) {
|
||||
return false;
|
||||
}
|
||||
if (document.archivedAt) {
|
||||
return false;
|
||||
}
|
||||
if (document.deletedAt) {
|
||||
return false;
|
||||
}
|
||||
if (document.template) {
|
||||
return false;
|
||||
}
|
||||
if (!document.publishedAt) {
|
||||
allow(User, "pinToHome", Document, (user, document) => {
|
||||
if (
|
||||
!document ||
|
||||
!document.isActive ||
|
||||
document.isDraft ||
|
||||
document.template
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -254,23 +208,23 @@ allow(User, ["pinToHome"], Document, (user, document) => {
|
||||
});
|
||||
|
||||
allow(User, "delete", Document, (user, document) => {
|
||||
if (!document) {
|
||||
return false;
|
||||
}
|
||||
if (document.deletedAt) {
|
||||
if (!document || document.deletedAt) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// allow deleting document without a collection
|
||||
if (document.collection && cannot(user, "update", document.collection)) {
|
||||
if (
|
||||
document.collection &&
|
||||
cannot(user, "deleteDocument", document.collection)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// unpublished drafts can always be deleted
|
||||
// unpublished drafts can always be deleted by their owner
|
||||
if (
|
||||
!document.deletedAt &&
|
||||
!document.publishedAt &&
|
||||
user.teamId === document.teamId
|
||||
document.isDraft &&
|
||||
user.id === document.createdById
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
@@ -279,15 +233,15 @@ allow(User, "delete", Document, (user, document) => {
|
||||
});
|
||||
|
||||
allow(User, "permanentDelete", Document, (user, document) => {
|
||||
if (!document) {
|
||||
return false;
|
||||
}
|
||||
if (!document.deletedAt) {
|
||||
if (!document || !document.deletedAt) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// allow deleting document without a collection
|
||||
if (document.collection && cannot(user, "update", document.collection)) {
|
||||
if (
|
||||
document.collection &&
|
||||
cannot(user, "updateDocument", document.collection)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -295,14 +249,14 @@ allow(User, "permanentDelete", Document, (user, document) => {
|
||||
});
|
||||
|
||||
allow(User, "restore", Document, (user, document) => {
|
||||
if (!document) {
|
||||
return false;
|
||||
}
|
||||
if (!document.deletedAt) {
|
||||
if (!document || !document.deletedAt) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (document.collection && cannot(user, "update", document.collection)) {
|
||||
if (
|
||||
document.collection &&
|
||||
cannot(user, "updateDocument", document.collection)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -310,23 +264,14 @@ allow(User, "restore", Document, (user, document) => {
|
||||
});
|
||||
|
||||
allow(User, "archive", Document, (user, document) => {
|
||||
if (!document) {
|
||||
return false;
|
||||
}
|
||||
if (!document.publishedAt) {
|
||||
return false;
|
||||
}
|
||||
if (document.archivedAt) {
|
||||
return false;
|
||||
}
|
||||
if (document.deletedAt) {
|
||||
if (!document || !document.isActive || document.isDraft) {
|
||||
return false;
|
||||
}
|
||||
invariant(
|
||||
document.collection,
|
||||
"collection is missing, did you forget to include in the query scope?"
|
||||
);
|
||||
if (cannot(user, "update", document.collection)) {
|
||||
if (cannot(user, "updateDocument", document.collection)) {
|
||||
return false;
|
||||
}
|
||||
return user.teamId === document.teamId;
|
||||
@@ -340,7 +285,7 @@ allow(User, "unarchive", Document, (user, document) => {
|
||||
document.collection,
|
||||
"collection is missing, did you forget to include in the query scope?"
|
||||
);
|
||||
if (cannot(user, "update", document.collection)) {
|
||||
if (cannot(user, "updateDocument", document.collection)) {
|
||||
return false;
|
||||
}
|
||||
if (!document.archivedAt) {
|
||||
@@ -360,17 +305,14 @@ allow(
|
||||
);
|
||||
|
||||
allow(User, "unpublish", Document, (user, document) => {
|
||||
if (!document) {
|
||||
if (!document || !document.isActive || document.isDraft) {
|
||||
return false;
|
||||
}
|
||||
invariant(
|
||||
document.collection,
|
||||
"collection is missing, did you forget to include in the query scope?"
|
||||
);
|
||||
if (!document.publishedAt || !!document.deletedAt || !!document.archivedAt) {
|
||||
return false;
|
||||
}
|
||||
if (cannot(user, "update", document.collection)) {
|
||||
if (cannot(user, "updateDocument", document.collection)) {
|
||||
return false;
|
||||
}
|
||||
return user.teamId === document.teamId;
|
||||
|
||||
Reference in New Issue
Block a user