@@ -112,7 +112,7 @@ describe("#attachments.delete", () => {
|
||||
it("should not allow deleting an attachment belonging to a document user does not have access to", async () => {
|
||||
const user = await buildUser();
|
||||
const collection = await buildCollection({
|
||||
private: true,
|
||||
permission: null,
|
||||
});
|
||||
const document = await buildDocument({
|
||||
teamId: collection.teamId,
|
||||
@@ -184,7 +184,7 @@ describe("#attachments.redirect", () => {
|
||||
const collection = await buildCollection({
|
||||
teamId: user.teamId,
|
||||
userId: user.id,
|
||||
private: true,
|
||||
permission: null,
|
||||
});
|
||||
const document = await buildDocument({
|
||||
teamId: user.teamId,
|
||||
@@ -208,7 +208,7 @@ describe("#attachments.redirect", () => {
|
||||
it("should not return a redirect for a private attachment belonging to a document user does not have access to", async () => {
|
||||
const user = await buildUser();
|
||||
const collection = await buildCollection({
|
||||
private: true,
|
||||
permission: null,
|
||||
});
|
||||
const document = await buildDocument({
|
||||
teamId: collection.teamId,
|
||||
|
||||
@@ -39,13 +39,13 @@ router.post("collections.create", auth(), async (ctx) => {
|
||||
name,
|
||||
color,
|
||||
description,
|
||||
permission,
|
||||
sharing,
|
||||
icon,
|
||||
sort = Collection.DEFAULT_SORT,
|
||||
} = ctx.body;
|
||||
|
||||
let { index } = ctx.body;
|
||||
const isPrivate = ctx.body.private;
|
||||
ctx.assertPresent(name, "name is required");
|
||||
|
||||
if (color) {
|
||||
@@ -89,7 +89,7 @@ router.post("collections.create", auth(), async (ctx) => {
|
||||
color,
|
||||
teamId: user.teamId,
|
||||
createdById: user.id,
|
||||
private: isPrivate,
|
||||
permission: permission ? permission : null,
|
||||
sharing,
|
||||
sort,
|
||||
index,
|
||||
@@ -105,11 +105,9 @@ router.post("collections.create", auth(), async (ctx) => {
|
||||
});
|
||||
|
||||
// we must reload the collection to get memberships for policy presenter
|
||||
if (isPrivate) {
|
||||
collection = await Collection.scope({
|
||||
method: ["withMembership", user.id],
|
||||
}).findByPk(collection.id);
|
||||
}
|
||||
collection = await Collection.scope({
|
||||
method: ["withMembership", user.id],
|
||||
}).findByPk(collection.id);
|
||||
|
||||
ctx.body = {
|
||||
data: presentCollection(collection),
|
||||
@@ -514,8 +512,16 @@ router.post("collections.export_all", auth(), async (ctx) => {
|
||||
});
|
||||
|
||||
router.post("collections.update", auth(), async (ctx) => {
|
||||
let { id, name, description, icon, color, sort, sharing } = ctx.body;
|
||||
const isPrivate = ctx.body.private;
|
||||
let {
|
||||
id,
|
||||
name,
|
||||
description,
|
||||
icon,
|
||||
permission,
|
||||
color,
|
||||
sort,
|
||||
sharing,
|
||||
} = ctx.body;
|
||||
|
||||
if (color) {
|
||||
ctx.assertHexColor(color, "Invalid hex value (please use format #FFFFFF)");
|
||||
@@ -528,9 +534,9 @@ router.post("collections.update", auth(), async (ctx) => {
|
||||
|
||||
authorize(user, "update", collection);
|
||||
|
||||
// we're making this collection private right now, ensure that the current
|
||||
// we're making this collection have no default access, ensure that the current
|
||||
// user has a read-write membership so that at least they can edit it
|
||||
if (isPrivate && !collection.private) {
|
||||
if (permission !== "read_write" && collection.permission === "read_write") {
|
||||
await CollectionUser.findOrCreate({
|
||||
where: {
|
||||
collectionId: collection.id,
|
||||
@@ -543,7 +549,7 @@ router.post("collections.update", auth(), async (ctx) => {
|
||||
});
|
||||
}
|
||||
|
||||
const isPrivacyChanged = isPrivate !== collection.private;
|
||||
const permissionChanged = permission !== collection.permission;
|
||||
|
||||
if (name !== undefined) {
|
||||
collection.name = name;
|
||||
@@ -557,8 +563,8 @@ router.post("collections.update", auth(), async (ctx) => {
|
||||
if (color !== undefined) {
|
||||
collection.color = color;
|
||||
}
|
||||
if (isPrivate !== undefined) {
|
||||
collection.private = isPrivate;
|
||||
if (permission !== undefined) {
|
||||
collection.permission = permission ? permission : null;
|
||||
}
|
||||
if (sharing !== undefined) {
|
||||
collection.sharing = sharing;
|
||||
@@ -580,7 +586,7 @@ router.post("collections.update", auth(), async (ctx) => {
|
||||
|
||||
// must reload to update collection membership for correct policy calculation
|
||||
// if the privacy level has changed. Otherwise skip this query for speed.
|
||||
if (isPrivacyChanged) {
|
||||
if (permissionChanged) {
|
||||
await collection.reload();
|
||||
}
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@ describe("#collections.list", () => {
|
||||
it("should not return private collections actor is not a member of", async () => {
|
||||
const { user, collection } = await seed();
|
||||
await buildCollection({
|
||||
private: true,
|
||||
permission: null,
|
||||
teamId: user.teamId,
|
||||
});
|
||||
const res = await server.post("/api/collections.list", {
|
||||
@@ -58,12 +58,12 @@ describe("#collections.list", () => {
|
||||
it("should return private collections actor is a member of", async () => {
|
||||
const user = await buildUser();
|
||||
await buildCollection({
|
||||
private: true,
|
||||
permission: null,
|
||||
teamId: user.teamId,
|
||||
userId: user.id,
|
||||
});
|
||||
await buildCollection({
|
||||
private: true,
|
||||
permission: null,
|
||||
teamId: user.teamId,
|
||||
userId: user.id,
|
||||
});
|
||||
@@ -82,13 +82,13 @@ describe("#collections.list", () => {
|
||||
it("should return private collections actor is a group-member of", async () => {
|
||||
const user = await buildUser();
|
||||
await buildCollection({
|
||||
private: true,
|
||||
permission: null,
|
||||
teamId: user.teamId,
|
||||
userId: user.id,
|
||||
});
|
||||
|
||||
const collection = await buildCollection({
|
||||
private: true,
|
||||
permission: null,
|
||||
teamId: user.teamId,
|
||||
});
|
||||
|
||||
@@ -256,7 +256,7 @@ describe("#collections.export", () => {
|
||||
it("should now allow export of private collection not a member", async () => {
|
||||
const { user } = await seed();
|
||||
const collection = await buildCollection({
|
||||
private: true,
|
||||
permission: null,
|
||||
teamId: user.teamId,
|
||||
});
|
||||
const res = await server.post("/api/collections.export", {
|
||||
@@ -268,7 +268,7 @@ describe("#collections.export", () => {
|
||||
|
||||
it("should allow export of private collection when the actor is a member", async () => {
|
||||
const { user, collection } = await seed();
|
||||
collection.private = true;
|
||||
collection.permission = null;
|
||||
await collection.save();
|
||||
|
||||
await CollectionUser.create({
|
||||
@@ -288,7 +288,7 @@ describe("#collections.export", () => {
|
||||
it("should allow export of private collection when the actor is a group member", async () => {
|
||||
const user = await buildUser();
|
||||
const collection = await buildCollection({
|
||||
private: true,
|
||||
permission: null,
|
||||
teamId: user.teamId,
|
||||
});
|
||||
|
||||
@@ -369,7 +369,7 @@ describe("#collections.add_user", () => {
|
||||
const collection = await buildCollection({
|
||||
teamId: user.teamId,
|
||||
userId: user.id,
|
||||
private: true,
|
||||
permission: null,
|
||||
});
|
||||
const anotherUser = await buildUser({ teamId: user.teamId });
|
||||
const res = await server.post("/api/collections.add_user", {
|
||||
@@ -389,7 +389,7 @@ describe("#collections.add_user", () => {
|
||||
const user = await buildUser();
|
||||
const collection = await buildCollection({
|
||||
teamId: user.teamId,
|
||||
private: true,
|
||||
permission: null,
|
||||
});
|
||||
const anotherUser = await buildUser();
|
||||
const res = await server.post("/api/collections.add_user", {
|
||||
@@ -433,7 +433,7 @@ describe("#collections.add_group", () => {
|
||||
const collection = await buildCollection({
|
||||
teamId: user.teamId,
|
||||
userId: user.id,
|
||||
private: true,
|
||||
permission: null,
|
||||
});
|
||||
const group = await buildGroup({ teamId: user.teamId });
|
||||
const res = await server.post("/api/collections.add_group", {
|
||||
@@ -454,7 +454,7 @@ describe("#collections.add_group", () => {
|
||||
const collection = await buildCollection({
|
||||
teamId: user.teamId,
|
||||
userId: user.id,
|
||||
private: true,
|
||||
permission: null,
|
||||
});
|
||||
const group = await buildGroup();
|
||||
const res = await server.post("/api/collections.add_group", {
|
||||
@@ -496,7 +496,7 @@ describe("#collections.remove_group", () => {
|
||||
const collection = await buildCollection({
|
||||
teamId: user.teamId,
|
||||
userId: user.id,
|
||||
private: true,
|
||||
permission: null,
|
||||
});
|
||||
const group = await buildGroup({ teamId: user.teamId });
|
||||
|
||||
@@ -528,7 +528,7 @@ describe("#collections.remove_group", () => {
|
||||
const user = await buildUser();
|
||||
const collection = await buildCollection({
|
||||
teamId: user.teamId,
|
||||
private: true,
|
||||
permission: null,
|
||||
});
|
||||
const group = await buildGroup();
|
||||
const res = await server.post("/api/collections.remove_group", {
|
||||
@@ -572,7 +572,7 @@ describe("#collections.remove_user", () => {
|
||||
const collection = await buildCollection({
|
||||
teamId: user.teamId,
|
||||
userId: user.id,
|
||||
private: true,
|
||||
permission: null,
|
||||
});
|
||||
const anotherUser = await buildUser({ teamId: user.teamId });
|
||||
|
||||
@@ -601,7 +601,7 @@ describe("#collections.remove_user", () => {
|
||||
const user = await buildUser();
|
||||
const collection = await buildCollection({
|
||||
teamId: user.teamId,
|
||||
private: true,
|
||||
permission: null,
|
||||
});
|
||||
const anotherUser = await buildUser();
|
||||
const res = await server.post("/api/collections.remove_user", {
|
||||
@@ -642,7 +642,7 @@ describe("#collections.remove_user", () => {
|
||||
describe("#collections.users", () => {
|
||||
it("should return users in private collection", async () => {
|
||||
const { collection, user } = await seed();
|
||||
collection.private = true;
|
||||
collection.permission = null;
|
||||
await collection.save();
|
||||
|
||||
await CollectionUser.create({
|
||||
@@ -684,7 +684,7 @@ describe("#collections.group_memberships", () => {
|
||||
const user = await buildUser();
|
||||
const group = await buildGroup({ teamId: user.teamId });
|
||||
const collection = await buildCollection({
|
||||
private: true,
|
||||
permission: null,
|
||||
teamId: user.teamId,
|
||||
});
|
||||
|
||||
@@ -721,7 +721,7 @@ describe("#collections.group_memberships", () => {
|
||||
const group = await buildGroup({ name: "will find", teamId: user.teamId });
|
||||
const group2 = await buildGroup({ name: "wont find", teamId: user.teamId });
|
||||
const collection = await buildCollection({
|
||||
private: true,
|
||||
permission: null,
|
||||
teamId: user.teamId,
|
||||
});
|
||||
|
||||
@@ -766,7 +766,7 @@ describe("#collections.group_memberships", () => {
|
||||
const group = await buildGroup({ teamId: user.teamId });
|
||||
const group2 = await buildGroup({ teamId: user.teamId });
|
||||
const collection = await buildCollection({
|
||||
private: true,
|
||||
permission: null,
|
||||
teamId: user.teamId,
|
||||
});
|
||||
|
||||
@@ -817,7 +817,7 @@ describe("#collections.group_memberships", () => {
|
||||
it("should require authorization", async () => {
|
||||
const user = await buildUser();
|
||||
const collection = await buildCollection({
|
||||
private: true,
|
||||
permission: null,
|
||||
teamId: user.teamId,
|
||||
});
|
||||
|
||||
@@ -831,7 +831,7 @@ describe("#collections.group_memberships", () => {
|
||||
describe("#collections.memberships", () => {
|
||||
it("should return members in private collection", async () => {
|
||||
const { collection, user } = await seed();
|
||||
collection.private = true;
|
||||
collection.permission = null;
|
||||
await collection.save();
|
||||
|
||||
await CollectionUser.create({
|
||||
@@ -945,7 +945,7 @@ describe("#collections.info", () => {
|
||||
|
||||
it("should require user member of collection", async () => {
|
||||
const { user, collection } = await seed();
|
||||
collection.private = true;
|
||||
collection.permission = null;
|
||||
await collection.save();
|
||||
|
||||
const res = await server.post("/api/collections.info", {
|
||||
@@ -956,7 +956,7 @@ describe("#collections.info", () => {
|
||||
|
||||
it("should allow user member of collection", async () => {
|
||||
const { user, collection } = await seed();
|
||||
collection.private = true;
|
||||
collection.permission = null;
|
||||
await collection.save();
|
||||
|
||||
await CollectionUser.create({
|
||||
@@ -1034,12 +1034,12 @@ describe("#collections.create", () => {
|
||||
it("should return correct policies with private collection", async () => {
|
||||
const { user } = await seed();
|
||||
const res = await server.post("/api/collections.create", {
|
||||
body: { token: user.getJwtToken(), name: "Test", private: true },
|
||||
body: { token: user.getJwtToken(), name: "Test", permission: null },
|
||||
});
|
||||
const body = await res.json();
|
||||
|
||||
expect(res.status).toEqual(200);
|
||||
expect(body.data.private).toBeTruthy();
|
||||
expect(body.data.permission).toEqual(null);
|
||||
expect(body.policies.length).toBe(1);
|
||||
expect(body.policies[0].abilities.read).toBeTruthy();
|
||||
expect(body.policies[0].abilities.export).toBeTruthy();
|
||||
@@ -1176,11 +1176,11 @@ describe("#collections.update", () => {
|
||||
it("allows editing individual fields", async () => {
|
||||
const { user, collection } = await seed();
|
||||
const res = await server.post("/api/collections.update", {
|
||||
body: { token: user.getJwtToken(), id: collection.id, private: true },
|
||||
body: { token: user.getJwtToken(), id: collection.id, permission: null },
|
||||
});
|
||||
const body = await res.json();
|
||||
expect(res.status).toEqual(200);
|
||||
expect(body.data.private).toBe(true);
|
||||
expect(body.data.permission).toBe(null);
|
||||
expect(body.data.name).toBe(collection.name);
|
||||
});
|
||||
|
||||
@@ -1190,14 +1190,14 @@ describe("#collections.update", () => {
|
||||
body: {
|
||||
token: user.getJwtToken(),
|
||||
id: collection.id,
|
||||
private: true,
|
||||
permission: null,
|
||||
name: "Test",
|
||||
},
|
||||
});
|
||||
const body = await res.json();
|
||||
expect(res.status).toEqual(200);
|
||||
expect(body.data.name).toBe("Test");
|
||||
expect(body.data.private).toBe(true);
|
||||
expect(body.data.permission).toBe(null);
|
||||
|
||||
// ensure we return with a write level policy
|
||||
expect(body.policies.length).toBe(1);
|
||||
@@ -1206,7 +1206,7 @@ describe("#collections.update", () => {
|
||||
|
||||
it("allows editing from private to non-private collection", async () => {
|
||||
const { user, collection } = await seed();
|
||||
collection.private = true;
|
||||
collection.permission = null;
|
||||
await collection.save();
|
||||
|
||||
await CollectionUser.create({
|
||||
@@ -1220,14 +1220,14 @@ describe("#collections.update", () => {
|
||||
body: {
|
||||
token: user.getJwtToken(),
|
||||
id: collection.id,
|
||||
private: false,
|
||||
permission: "read_write",
|
||||
name: "Test",
|
||||
},
|
||||
});
|
||||
const body = await res.json();
|
||||
expect(res.status).toEqual(200);
|
||||
expect(body.data.name).toBe("Test");
|
||||
expect(body.data.private).toBe(false);
|
||||
expect(body.data.permission).toBe("read_write");
|
||||
|
||||
// ensure we return with a write level policy
|
||||
expect(body.policies.length).toBe(1);
|
||||
@@ -1236,7 +1236,7 @@ describe("#collections.update", () => {
|
||||
|
||||
it("allows editing by read-write collection user", async () => {
|
||||
const { user, collection } = await seed();
|
||||
collection.private = true;
|
||||
collection.permission = null;
|
||||
await collection.save();
|
||||
|
||||
await CollectionUser.create({
|
||||
@@ -1258,7 +1258,7 @@ describe("#collections.update", () => {
|
||||
it("allows editing by read-write collection group user", async () => {
|
||||
const user = await buildUser();
|
||||
const collection = await buildCollection({
|
||||
private: true,
|
||||
permission: null,
|
||||
teamId: user.teamId,
|
||||
});
|
||||
|
||||
@@ -1280,7 +1280,7 @@ describe("#collections.update", () => {
|
||||
|
||||
it("does not allow editing by read-only collection user", async () => {
|
||||
const { user, collection } = await seed();
|
||||
collection.private = true;
|
||||
collection.permission = null;
|
||||
await collection.save();
|
||||
|
||||
await CollectionUser.create({
|
||||
@@ -1393,7 +1393,7 @@ describe("#collections.delete", () => {
|
||||
it("allows deleting by read-write collection group user", async () => {
|
||||
const user = await buildUser();
|
||||
const collection = await buildCollection({
|
||||
private: true,
|
||||
permission: null,
|
||||
teamId: user.teamId,
|
||||
});
|
||||
await buildCollection({
|
||||
|
||||
@@ -50,7 +50,7 @@ describe("#documents.info", () => {
|
||||
it("should not return published document in collection not a member of", async () => {
|
||||
const user = await buildUser();
|
||||
const collection = await buildCollection({
|
||||
private: true,
|
||||
permission: null,
|
||||
teamId: user.teamId,
|
||||
});
|
||||
const document = await buildDocument({ collectionId: collection.id });
|
||||
@@ -209,7 +209,7 @@ describe("#documents.info", () => {
|
||||
userId: user.id,
|
||||
});
|
||||
|
||||
collection.private = true;
|
||||
collection.permission = null;
|
||||
await collection.save();
|
||||
|
||||
const res = await server.post("/api/documents.info", {
|
||||
@@ -282,7 +282,7 @@ describe("#documents.export", () => {
|
||||
it("should not return published document in collection not a member of", async () => {
|
||||
const user = await buildUser();
|
||||
const collection = await buildCollection({
|
||||
private: true,
|
||||
permission: null,
|
||||
teamId: user.teamId,
|
||||
});
|
||||
const document = await buildDocument({ collectionId: collection.id });
|
||||
@@ -400,7 +400,7 @@ describe("#documents.export", () => {
|
||||
userId: user.id,
|
||||
});
|
||||
|
||||
collection.private = true;
|
||||
collection.permission = null;
|
||||
await collection.save();
|
||||
|
||||
const res = await server.post("/api/documents.export", {
|
||||
@@ -501,7 +501,7 @@ describe("#documents.list", () => {
|
||||
|
||||
it("should not return documents in private collections not a member of", async () => {
|
||||
const { user, collection } = await seed();
|
||||
collection.private = true;
|
||||
collection.permission = null;
|
||||
await collection.save();
|
||||
|
||||
const res = await server.post("/api/documents.list", {
|
||||
@@ -573,7 +573,7 @@ describe("#documents.list", () => {
|
||||
|
||||
it("should allow filtering to private collection", async () => {
|
||||
const { user, collection } = await seed();
|
||||
collection.private = true;
|
||||
collection.permission = null;
|
||||
await collection.save();
|
||||
|
||||
await CollectionUser.create({
|
||||
@@ -647,7 +647,7 @@ describe("#documents.pinned", () => {
|
||||
|
||||
it("should return pinned documents in private collections member of", async () => {
|
||||
const { user, collection, document } = await seed();
|
||||
collection.private = true;
|
||||
collection.permission = null;
|
||||
await collection.save();
|
||||
|
||||
document.pinnedById = user.id;
|
||||
@@ -672,7 +672,7 @@ describe("#documents.pinned", () => {
|
||||
|
||||
it("should not return pinned documents in private collections not a member of", async () => {
|
||||
const collection = await buildCollection({
|
||||
private: true,
|
||||
permission: null,
|
||||
});
|
||||
|
||||
const user = await buildUser({ teamId: collection.teamId });
|
||||
@@ -710,7 +710,7 @@ describe("#documents.drafts", () => {
|
||||
document.publishedAt = null;
|
||||
await document.save();
|
||||
|
||||
collection.private = true;
|
||||
collection.permission = null;
|
||||
await collection.save();
|
||||
|
||||
const res = await server.post("/api/documents.drafts", {
|
||||
@@ -996,7 +996,7 @@ describe("#documents.search", () => {
|
||||
|
||||
it("should return documents for a specific private collection", async () => {
|
||||
const { user, collection } = await seed();
|
||||
collection.private = true;
|
||||
collection.permission = null;
|
||||
await collection.save();
|
||||
|
||||
await CollectionUser.create({
|
||||
@@ -1061,7 +1061,7 @@ describe("#documents.search", () => {
|
||||
|
||||
it("should not return documents in private collections not a member of", async () => {
|
||||
const { user } = await seed();
|
||||
const collection = await buildCollection({ private: true });
|
||||
const collection = await buildCollection({ permission: null });
|
||||
|
||||
await buildDocument({
|
||||
title: "search term",
|
||||
@@ -1158,7 +1158,7 @@ describe("#documents.archived", () => {
|
||||
|
||||
it("should not return documents in private collections not a member of", async () => {
|
||||
const { user } = await seed();
|
||||
const collection = await buildCollection({ private: true });
|
||||
const collection = await buildCollection({ permission: null });
|
||||
|
||||
const document = await buildDocument({
|
||||
teamId: user.teamId,
|
||||
@@ -1224,7 +1224,7 @@ describe("#documents.viewed", () => {
|
||||
it("should not return recently viewed documents in collection not a member of", async () => {
|
||||
const { user, document, collection } = await seed();
|
||||
await View.increment({ documentId: document.id, userId: user.id });
|
||||
collection.private = true;
|
||||
collection.permission = null;
|
||||
await collection.save();
|
||||
|
||||
const res = await server.post("/api/documents.viewed", {
|
||||
@@ -1808,7 +1808,7 @@ describe("#documents.update", () => {
|
||||
document.publishedAt = null;
|
||||
await document.save();
|
||||
|
||||
collection.private = true;
|
||||
collection.permission = null;
|
||||
await collection.save();
|
||||
|
||||
await CollectionUser.create({
|
||||
@@ -1903,7 +1903,7 @@ describe("#documents.update", () => {
|
||||
|
||||
it("allows editing by read-write collection user", async () => {
|
||||
const { admin, document, collection } = await seed();
|
||||
collection.private = true;
|
||||
collection.permission = null;
|
||||
await collection.save();
|
||||
|
||||
await CollectionUser.create({
|
||||
@@ -1931,7 +1931,7 @@ describe("#documents.update", () => {
|
||||
|
||||
it("does not allow editing by read-only collection user", async () => {
|
||||
const { user, document, collection } = await seed();
|
||||
collection.private = true;
|
||||
collection.permission = null;
|
||||
await collection.save();
|
||||
|
||||
await CollectionUser.create({
|
||||
@@ -1953,6 +1953,23 @@ describe("#documents.update", () => {
|
||||
expect(res.status).toEqual(403);
|
||||
});
|
||||
|
||||
it("does not allow editing in read-only collection", async () => {
|
||||
const { user, document, collection } = await seed();
|
||||
collection.permission = "read";
|
||||
await collection.save();
|
||||
|
||||
const res = await server.post("/api/documents.update", {
|
||||
body: {
|
||||
token: user.getJwtToken(),
|
||||
id: document.id,
|
||||
text: "Changed text",
|
||||
lastRevision: document.revision,
|
||||
},
|
||||
});
|
||||
|
||||
expect(res.status).toEqual(403);
|
||||
});
|
||||
|
||||
it("should append document with text", async () => {
|
||||
const { user, document } = await seed();
|
||||
|
||||
|
||||
@@ -66,7 +66,7 @@ describe("#revisions.list", () => {
|
||||
const { user, document, collection } = await seed();
|
||||
await Revision.createFromDocument(document);
|
||||
|
||||
collection.private = true;
|
||||
collection.permission = null;
|
||||
await collection.save();
|
||||
|
||||
const res = await server.post("/api/revisions.list", {
|
||||
|
||||
@@ -115,7 +115,7 @@ describe("#shares.list", () => {
|
||||
userId: admin.id,
|
||||
});
|
||||
|
||||
collection.private = true;
|
||||
collection.permission = null;
|
||||
await collection.save();
|
||||
|
||||
const res = await server.post("/api/shares.list", {
|
||||
@@ -151,7 +151,7 @@ describe("#shares.create", () => {
|
||||
|
||||
it("should not allow creating a share record with read-only permissions", async () => {
|
||||
const { user, document, collection } = await seed();
|
||||
collection.private = true;
|
||||
collection.permission = null;
|
||||
|
||||
await collection.save();
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ describe("#views.list", () => {
|
||||
|
||||
it("should return views for a document in read-only collection", async () => {
|
||||
const { user, document, collection } = await seed();
|
||||
collection.private = true;
|
||||
collection.permission = null;
|
||||
await collection.save();
|
||||
|
||||
await CollectionUser.create({
|
||||
@@ -84,7 +84,7 @@ describe("#views.create", () => {
|
||||
|
||||
it("should allow creating a view record for document in read-only collection", async () => {
|
||||
const { user, document, collection } = await seed();
|
||||
collection.private = true;
|
||||
collection.permission = null;
|
||||
await collection.save();
|
||||
|
||||
await CollectionUser.create({
|
||||
|
||||
@@ -58,7 +58,7 @@ export default async function collectionImporter({
|
||||
},
|
||||
defaults: {
|
||||
createdById: user.id,
|
||||
private: false,
|
||||
permission: "read_write",
|
||||
},
|
||||
});
|
||||
|
||||
@@ -71,7 +71,7 @@ export default async function collectionImporter({
|
||||
teamId: user.teamId,
|
||||
createdById: user.id,
|
||||
name,
|
||||
private: false,
|
||||
permission: "read_write",
|
||||
});
|
||||
await Event.create({
|
||||
name: "collections.create",
|
||||
|
||||
38
server/migrations/20210327005406-read-only-collections.js
Normal file
38
server/migrations/20210327005406-read-only-collections.js
Normal file
@@ -0,0 +1,38 @@
|
||||
'use strict';
|
||||
|
||||
module.exports = {
|
||||
up: async (queryInterface, Sequelize) => {
|
||||
await queryInterface.addColumn("collections", "permission", {
|
||||
type: Sequelize.STRING,
|
||||
defaultValue: null,
|
||||
allowNull: true,
|
||||
validate: {
|
||||
isIn: [["read", "read_write"]],
|
||||
},
|
||||
});
|
||||
|
||||
await queryInterface.sequelize.query(`
|
||||
UPDATE collections
|
||||
SET "permission" = 'read_write'
|
||||
WHERE "private" = false
|
||||
`);
|
||||
|
||||
await queryInterface.removeColumn("collections", "private");
|
||||
},
|
||||
|
||||
down: async (queryInterface, Sequelize) => {
|
||||
await queryInterface.addColumn("collections", "private", {
|
||||
type: Sequelize.BOOLEAN,
|
||||
allowNull: false,
|
||||
defaultValue: false
|
||||
});
|
||||
|
||||
await queryInterface.sequelize.query(`
|
||||
UPDATE collections
|
||||
SET "private" = true
|
||||
WHERE "permission" IS NULL
|
||||
`);
|
||||
|
||||
await queryInterface.removeColumn("collections", "permission");
|
||||
}
|
||||
};
|
||||
@@ -25,7 +25,14 @@ const Collection = sequelize.define(
|
||||
type: DataTypes.STRING,
|
||||
defaultValue: null,
|
||||
},
|
||||
private: DataTypes.BOOLEAN,
|
||||
permission: {
|
||||
type: DataTypes.STRING,
|
||||
defaultValue: null,
|
||||
allowNull: true,
|
||||
validate: {
|
||||
isIn: [["read", "read_write"]],
|
||||
},
|
||||
},
|
||||
maintainerApprovalRequired: DataTypes.BOOLEAN,
|
||||
documentStructure: DataTypes.JSONB,
|
||||
sharing: {
|
||||
@@ -199,7 +206,7 @@ Collection.addHook("afterDestroy", async (model: Collection) => {
|
||||
});
|
||||
|
||||
Collection.addHook("afterCreate", (model: Collection, options) => {
|
||||
if (model.private) {
|
||||
if (model.permission !== "read_write") {
|
||||
return CollectionUser.findOrCreate({
|
||||
where: {
|
||||
collectionId: model.id,
|
||||
|
||||
@@ -254,7 +254,7 @@ describe("#membershipUserIds", () => {
|
||||
|
||||
const collection = await buildCollection({
|
||||
userId: users[0].id,
|
||||
private: true,
|
||||
permission: null,
|
||||
teamId,
|
||||
});
|
||||
|
||||
|
||||
@@ -178,7 +178,7 @@ describe("#searchForTeam", () => {
|
||||
test("should not return search results from private collections", async () => {
|
||||
const team = await buildTeam();
|
||||
const collection = await buildCollection({
|
||||
private: true,
|
||||
permission: null,
|
||||
teamId: team.id,
|
||||
});
|
||||
await buildDocument({
|
||||
|
||||
@@ -15,11 +15,11 @@ describe("afterDestroy hook", () => {
|
||||
const user2 = await buildUser({ teamId });
|
||||
|
||||
const collection1 = await buildCollection({
|
||||
private: true,
|
||||
permission: null,
|
||||
teamId,
|
||||
});
|
||||
const collection2 = await buildCollection({
|
||||
private: true,
|
||||
permission: null,
|
||||
teamId,
|
||||
});
|
||||
|
||||
|
||||
@@ -225,10 +225,16 @@ Team.prototype.activateUser = async function (user: User, admin: User) {
|
||||
|
||||
Team.prototype.collectionIds = async function (paranoid: boolean = true) {
|
||||
let models = await Collection.findAll({
|
||||
attributes: ["id", "private"],
|
||||
where: { teamId: this.id, private: false },
|
||||
attributes: ["id"],
|
||||
where: {
|
||||
teamId: this.id,
|
||||
permission: {
|
||||
[Op.ne]: null,
|
||||
},
|
||||
},
|
||||
paranoid,
|
||||
});
|
||||
|
||||
return models.map((c) => c.id);
|
||||
};
|
||||
|
||||
|
||||
@@ -1,38 +1,56 @@
|
||||
/* eslint-disable flowtype/require-valid-file-annotation */
|
||||
import { buildTeam } from "../test/factories";
|
||||
// @flow
|
||||
import { buildTeam, buildCollection } from "../test/factories";
|
||||
import { flushdb } from "../test/support";
|
||||
|
||||
beforeEach(() => flushdb());
|
||||
|
||||
it("should set subdomain if available", async () => {
|
||||
const team = await buildTeam();
|
||||
const subdomain = await team.provisionSubdomain("testy");
|
||||
expect(subdomain).toEqual("testy");
|
||||
expect(team.subdomain).toEqual("testy");
|
||||
describe("collectionIds", () => {
|
||||
it("should return non-private collection ids", async () => {
|
||||
const team = await buildTeam();
|
||||
const collection = await buildCollection({ teamId: team.id });
|
||||
|
||||
// build a collection in another team
|
||||
await buildCollection();
|
||||
|
||||
// build a private collection
|
||||
await buildCollection({ teamId: team.id, permission: null });
|
||||
const response = await team.collectionIds();
|
||||
expect(response.length).toEqual(1);
|
||||
expect(response[0]).toEqual(collection.id);
|
||||
});
|
||||
});
|
||||
|
||||
it("should set subdomain append if unavailable", async () => {
|
||||
await buildTeam({ subdomain: "myteam" });
|
||||
describe("provisionSubdomain", () => {
|
||||
it("should set subdomain if available", async () => {
|
||||
const team = await buildTeam();
|
||||
const subdomain = await team.provisionSubdomain("testy");
|
||||
expect(subdomain).toEqual("testy");
|
||||
expect(team.subdomain).toEqual("testy");
|
||||
});
|
||||
|
||||
const team = await buildTeam();
|
||||
const subdomain = await team.provisionSubdomain("myteam");
|
||||
expect(subdomain).toEqual("myteam1");
|
||||
expect(team.subdomain).toEqual("myteam1");
|
||||
});
|
||||
|
||||
it("should increment subdomain append if unavailable", async () => {
|
||||
await buildTeam({ subdomain: "myteam" });
|
||||
await buildTeam({ subdomain: "myteam1" });
|
||||
|
||||
const team = await buildTeam();
|
||||
const subdomain = await team.provisionSubdomain("myteam");
|
||||
expect(subdomain).toEqual("myteam2");
|
||||
expect(team.subdomain).toEqual("myteam2");
|
||||
});
|
||||
|
||||
it("should do nothing if subdomain already set", async () => {
|
||||
const team = await buildTeam({ subdomain: "example" });
|
||||
const subdomain = await team.provisionSubdomain("myteam");
|
||||
expect(subdomain).toEqual("example");
|
||||
expect(team.subdomain).toEqual("example");
|
||||
it("should set subdomain append if unavailable", async () => {
|
||||
await buildTeam({ subdomain: "myteam" });
|
||||
|
||||
const team = await buildTeam();
|
||||
const subdomain = await team.provisionSubdomain("myteam");
|
||||
expect(subdomain).toEqual("myteam1");
|
||||
expect(team.subdomain).toEqual("myteam1");
|
||||
});
|
||||
|
||||
it("should increment subdomain append if unavailable", async () => {
|
||||
await buildTeam({ subdomain: "myteam" });
|
||||
await buildTeam({ subdomain: "myteam1" });
|
||||
|
||||
const team = await buildTeam();
|
||||
const subdomain = await team.provisionSubdomain("myteam");
|
||||
expect(subdomain).toEqual("myteam2");
|
||||
expect(team.subdomain).toEqual("myteam2");
|
||||
});
|
||||
|
||||
it("should do nothing if subdomain already set", async () => {
|
||||
const team = await buildTeam({ subdomain: "example" });
|
||||
const subdomain = await team.provisionSubdomain("myteam");
|
||||
expect(subdomain).toEqual("example");
|
||||
expect(team.subdomain).toEqual("example");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -91,7 +91,7 @@ User.prototype.collectionIds = async function (options = {}) {
|
||||
const collectionStubs = await Collection.scope({
|
||||
method: ["withMembership", this.id],
|
||||
}).findAll({
|
||||
attributes: ["id", "private"],
|
||||
attributes: ["id", "permission"],
|
||||
where: { teamId: this.teamId },
|
||||
paranoid: true,
|
||||
...options,
|
||||
@@ -100,7 +100,8 @@ User.prototype.collectionIds = async function (options = {}) {
|
||||
return collectionStubs
|
||||
.filter(
|
||||
(c) =>
|
||||
!c.private ||
|
||||
c.permission === "read" ||
|
||||
c.permission === "read_write" ||
|
||||
c.memberships.length > 0 ||
|
||||
c.collectionGroupMemberships.length > 0
|
||||
)
|
||||
|
||||
@@ -1,10 +1,75 @@
|
||||
/* eslint-disable flowtype/require-valid-file-annotation */
|
||||
import { buildUser } from "../test/factories";
|
||||
// @flow
|
||||
import { CollectionUser } from "../models";
|
||||
import { buildUser, buildTeam, buildCollection } from "../test/factories";
|
||||
import { flushdb } from "../test/support";
|
||||
|
||||
beforeEach(() => flushdb());
|
||||
|
||||
it("should set JWT secret", async () => {
|
||||
const user = await buildUser();
|
||||
expect(user.getJwtToken()).toBeTruthy();
|
||||
describe("user model", () => {
|
||||
describe("getJwtToken", () => {
|
||||
it("should set JWT secret", async () => {
|
||||
const user = await buildUser();
|
||||
expect(user.getJwtToken()).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
describe("collectionIds", () => {
|
||||
it("should return read_write collections", async () => {
|
||||
const team = await buildTeam();
|
||||
const user = await buildUser({ teamId: team.id });
|
||||
const collection = await buildCollection({
|
||||
teamId: team.id,
|
||||
permission: "read_write",
|
||||
});
|
||||
|
||||
const response = await user.collectionIds();
|
||||
expect(response.length).toEqual(1);
|
||||
expect(response[0]).toEqual(collection.id);
|
||||
});
|
||||
|
||||
it("should return read collections", async () => {
|
||||
const team = await buildTeam();
|
||||
const user = await buildUser({ teamId: team.id });
|
||||
const collection = await buildCollection({
|
||||
teamId: team.id,
|
||||
permission: "read",
|
||||
});
|
||||
|
||||
const response = await user.collectionIds();
|
||||
expect(response.length).toEqual(1);
|
||||
expect(response[0]).toEqual(collection.id);
|
||||
});
|
||||
|
||||
it("should not return private collections", async () => {
|
||||
const team = await buildTeam();
|
||||
const user = await buildUser({ teamId: team.id });
|
||||
await buildCollection({
|
||||
teamId: team.id,
|
||||
permission: null,
|
||||
});
|
||||
|
||||
const response = await user.collectionIds();
|
||||
expect(response.length).toEqual(0);
|
||||
});
|
||||
|
||||
it("should not return private collection with membership", async () => {
|
||||
const team = await buildTeam();
|
||||
const user = await buildUser({ teamId: team.id });
|
||||
const collection = await buildCollection({
|
||||
teamId: team.id,
|
||||
permission: null,
|
||||
});
|
||||
|
||||
await CollectionUser.create({
|
||||
createdById: user.id,
|
||||
collectionId: collection.id,
|
||||
userId: user.id,
|
||||
permission: "read",
|
||||
});
|
||||
|
||||
const response = await user.collectionIds();
|
||||
expect(response.length).toEqual(1);
|
||||
expect(response[0]).toEqual(collection.id);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -28,7 +28,7 @@ allow(User, "move", Collection, (user, collection) => {
|
||||
allow(User, ["read", "export"], Collection, (user, collection) => {
|
||||
if (!collection || user.teamId !== collection.teamId) return false;
|
||||
|
||||
if (collection.private) {
|
||||
if (!collection.permission) {
|
||||
invariant(
|
||||
collection.memberships,
|
||||
"membership should be preloaded, did you forget withMembership scope?"
|
||||
@@ -51,7 +51,7 @@ allow(User, "share", Collection, (user, collection) => {
|
||||
if (!collection || user.teamId !== collection.teamId) return false;
|
||||
if (!collection.sharing) return false;
|
||||
|
||||
if (collection.private) {
|
||||
if (collection.permission !== "read_write") {
|
||||
invariant(
|
||||
collection.memberships,
|
||||
"membership should be preloaded, did you forget withMembership scope?"
|
||||
@@ -73,7 +73,7 @@ allow(User, "share", Collection, (user, collection) => {
|
||||
allow(User, ["publish", "update"], Collection, (user, collection) => {
|
||||
if (!collection || user.teamId !== collection.teamId) return false;
|
||||
|
||||
if (collection.private) {
|
||||
if (collection.permission !== "read_write") {
|
||||
invariant(
|
||||
collection.memberships,
|
||||
"membership should be preloaded, did you forget withMembership scope?"
|
||||
@@ -95,7 +95,7 @@ allow(User, ["publish", "update"], Collection, (user, collection) => {
|
||||
allow(User, "delete", Collection, (user, collection) => {
|
||||
if (!collection || user.teamId !== collection.teamId) return false;
|
||||
|
||||
if (collection.private) {
|
||||
if (collection.permission !== "read_write") {
|
||||
invariant(
|
||||
collection.memberships,
|
||||
"membership should be preloaded, did you forget withMembership scope?"
|
||||
|
||||
136
server/policies/collection.test.js
Normal file
136
server/policies/collection.test.js
Normal file
@@ -0,0 +1,136 @@
|
||||
// @flow
|
||||
import { CollectionUser, Collection } from "../models";
|
||||
import { buildUser, buildTeam, buildCollection } from "../test/factories";
|
||||
import { flushdb } from "../test/support";
|
||||
import { serialize } from "./index";
|
||||
|
||||
beforeEach(() => flushdb());
|
||||
|
||||
describe("read_write permission", () => {
|
||||
it("should allow read write permissions for team member", async () => {
|
||||
const team = await buildTeam();
|
||||
const user = await buildUser({ teamId: team.id });
|
||||
const collection = await buildCollection({
|
||||
teamId: team.id,
|
||||
permission: "read_write",
|
||||
});
|
||||
const abilities = serialize(user, collection);
|
||||
expect(abilities.read).toEqual(true);
|
||||
expect(abilities.export).toEqual(true);
|
||||
expect(abilities.update).toEqual(true);
|
||||
expect(abilities.share).toEqual(true);
|
||||
});
|
||||
|
||||
it("should override read membership permission", async () => {
|
||||
const team = await buildTeam();
|
||||
const user = await buildUser({ teamId: team.id });
|
||||
let collection = await buildCollection({
|
||||
teamId: team.id,
|
||||
permission: "read_write",
|
||||
});
|
||||
|
||||
await CollectionUser.create({
|
||||
createdById: user.id,
|
||||
collectionId: collection.id,
|
||||
userId: user.id,
|
||||
permission: "read",
|
||||
});
|
||||
|
||||
// reload to get membership
|
||||
collection = await Collection.scope({
|
||||
method: ["withMembership", user.id],
|
||||
}).findByPk(collection.id);
|
||||
|
||||
const abilities = serialize(user, collection);
|
||||
expect(abilities.read).toEqual(true);
|
||||
expect(abilities.export).toEqual(true);
|
||||
expect(abilities.update).toEqual(true);
|
||||
expect(abilities.share).toEqual(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe("read permission", () => {
|
||||
it("should allow read permissions for team member", async () => {
|
||||
const team = await buildTeam();
|
||||
const user = await buildUser({ teamId: team.id });
|
||||
const collection = await buildCollection({
|
||||
teamId: team.id,
|
||||
permission: "read",
|
||||
});
|
||||
const abilities = serialize(user, collection);
|
||||
expect(abilities.read).toEqual(true);
|
||||
expect(abilities.export).toEqual(true);
|
||||
expect(abilities.update).toEqual(false);
|
||||
expect(abilities.share).toEqual(false);
|
||||
});
|
||||
|
||||
it("should allow override with read_write membership permission", async () => {
|
||||
const team = await buildTeam();
|
||||
const user = await buildUser({ teamId: team.id });
|
||||
let collection = await buildCollection({
|
||||
teamId: team.id,
|
||||
permission: "read",
|
||||
});
|
||||
|
||||
await CollectionUser.create({
|
||||
createdById: user.id,
|
||||
collectionId: collection.id,
|
||||
userId: user.id,
|
||||
permission: "read_write",
|
||||
});
|
||||
|
||||
// reload to get membership
|
||||
collection = await Collection.scope({
|
||||
method: ["withMembership", user.id],
|
||||
}).findByPk(collection.id);
|
||||
|
||||
const abilities = serialize(user, collection);
|
||||
expect(abilities.read).toEqual(true);
|
||||
expect(abilities.export).toEqual(true);
|
||||
expect(abilities.update).toEqual(true);
|
||||
expect(abilities.share).toEqual(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe("no permission", () => {
|
||||
it("should allow no permissions for team member", async () => {
|
||||
const team = await buildTeam();
|
||||
const user = await buildUser({ teamId: team.id });
|
||||
const collection = await buildCollection({
|
||||
teamId: team.id,
|
||||
permission: null,
|
||||
});
|
||||
const abilities = serialize(user, collection);
|
||||
expect(abilities.read).toEqual(false);
|
||||
expect(abilities.export).toEqual(false);
|
||||
expect(abilities.update).toEqual(false);
|
||||
expect(abilities.share).toEqual(false);
|
||||
});
|
||||
|
||||
it("should allow override with team member membership permission", async () => {
|
||||
const team = await buildTeam();
|
||||
const user = await buildUser({ teamId: team.id });
|
||||
let collection = await buildCollection({
|
||||
teamId: team.id,
|
||||
permission: null,
|
||||
});
|
||||
|
||||
await CollectionUser.create({
|
||||
createdById: user.id,
|
||||
collectionId: collection.id,
|
||||
userId: user.id,
|
||||
permission: "read_write",
|
||||
});
|
||||
|
||||
// reload to get membership
|
||||
collection = await Collection.scope({
|
||||
method: ["withMembership", user.id],
|
||||
}).findByPk(collection.id);
|
||||
|
||||
const abilities = serialize(user, collection);
|
||||
expect(abilities.read).toEqual(true);
|
||||
expect(abilities.export).toEqual(true);
|
||||
expect(abilities.update).toEqual(true);
|
||||
expect(abilities.share).toEqual(true);
|
||||
});
|
||||
});
|
||||
83
server/policies/document.test.js
Normal file
83
server/policies/document.test.js
Normal file
@@ -0,0 +1,83 @@
|
||||
// @flow
|
||||
import {
|
||||
buildUser,
|
||||
buildTeam,
|
||||
buildDocument,
|
||||
buildCollection,
|
||||
} from "../test/factories";
|
||||
import { flushdb } from "../test/support";
|
||||
import { serialize } from "./index";
|
||||
|
||||
beforeEach(() => flushdb());
|
||||
|
||||
describe("read_write collection", () => {
|
||||
it("should allow read write permissions for team member", async () => {
|
||||
const team = await buildTeam();
|
||||
const user = await buildUser({ teamId: team.id });
|
||||
const collection = await buildCollection({
|
||||
teamId: team.id,
|
||||
permission: "read_write",
|
||||
});
|
||||
const document = await buildDocument({
|
||||
teamId: team.id,
|
||||
collectionId: collection.id,
|
||||
});
|
||||
const abilities = serialize(user, document);
|
||||
expect(abilities.read).toEqual(true);
|
||||
expect(abilities.download).toEqual(true);
|
||||
expect(abilities.update).toEqual(true);
|
||||
expect(abilities.createChildDocument).toEqual(true);
|
||||
expect(abilities.archive).toEqual(true);
|
||||
expect(abilities.delete).toEqual(true);
|
||||
expect(abilities.share).toEqual(true);
|
||||
expect(abilities.move).toEqual(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe("read collection", () => {
|
||||
it("should allow read only permissions permissions for team member", async () => {
|
||||
const team = await buildTeam();
|
||||
const user = await buildUser({ teamId: team.id });
|
||||
const collection = await buildCollection({
|
||||
teamId: team.id,
|
||||
permission: "read",
|
||||
});
|
||||
const document = await buildDocument({
|
||||
teamId: team.id,
|
||||
collectionId: collection.id,
|
||||
});
|
||||
const abilities = serialize(user, document);
|
||||
expect(abilities.read).toEqual(true);
|
||||
expect(abilities.download).toEqual(true);
|
||||
expect(abilities.update).toEqual(false);
|
||||
expect(abilities.createChildDocument).toEqual(false);
|
||||
expect(abilities.archive).toEqual(false);
|
||||
expect(abilities.delete).toEqual(false);
|
||||
expect(abilities.share).toEqual(false);
|
||||
expect(abilities.move).toEqual(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe("private collection", () => {
|
||||
it("should allow no permissions for team member", async () => {
|
||||
const team = await buildTeam();
|
||||
const user = await buildUser({ teamId: team.id });
|
||||
const collection = await buildCollection({
|
||||
teamId: team.id,
|
||||
permission: null,
|
||||
});
|
||||
const document = await buildDocument({
|
||||
teamId: team.id,
|
||||
collectionId: collection.id,
|
||||
});
|
||||
const abilities = serialize(user, document);
|
||||
expect(abilities.read).toEqual(false);
|
||||
expect(abilities.download).toEqual(false);
|
||||
expect(abilities.update).toEqual(false);
|
||||
expect(abilities.createChildDocument).toEqual(false);
|
||||
expect(abilities.archive).toEqual(false);
|
||||
expect(abilities.delete).toEqual(false);
|
||||
expect(abilities.share).toEqual(false);
|
||||
expect(abilities.move).toEqual(false);
|
||||
});
|
||||
});
|
||||
@@ -30,7 +30,7 @@ export default function present(collection: Collection) {
|
||||
icon: collection.icon,
|
||||
index: collection.index,
|
||||
color: collection.color || "#4E5C6E",
|
||||
private: collection.private,
|
||||
permission: collection.permission,
|
||||
sharing: collection.sharing,
|
||||
createdAt: collection.createdAt,
|
||||
updatedAt: collection.updatedAt,
|
||||
|
||||
@@ -122,7 +122,7 @@ export default class Notifications {
|
||||
],
|
||||
});
|
||||
if (!collection) return;
|
||||
if (collection.private) return;
|
||||
if (!collection.permission) return;
|
||||
|
||||
const notificationSettings = await NotificationSetting.findAll({
|
||||
where: {
|
||||
|
||||
@@ -64,7 +64,7 @@ describe("documents.publish", () => {
|
||||
const user = await buildUser();
|
||||
const collection = await buildCollection({
|
||||
teamId: user.teamId,
|
||||
private: true,
|
||||
permission: null,
|
||||
});
|
||||
const document = await buildDocument({
|
||||
teamId: user.teamId,
|
||||
|
||||
@@ -157,9 +157,9 @@ export default class Websockets {
|
||||
|
||||
socketio
|
||||
.to(
|
||||
collection.private
|
||||
? `collection-${collection.id}`
|
||||
: `team-${collection.teamId}`
|
||||
collection.permission
|
||||
? `team-${collection.teamId}`
|
||||
: `collection-${collection.id}`
|
||||
)
|
||||
.emit("entities", {
|
||||
event: event.name,
|
||||
@@ -173,9 +173,9 @@ export default class Websockets {
|
||||
|
||||
return socketio
|
||||
.to(
|
||||
collection.private
|
||||
? `collection-${collection.id}`
|
||||
: `team-${collection.teamId}`
|
||||
collection.permission
|
||||
? `team-${collection.teamId}`
|
||||
: `collection-${collection.id}`
|
||||
)
|
||||
.emit("join", {
|
||||
event: event.name,
|
||||
|
||||
@@ -159,6 +159,7 @@ export async function buildCollection(overrides: Object = {}) {
|
||||
name: `Test Collection ${count}`,
|
||||
description: "Test collection description",
|
||||
createdById: overrides.userId,
|
||||
permission: "read_write",
|
||||
...overrides,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -78,6 +78,7 @@ export const seed = async () => {
|
||||
urlId: "collection",
|
||||
teamId: team.id,
|
||||
createdById: user.id,
|
||||
permission: "read_write",
|
||||
});
|
||||
|
||||
const document = await Document.create({
|
||||
|
||||
Reference in New Issue
Block a user