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:
@@ -396,18 +396,18 @@ describe("#collections.export_all", () => {
|
||||
|
||||
describe("#collections.add_user", () => {
|
||||
it("should add user to collection", async () => {
|
||||
const user = await buildUser();
|
||||
const admin = await buildAdmin();
|
||||
const collection = await buildCollection({
|
||||
teamId: user.teamId,
|
||||
userId: user.id,
|
||||
teamId: admin.teamId,
|
||||
userId: admin.id,
|
||||
permission: null,
|
||||
});
|
||||
const anotherUser = await buildUser({
|
||||
teamId: user.teamId,
|
||||
teamId: admin.teamId,
|
||||
});
|
||||
const res = await server.post("/api/collections.add_user", {
|
||||
body: {
|
||||
token: user.getJwtToken(),
|
||||
token: admin.getJwtToken(),
|
||||
id: collection.id,
|
||||
userId: anotherUser.id,
|
||||
},
|
||||
@@ -616,25 +616,25 @@ describe("#collections.remove_group", () => {
|
||||
|
||||
describe("#collections.remove_user", () => {
|
||||
it("should remove user from collection", async () => {
|
||||
const user = await buildUser();
|
||||
const admin = await buildAdmin();
|
||||
const collection = await buildCollection({
|
||||
teamId: user.teamId,
|
||||
userId: user.id,
|
||||
teamId: admin.teamId,
|
||||
userId: admin.id,
|
||||
permission: null,
|
||||
});
|
||||
const anotherUser = await buildUser({
|
||||
teamId: user.teamId,
|
||||
teamId: admin.teamId,
|
||||
});
|
||||
await server.post("/api/collections.add_user", {
|
||||
body: {
|
||||
token: user.getJwtToken(),
|
||||
token: admin.getJwtToken(),
|
||||
id: collection.id,
|
||||
userId: anotherUser.id,
|
||||
},
|
||||
});
|
||||
const res = await server.post("/api/collections.remove_user", {
|
||||
body: {
|
||||
token: user.getJwtToken(),
|
||||
token: admin.getJwtToken(),
|
||||
id: collection.id,
|
||||
userId: anotherUser.id,
|
||||
},
|
||||
@@ -839,12 +839,7 @@ describe("#collections.memberships", () => {
|
||||
const { collection, user } = await seed();
|
||||
collection.permission = null;
|
||||
await collection.save();
|
||||
await CollectionUser.create({
|
||||
createdById: user.id,
|
||||
collectionId: collection.id,
|
||||
userId: user.id,
|
||||
permission: CollectionPermission.ReadWrite,
|
||||
});
|
||||
|
||||
const res = await server.post("/api/collections.memberships", {
|
||||
body: {
|
||||
token: user.getJwtToken(),
|
||||
@@ -857,7 +852,7 @@ describe("#collections.memberships", () => {
|
||||
expect(body.data.users[0].id).toEqual(user.id);
|
||||
expect(body.data.memberships.length).toEqual(1);
|
||||
expect(body.data.memberships[0].permission).toEqual(
|
||||
CollectionPermission.ReadWrite
|
||||
CollectionPermission.Admin
|
||||
);
|
||||
});
|
||||
|
||||
@@ -866,12 +861,6 @@ describe("#collections.memberships", () => {
|
||||
const user2 = await buildUser({
|
||||
name: "Won't find",
|
||||
});
|
||||
await CollectionUser.create({
|
||||
createdById: user.id,
|
||||
collectionId: collection.id,
|
||||
userId: user.id,
|
||||
permission: CollectionPermission.ReadWrite,
|
||||
});
|
||||
await CollectionUser.create({
|
||||
createdById: user2.id,
|
||||
collectionId: collection.id,
|
||||
@@ -957,6 +946,12 @@ describe("#collections.info", () => {
|
||||
const { user, collection } = await seed();
|
||||
collection.permission = null;
|
||||
await collection.save();
|
||||
await CollectionUser.destroy({
|
||||
where: {
|
||||
collectionId: collection.id,
|
||||
userId: user.id,
|
||||
},
|
||||
});
|
||||
const res = await server.post("/api/collections.info", {
|
||||
body: {
|
||||
token: user.getJwtToken(),
|
||||
@@ -1181,10 +1176,10 @@ describe("#collections.update", () => {
|
||||
});
|
||||
|
||||
it("allows editing non-private collection", async () => {
|
||||
const { user, collection } = await seed();
|
||||
const { admin, collection } = await seed();
|
||||
const res = await server.post("/api/collections.update", {
|
||||
body: {
|
||||
token: user.getJwtToken(),
|
||||
token: admin.getJwtToken(),
|
||||
id: collection.id,
|
||||
name: "Test",
|
||||
},
|
||||
@@ -1196,14 +1191,14 @@ describe("#collections.update", () => {
|
||||
});
|
||||
|
||||
it("allows editing sort", async () => {
|
||||
const { user, collection } = await seed();
|
||||
const { admin, collection } = await seed();
|
||||
const sort = {
|
||||
field: "index",
|
||||
direction: "desc",
|
||||
};
|
||||
const res = await server.post("/api/collections.update", {
|
||||
body: {
|
||||
token: user.getJwtToken(),
|
||||
token: admin.getJwtToken(),
|
||||
id: collection.id,
|
||||
sort,
|
||||
},
|
||||
@@ -1215,10 +1210,10 @@ describe("#collections.update", () => {
|
||||
});
|
||||
|
||||
it("allows editing individual fields", async () => {
|
||||
const { user, collection } = await seed();
|
||||
const { admin, collection } = await seed();
|
||||
const res = await server.post("/api/collections.update", {
|
||||
body: {
|
||||
token: user.getJwtToken(),
|
||||
token: admin.getJwtToken(),
|
||||
id: collection.id,
|
||||
permission: null,
|
||||
},
|
||||
@@ -1230,10 +1225,10 @@ describe("#collections.update", () => {
|
||||
});
|
||||
|
||||
it("allows editing from non-private to private collection, and trims whitespace", async () => {
|
||||
const { user, collection } = await seed();
|
||||
const { admin, collection } = await seed();
|
||||
const res = await server.post("/api/collections.update", {
|
||||
body: {
|
||||
token: user.getJwtToken(),
|
||||
token: admin.getJwtToken(),
|
||||
id: collection.id,
|
||||
permission: null,
|
||||
name: " Test ",
|
||||
@@ -1249,18 +1244,18 @@ describe("#collections.update", () => {
|
||||
});
|
||||
|
||||
it("allows editing from private to non-private collection", async () => {
|
||||
const { user, collection } = await seed();
|
||||
const { admin, collection } = await seed();
|
||||
collection.permission = null;
|
||||
await collection.save();
|
||||
await CollectionUser.create({
|
||||
collectionId: collection.id,
|
||||
userId: user.id,
|
||||
createdById: user.id,
|
||||
userId: admin.id,
|
||||
createdById: admin.id,
|
||||
permission: CollectionPermission.ReadWrite,
|
||||
});
|
||||
const res = await server.post("/api/collections.update", {
|
||||
body: {
|
||||
token: user.getJwtToken(),
|
||||
token: admin.getJwtToken(),
|
||||
id: collection.id,
|
||||
permission: CollectionPermission.ReadWrite,
|
||||
name: "Test",
|
||||
@@ -1276,18 +1271,18 @@ describe("#collections.update", () => {
|
||||
});
|
||||
|
||||
it("allows editing by read-write collection user", async () => {
|
||||
const { user, collection } = await seed();
|
||||
const { admin, collection } = await seed();
|
||||
collection.permission = null;
|
||||
await collection.save();
|
||||
await CollectionUser.create({
|
||||
collectionId: collection.id,
|
||||
userId: user.id,
|
||||
createdById: user.id,
|
||||
userId: admin.id,
|
||||
createdById: admin.id,
|
||||
permission: CollectionPermission.ReadWrite,
|
||||
});
|
||||
const res = await server.post("/api/collections.update", {
|
||||
body: {
|
||||
token: user.getJwtToken(),
|
||||
token: admin.getJwtToken(),
|
||||
id: collection.id,
|
||||
name: "Test",
|
||||
},
|
||||
@@ -1298,7 +1293,7 @@ describe("#collections.update", () => {
|
||||
expect(body.policies.length).toBe(1);
|
||||
});
|
||||
|
||||
it("allows editing by read-write collection group user", async () => {
|
||||
it("allows editing by admin collection group user", async () => {
|
||||
const user = await buildUser();
|
||||
const collection = await buildCollection({
|
||||
permission: null,
|
||||
@@ -1314,7 +1309,7 @@ describe("#collections.update", () => {
|
||||
});
|
||||
await collection.$add("group", group, {
|
||||
through: {
|
||||
permission: CollectionPermission.ReadWrite,
|
||||
permission: CollectionPermission.Admin,
|
||||
createdById: user.id,
|
||||
},
|
||||
});
|
||||
@@ -1335,12 +1330,18 @@ describe("#collections.update", () => {
|
||||
const { user, collection } = await seed();
|
||||
collection.permission = null;
|
||||
await collection.save();
|
||||
await CollectionUser.create({
|
||||
collectionId: collection.id,
|
||||
userId: user.id,
|
||||
createdById: user.id,
|
||||
permission: CollectionPermission.Read,
|
||||
});
|
||||
await CollectionUser.update(
|
||||
{
|
||||
createdById: user.id,
|
||||
permission: CollectionPermission.Read,
|
||||
},
|
||||
{
|
||||
where: {
|
||||
collectionId: collection.id,
|
||||
userId: user.id,
|
||||
},
|
||||
}
|
||||
);
|
||||
const res = await server.post("/api/collections.update", {
|
||||
body: {
|
||||
token: user.getJwtToken(),
|
||||
@@ -1352,14 +1353,14 @@ describe("#collections.update", () => {
|
||||
});
|
||||
|
||||
it("does not allow setting unknown sort fields", async () => {
|
||||
const { user, collection } = await seed();
|
||||
const { admin, collection } = await seed();
|
||||
const sort = {
|
||||
field: "blah",
|
||||
direction: "desc",
|
||||
};
|
||||
const res = await server.post("/api/collections.update", {
|
||||
body: {
|
||||
token: user.getJwtToken(),
|
||||
token: admin.getJwtToken(),
|
||||
id: collection.id,
|
||||
sort,
|
||||
},
|
||||
@@ -1368,14 +1369,14 @@ describe("#collections.update", () => {
|
||||
});
|
||||
|
||||
it("does not allow setting unknown sort directions", async () => {
|
||||
const { user, collection } = await seed();
|
||||
const { admin, collection } = await seed();
|
||||
const sort = {
|
||||
field: "title",
|
||||
direction: "blah",
|
||||
};
|
||||
const res = await server.post("/api/collections.update", {
|
||||
body: {
|
||||
token: user.getJwtToken(),
|
||||
token: admin.getJwtToken(),
|
||||
id: collection.id,
|
||||
sort,
|
||||
},
|
||||
@@ -1405,10 +1406,10 @@ describe("#collections.delete", () => {
|
||||
});
|
||||
|
||||
it("should not allow deleting last collection", async () => {
|
||||
const { user, collection } = await seed();
|
||||
const { admin, collection } = await seed();
|
||||
const res = await server.post("/api/collections.delete", {
|
||||
body: {
|
||||
token: user.getJwtToken(),
|
||||
token: admin.getJwtToken(),
|
||||
id: collection.id,
|
||||
},
|
||||
});
|
||||
@@ -1416,15 +1417,15 @@ describe("#collections.delete", () => {
|
||||
});
|
||||
|
||||
it("should delete collection", async () => {
|
||||
const { user, collection } = await seed();
|
||||
const { admin, collection } = await seed();
|
||||
// to ensure it isn't the last collection
|
||||
await buildCollection({
|
||||
teamId: user.teamId,
|
||||
createdById: user.id,
|
||||
teamId: admin.teamId,
|
||||
createdById: admin.id,
|
||||
});
|
||||
const res = await server.post("/api/collections.delete", {
|
||||
body: {
|
||||
token: user.getJwtToken(),
|
||||
token: admin.getJwtToken(),
|
||||
id: collection.id,
|
||||
},
|
||||
});
|
||||
@@ -1434,11 +1435,11 @@ describe("#collections.delete", () => {
|
||||
});
|
||||
|
||||
it("should delete published documents", async () => {
|
||||
const { user, collection } = await seed();
|
||||
const { admin, collection } = await seed();
|
||||
// to ensure it isn't the last collection
|
||||
await buildCollection({
|
||||
teamId: user.teamId,
|
||||
createdById: user.id,
|
||||
teamId: admin.teamId,
|
||||
createdById: admin.id,
|
||||
});
|
||||
// archived document should not be deleted
|
||||
await buildDocument({
|
||||
@@ -1447,7 +1448,7 @@ describe("#collections.delete", () => {
|
||||
});
|
||||
const res = await server.post("/api/collections.delete", {
|
||||
body: {
|
||||
token: user.getJwtToken(),
|
||||
token: admin.getJwtToken(),
|
||||
id: collection.id,
|
||||
},
|
||||
});
|
||||
@@ -1463,7 +1464,7 @@ describe("#collections.delete", () => {
|
||||
).toEqual(1);
|
||||
});
|
||||
|
||||
it("allows deleting by read-write collection group user", async () => {
|
||||
it("allows deleting by admin collection group user", async () => {
|
||||
const user = await buildUser();
|
||||
const collection = await buildCollection({
|
||||
permission: null,
|
||||
@@ -1482,7 +1483,7 @@ describe("#collections.delete", () => {
|
||||
});
|
||||
await collection.$add("group", group, {
|
||||
through: {
|
||||
permission: CollectionPermission.ReadWrite,
|
||||
permission: CollectionPermission.Admin,
|
||||
createdById: user.id,
|
||||
},
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user