feat: Allow viewers to be upgraded to editors on individual collections (#4023)
* Improve types * More types, fix default permission for viewers added to collection * fix change of default role for CollectionGroup * Restore policy * test * tests
This commit is contained in:
@@ -130,12 +130,3 @@ Object {
|
||||
"status": 401,
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`#collections.users should require authentication 1`] = `
|
||||
Object {
|
||||
"error": "authentication_required",
|
||||
"message": "Authentication required",
|
||||
"ok": false,
|
||||
"status": 401,
|
||||
}
|
||||
`;
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { CollectionPermission } from "@shared/types";
|
||||
import { colorPalette } from "@shared/utils/collections";
|
||||
import { Document, CollectionUser, CollectionGroup } from "@server/models";
|
||||
import {
|
||||
@@ -101,7 +102,7 @@ describe("#collections.list", () => {
|
||||
});
|
||||
await collection.$add("group", group, {
|
||||
through: {
|
||||
permission: "read",
|
||||
permission: CollectionPermission.Read,
|
||||
createdById: user.id,
|
||||
},
|
||||
});
|
||||
@@ -293,7 +294,7 @@ describe("#collections.export", () => {
|
||||
createdById: admin.id,
|
||||
collectionId: collection.id,
|
||||
userId: admin.id,
|
||||
permission: "read_write",
|
||||
permission: CollectionPermission.ReadWrite,
|
||||
});
|
||||
const res = await server.post("/api/collections.export", {
|
||||
body: {
|
||||
@@ -320,7 +321,7 @@ describe("#collections.export", () => {
|
||||
});
|
||||
await collection.$add("group", group, {
|
||||
through: {
|
||||
permission: "read_write",
|
||||
permission: CollectionPermission.ReadWrite,
|
||||
createdById: admin.id,
|
||||
},
|
||||
});
|
||||
@@ -671,48 +672,6 @@ describe("#collections.remove_user", () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe("#collections.users", () => {
|
||||
it("should return users in private collection", async () => {
|
||||
const { collection, user } = await seed();
|
||||
collection.permission = null;
|
||||
await collection.save();
|
||||
await CollectionUser.create({
|
||||
createdById: user.id,
|
||||
collectionId: collection.id,
|
||||
userId: user.id,
|
||||
permission: "read",
|
||||
});
|
||||
const res = await server.post("/api/collections.users", {
|
||||
body: {
|
||||
token: user.getJwtToken(),
|
||||
id: collection.id,
|
||||
},
|
||||
});
|
||||
const body = await res.json();
|
||||
expect(res.status).toEqual(200);
|
||||
expect(body.data.length).toEqual(1);
|
||||
});
|
||||
|
||||
it("should require authentication", async () => {
|
||||
const res = await server.post("/api/collections.users");
|
||||
const body = await res.json();
|
||||
expect(res.status).toEqual(401);
|
||||
expect(body).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("should require authorization", async () => {
|
||||
const { collection } = await seed();
|
||||
const user = await buildUser();
|
||||
const res = await server.post("/api/collections.users", {
|
||||
body: {
|
||||
token: user.getJwtToken(),
|
||||
id: collection.id,
|
||||
},
|
||||
});
|
||||
expect(res.status).toEqual(403);
|
||||
});
|
||||
});
|
||||
|
||||
describe("#collections.group_memberships", () => {
|
||||
it("should return groups in private collection", async () => {
|
||||
const user = await buildUser();
|
||||
@@ -727,13 +686,13 @@ describe("#collections.group_memberships", () => {
|
||||
createdById: user.id,
|
||||
collectionId: collection.id,
|
||||
userId: user.id,
|
||||
permission: "read_write",
|
||||
permission: CollectionPermission.ReadWrite,
|
||||
});
|
||||
await CollectionGroup.create({
|
||||
createdById: user.id,
|
||||
collectionId: collection.id,
|
||||
groupId: group.id,
|
||||
permission: "read_write",
|
||||
permission: CollectionPermission.ReadWrite,
|
||||
});
|
||||
const res = await server.post("/api/collections.group_memberships", {
|
||||
body: {
|
||||
@@ -747,7 +706,7 @@ describe("#collections.group_memberships", () => {
|
||||
expect(body.data.groups[0].id).toEqual(group.id);
|
||||
expect(body.data.collectionGroupMemberships.length).toEqual(1);
|
||||
expect(body.data.collectionGroupMemberships[0].permission).toEqual(
|
||||
"read_write"
|
||||
CollectionPermission.ReadWrite
|
||||
);
|
||||
});
|
||||
|
||||
@@ -769,19 +728,19 @@ describe("#collections.group_memberships", () => {
|
||||
createdById: user.id,
|
||||
collectionId: collection.id,
|
||||
userId: user.id,
|
||||
permission: "read_write",
|
||||
permission: CollectionPermission.ReadWrite,
|
||||
});
|
||||
await CollectionGroup.create({
|
||||
createdById: user.id,
|
||||
collectionId: collection.id,
|
||||
groupId: group.id,
|
||||
permission: "read_write",
|
||||
permission: CollectionPermission.ReadWrite,
|
||||
});
|
||||
await CollectionGroup.create({
|
||||
createdById: user.id,
|
||||
collectionId: collection.id,
|
||||
groupId: group2.id,
|
||||
permission: "read_write",
|
||||
permission: CollectionPermission.ReadWrite,
|
||||
});
|
||||
const res = await server.post("/api/collections.group_memberships", {
|
||||
body: {
|
||||
@@ -812,25 +771,25 @@ describe("#collections.group_memberships", () => {
|
||||
createdById: user.id,
|
||||
collectionId: collection.id,
|
||||
userId: user.id,
|
||||
permission: "read_write",
|
||||
permission: CollectionPermission.ReadWrite,
|
||||
});
|
||||
await CollectionGroup.create({
|
||||
createdById: user.id,
|
||||
collectionId: collection.id,
|
||||
groupId: group.id,
|
||||
permission: "read_write",
|
||||
permission: CollectionPermission.ReadWrite,
|
||||
});
|
||||
await CollectionGroup.create({
|
||||
createdById: user.id,
|
||||
collectionId: collection.id,
|
||||
groupId: group2.id,
|
||||
permission: "maintainer",
|
||||
permission: CollectionPermission.Read,
|
||||
});
|
||||
const res = await server.post("/api/collections.group_memberships", {
|
||||
body: {
|
||||
token: user.getJwtToken(),
|
||||
id: collection.id,
|
||||
permission: "maintainer",
|
||||
permission: CollectionPermission.Read,
|
||||
},
|
||||
});
|
||||
const body = await res.json();
|
||||
@@ -871,7 +830,7 @@ describe("#collections.memberships", () => {
|
||||
createdById: user.id,
|
||||
collectionId: collection.id,
|
||||
userId: user.id,
|
||||
permission: "read_write",
|
||||
permission: CollectionPermission.ReadWrite,
|
||||
});
|
||||
const res = await server.post("/api/collections.memberships", {
|
||||
body: {
|
||||
@@ -884,7 +843,9 @@ describe("#collections.memberships", () => {
|
||||
expect(body.data.users.length).toEqual(1);
|
||||
expect(body.data.users[0].id).toEqual(user.id);
|
||||
expect(body.data.memberships.length).toEqual(1);
|
||||
expect(body.data.memberships[0].permission).toEqual("read_write");
|
||||
expect(body.data.memberships[0].permission).toEqual(
|
||||
CollectionPermission.ReadWrite
|
||||
);
|
||||
});
|
||||
|
||||
it("should allow filtering members in collection by name", async () => {
|
||||
@@ -896,13 +857,13 @@ describe("#collections.memberships", () => {
|
||||
createdById: user.id,
|
||||
collectionId: collection.id,
|
||||
userId: user.id,
|
||||
permission: "read_write",
|
||||
permission: CollectionPermission.ReadWrite,
|
||||
});
|
||||
await CollectionUser.create({
|
||||
createdById: user2.id,
|
||||
collectionId: collection.id,
|
||||
userId: user2.id,
|
||||
permission: "read_write",
|
||||
permission: CollectionPermission.ReadWrite,
|
||||
});
|
||||
const res = await server.post("/api/collections.memberships", {
|
||||
body: {
|
||||
@@ -924,19 +885,19 @@ describe("#collections.memberships", () => {
|
||||
createdById: user.id,
|
||||
collectionId: collection.id,
|
||||
userId: user.id,
|
||||
permission: "read_write",
|
||||
permission: CollectionPermission.ReadWrite,
|
||||
});
|
||||
await CollectionUser.create({
|
||||
createdById: user2.id,
|
||||
collectionId: collection.id,
|
||||
userId: user2.id,
|
||||
permission: "maintainer",
|
||||
permission: CollectionPermission.Read,
|
||||
});
|
||||
const res = await server.post("/api/collections.memberships", {
|
||||
body: {
|
||||
token: user.getJwtToken(),
|
||||
id: collection.id,
|
||||
permission: "maintainer",
|
||||
permission: CollectionPermission.Read,
|
||||
},
|
||||
});
|
||||
const body = await res.json();
|
||||
@@ -1000,7 +961,7 @@ describe("#collections.info", () => {
|
||||
collectionId: collection.id,
|
||||
userId: user.id,
|
||||
createdById: user.id,
|
||||
permission: "read",
|
||||
permission: CollectionPermission.Read,
|
||||
});
|
||||
const res = await server.post("/api/collections.info", {
|
||||
body: {
|
||||
@@ -1282,20 +1243,20 @@ describe("#collections.update", () => {
|
||||
collectionId: collection.id,
|
||||
userId: user.id,
|
||||
createdById: user.id,
|
||||
permission: "read_write",
|
||||
permission: CollectionPermission.ReadWrite,
|
||||
});
|
||||
const res = await server.post("/api/collections.update", {
|
||||
body: {
|
||||
token: user.getJwtToken(),
|
||||
id: collection.id,
|
||||
permission: "read_write",
|
||||
permission: CollectionPermission.ReadWrite,
|
||||
name: "Test",
|
||||
},
|
||||
});
|
||||
const body = await res.json();
|
||||
expect(res.status).toEqual(200);
|
||||
expect(body.data.name).toBe("Test");
|
||||
expect(body.data.permission).toBe("read_write");
|
||||
expect(body.data.permission).toBe(CollectionPermission.ReadWrite);
|
||||
// ensure we return with a write level policy
|
||||
expect(body.policies.length).toBe(1);
|
||||
expect(body.policies[0].abilities.update).toBe(true);
|
||||
@@ -1309,7 +1270,7 @@ describe("#collections.update", () => {
|
||||
collectionId: collection.id,
|
||||
userId: user.id,
|
||||
createdById: user.id,
|
||||
permission: "read_write",
|
||||
permission: CollectionPermission.ReadWrite,
|
||||
});
|
||||
const res = await server.post("/api/collections.update", {
|
||||
body: {
|
||||
@@ -1340,7 +1301,7 @@ describe("#collections.update", () => {
|
||||
});
|
||||
await collection.$add("group", group, {
|
||||
through: {
|
||||
permission: "read_write",
|
||||
permission: CollectionPermission.ReadWrite,
|
||||
createdById: user.id,
|
||||
},
|
||||
});
|
||||
@@ -1365,7 +1326,7 @@ describe("#collections.update", () => {
|
||||
collectionId: collection.id,
|
||||
userId: user.id,
|
||||
createdById: user.id,
|
||||
permission: "read",
|
||||
permission: CollectionPermission.Read,
|
||||
});
|
||||
const res = await server.post("/api/collections.update", {
|
||||
body: {
|
||||
@@ -1508,7 +1469,7 @@ describe("#collections.delete", () => {
|
||||
});
|
||||
await collection.$add("group", group, {
|
||||
through: {
|
||||
permission: "read_write",
|
||||
permission: CollectionPermission.ReadWrite,
|
||||
createdById: user.id,
|
||||
},
|
||||
});
|
||||
|
||||
@@ -3,6 +3,7 @@ import invariant from "invariant";
|
||||
import Router from "koa-router";
|
||||
import { Sequelize, Op, WhereOptions } from "sequelize";
|
||||
import { randomElement } from "@shared/random";
|
||||
import { CollectionPermission } from "@shared/types";
|
||||
import { colorPalette } from "@shared/utils/collections";
|
||||
import { RateLimiterStrategy } from "@server/RateLimiter";
|
||||
import collectionExporter from "@server/commands/collectionExporter";
|
||||
@@ -45,6 +46,7 @@ import {
|
||||
assertPresent,
|
||||
assertHexColor,
|
||||
assertIndexCharacters,
|
||||
assertCollectionPermission,
|
||||
} from "@server/validation";
|
||||
import pagination from "./middlewares/pagination";
|
||||
|
||||
@@ -199,9 +201,10 @@ router.post(
|
||||
);
|
||||
|
||||
router.post("collections.add_group", auth(), async (ctx) => {
|
||||
const { id, groupId, permission = "read_write" } = ctx.body;
|
||||
const { id, groupId, permission = CollectionPermission.ReadWrite } = ctx.body;
|
||||
assertUuid(id, "id is required");
|
||||
assertUuid(groupId, "groupId is required");
|
||||
assertCollectionPermission(permission);
|
||||
|
||||
const collection = await Collection.scope({
|
||||
method: ["withMembership", ctx.state.user.id],
|
||||
@@ -340,7 +343,7 @@ router.post(
|
||||
);
|
||||
|
||||
router.post("collections.add_user", auth(), async (ctx) => {
|
||||
const { id, userId, permission = "read_write" } = ctx.body;
|
||||
const { id, userId, permission } = ctx.body;
|
||||
assertUuid(id, "id is required");
|
||||
assertUuid(userId, "userId is required");
|
||||
|
||||
@@ -359,11 +362,15 @@ router.post("collections.add_user", auth(), async (ctx) => {
|
||||
},
|
||||
});
|
||||
|
||||
if (permission) {
|
||||
assertCollectionPermission(permission);
|
||||
}
|
||||
|
||||
if (!membership) {
|
||||
membership = await CollectionUser.create({
|
||||
collectionId: id,
|
||||
userId,
|
||||
permission,
|
||||
permission: permission || user.defaultCollectionPermission,
|
||||
createdById: ctx.state.user.id,
|
||||
});
|
||||
} else if (permission) {
|
||||
@@ -422,24 +429,6 @@ router.post("collections.remove_user", auth(), async (ctx) => {
|
||||
};
|
||||
});
|
||||
|
||||
// DEPRECATED: Use collection.memberships which has pagination, filtering and permissions
|
||||
router.post("collections.users", auth(), async (ctx) => {
|
||||
const { id } = ctx.body;
|
||||
assertUuid(id, "id is required");
|
||||
const { user } = ctx.state;
|
||||
|
||||
const collection = await Collection.scope({
|
||||
method: ["withMembership", user.id],
|
||||
}).findByPk(id);
|
||||
authorize(user, "read", collection);
|
||||
|
||||
const users = await collection.$get("users");
|
||||
|
||||
ctx.body = {
|
||||
data: users.map((user) => presentUser(user)),
|
||||
};
|
||||
});
|
||||
|
||||
router.post("collections.memberships", auth(), pagination(), async (ctx) => {
|
||||
const { id, query, permission } = ctx.body;
|
||||
assertUuid(id, "id is required");
|
||||
@@ -464,6 +453,7 @@ router.post("collections.memberships", auth(), pagination(), async (ctx) => {
|
||||
}
|
||||
|
||||
if (permission) {
|
||||
assertCollectionPermission(permission);
|
||||
where = { ...where, permission };
|
||||
}
|
||||
|
||||
@@ -575,16 +565,19 @@ router.post("collections.update", auth(), async (ctx) => {
|
||||
}).findByPk(id);
|
||||
authorize(user, "update", collection);
|
||||
|
||||
// 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 (permission !== "read_write" && collection.permission === "read_write") {
|
||||
// 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 (
|
||||
permission !== CollectionPermission.ReadWrite &&
|
||||
collection.permission === CollectionPermission.ReadWrite
|
||||
) {
|
||||
await CollectionUser.findOrCreate({
|
||||
where: {
|
||||
collectionId: collection.id,
|
||||
userId: user.id,
|
||||
},
|
||||
defaults: {
|
||||
permission: "read_write",
|
||||
permission: CollectionPermission.ReadWrite,
|
||||
createdById: user.id,
|
||||
},
|
||||
});
|
||||
@@ -610,12 +603,9 @@ router.post("collections.update", auth(), async (ctx) => {
|
||||
}
|
||||
|
||||
if (permission !== undefined) {
|
||||
// frontend sends empty string
|
||||
assertIn(
|
||||
permission,
|
||||
["read_write", "read", "", null],
|
||||
"Invalid permission"
|
||||
);
|
||||
if (permission) {
|
||||
assertCollectionPermission(permission);
|
||||
}
|
||||
privacyChanged = permission !== collection.permission;
|
||||
collection.permission = permission ? permission : null;
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { CollectionPermission } from "@shared/types";
|
||||
import {
|
||||
Document,
|
||||
View,
|
||||
@@ -800,7 +801,7 @@ describe("#documents.list", () => {
|
||||
createdById: user.id,
|
||||
collectionId: collection.id,
|
||||
userId: user.id,
|
||||
permission: "read",
|
||||
permission: CollectionPermission.Read,
|
||||
});
|
||||
const res = await server.post("/api/documents.list", {
|
||||
body: {
|
||||
@@ -1244,7 +1245,7 @@ describe("#documents.search", () => {
|
||||
createdById: user.id,
|
||||
collectionId: collection.id,
|
||||
userId: user.id,
|
||||
permission: "read",
|
||||
permission: CollectionPermission.Read,
|
||||
});
|
||||
const document = await buildDocument({
|
||||
title: "search term",
|
||||
@@ -2005,7 +2006,7 @@ describe("#documents.update", () => {
|
||||
createdById: user.id,
|
||||
collectionId: collection.id,
|
||||
userId: user.id,
|
||||
permission: "read_write",
|
||||
permission: CollectionPermission.ReadWrite,
|
||||
});
|
||||
const res = await server.post("/api/documents.update", {
|
||||
body: {
|
||||
@@ -2094,7 +2095,7 @@ describe("#documents.update", () => {
|
||||
collectionId: collection.id,
|
||||
userId: admin.id,
|
||||
createdById: admin.id,
|
||||
permission: "read_write",
|
||||
permission: CollectionPermission.ReadWrite,
|
||||
});
|
||||
const res = await server.post("/api/documents.update", {
|
||||
body: {
|
||||
@@ -2118,7 +2119,7 @@ describe("#documents.update", () => {
|
||||
collectionId: collection.id,
|
||||
userId: user.id,
|
||||
createdById: user.id,
|
||||
permission: "read",
|
||||
permission: CollectionPermission.Read,
|
||||
});
|
||||
const res = await server.post("/api/documents.update", {
|
||||
body: {
|
||||
@@ -2133,7 +2134,7 @@ describe("#documents.update", () => {
|
||||
|
||||
it("does not allow editing in read-only collection", async () => {
|
||||
const { user, document, collection } = await seed();
|
||||
collection.permission = "read";
|
||||
collection.permission = CollectionPermission.Read;
|
||||
await collection.save();
|
||||
const res = await server.post("/api/documents.update", {
|
||||
body: {
|
||||
|
||||
@@ -326,76 +326,71 @@ router.post("documents.viewed", auth(), pagination(), async (ctx) => {
|
||||
};
|
||||
});
|
||||
|
||||
router.post(
|
||||
"documents.drafts",
|
||||
auth({ member: true }),
|
||||
pagination(),
|
||||
async (ctx) => {
|
||||
let { direction } = ctx.body;
|
||||
const { collectionId, dateFilter, sort = "updatedAt" } = ctx.body;
|
||||
router.post("documents.drafts", auth(), pagination(), async (ctx) => {
|
||||
let { direction } = ctx.body;
|
||||
const { collectionId, dateFilter, sort = "updatedAt" } = ctx.body;
|
||||
|
||||
assertSort(sort, Document);
|
||||
if (direction !== "ASC") {
|
||||
direction = "DESC";
|
||||
}
|
||||
const { user } = ctx.state;
|
||||
|
||||
if (collectionId) {
|
||||
assertUuid(collectionId, "collectionId must be a UUID");
|
||||
const collection = await Collection.scope({
|
||||
method: ["withMembership", user.id],
|
||||
}).findByPk(collectionId);
|
||||
authorize(user, "read", collection);
|
||||
}
|
||||
|
||||
const collectionIds = collectionId
|
||||
? [collectionId]
|
||||
: await user.collectionIds();
|
||||
const where: WhereOptions<Document> = {
|
||||
createdById: user.id,
|
||||
collectionId: collectionIds,
|
||||
publishedAt: {
|
||||
[Op.is]: null,
|
||||
},
|
||||
};
|
||||
|
||||
if (dateFilter) {
|
||||
assertIn(
|
||||
dateFilter,
|
||||
["day", "week", "month", "year"],
|
||||
"dateFilter must be one of day,week,month,year"
|
||||
);
|
||||
where.updatedAt = {
|
||||
[Op.gte]: subtractDate(new Date(), dateFilter),
|
||||
};
|
||||
} else {
|
||||
delete where.updatedAt;
|
||||
}
|
||||
|
||||
const collectionScope: Readonly<ScopeOptions> = {
|
||||
method: ["withCollectionPermissions", user.id],
|
||||
};
|
||||
const documents = await Document.scope([
|
||||
"defaultScope",
|
||||
collectionScope,
|
||||
]).findAll({
|
||||
where,
|
||||
order: [[sort, direction]],
|
||||
offset: ctx.state.pagination.offset,
|
||||
limit: ctx.state.pagination.limit,
|
||||
});
|
||||
const data = await Promise.all(
|
||||
documents.map((document) => presentDocument(document))
|
||||
);
|
||||
const policies = presentPolicies(user, documents);
|
||||
|
||||
ctx.body = {
|
||||
pagination: ctx.state.pagination,
|
||||
data,
|
||||
policies,
|
||||
};
|
||||
assertSort(sort, Document);
|
||||
if (direction !== "ASC") {
|
||||
direction = "DESC";
|
||||
}
|
||||
);
|
||||
const { user } = ctx.state;
|
||||
|
||||
if (collectionId) {
|
||||
assertUuid(collectionId, "collectionId must be a UUID");
|
||||
const collection = await Collection.scope({
|
||||
method: ["withMembership", user.id],
|
||||
}).findByPk(collectionId);
|
||||
authorize(user, "read", collection);
|
||||
}
|
||||
|
||||
const collectionIds = collectionId
|
||||
? [collectionId]
|
||||
: await user.collectionIds();
|
||||
const where: WhereOptions<Document> = {
|
||||
createdById: user.id,
|
||||
collectionId: collectionIds,
|
||||
publishedAt: {
|
||||
[Op.is]: null,
|
||||
},
|
||||
};
|
||||
|
||||
if (dateFilter) {
|
||||
assertIn(
|
||||
dateFilter,
|
||||
["day", "week", "month", "year"],
|
||||
"dateFilter must be one of day,week,month,year"
|
||||
);
|
||||
where.updatedAt = {
|
||||
[Op.gte]: subtractDate(new Date(), dateFilter),
|
||||
};
|
||||
} else {
|
||||
delete where.updatedAt;
|
||||
}
|
||||
|
||||
const collectionScope: Readonly<ScopeOptions> = {
|
||||
method: ["withCollectionPermissions", user.id],
|
||||
};
|
||||
const documents = await Document.scope([
|
||||
"defaultScope",
|
||||
collectionScope,
|
||||
]).findAll({
|
||||
where,
|
||||
order: [[sort, direction]],
|
||||
offset: ctx.state.pagination.offset,
|
||||
limit: ctx.state.pagination.limit,
|
||||
});
|
||||
const data = await Promise.all(
|
||||
documents.map((document) => presentDocument(document))
|
||||
);
|
||||
const policies = presentPolicies(user, documents);
|
||||
|
||||
ctx.body = {
|
||||
pagination: ctx.state.pagination,
|
||||
data,
|
||||
policies,
|
||||
};
|
||||
});
|
||||
|
||||
router.post(
|
||||
"documents.info",
|
||||
@@ -777,7 +772,7 @@ router.post("documents.templatize", auth({ member: true }), async (ctx) => {
|
||||
};
|
||||
});
|
||||
|
||||
router.post("documents.update", auth({ member: true }), async (ctx) => {
|
||||
router.post("documents.update", auth(), async (ctx) => {
|
||||
const {
|
||||
id,
|
||||
title,
|
||||
@@ -837,7 +832,7 @@ router.post("documents.update", auth({ member: true }), async (ctx) => {
|
||||
};
|
||||
});
|
||||
|
||||
router.post("documents.move", auth({ member: true }), async (ctx) => {
|
||||
router.post("documents.move", auth(), async (ctx) => {
|
||||
const { id, collectionId, parentDocumentId, index } = ctx.body;
|
||||
assertUuid(id, "id must be a uuid");
|
||||
assertUuid(collectionId, "collectionId must be a uuid");
|
||||
@@ -903,7 +898,7 @@ router.post("documents.move", auth({ member: true }), async (ctx) => {
|
||||
};
|
||||
});
|
||||
|
||||
router.post("documents.archive", auth({ member: true }), async (ctx) => {
|
||||
router.post("documents.archive", auth(), async (ctx) => {
|
||||
const { id } = ctx.body;
|
||||
assertPresent(id, "id is required");
|
||||
const { user } = ctx.state;
|
||||
@@ -932,7 +927,7 @@ router.post("documents.archive", auth({ member: true }), async (ctx) => {
|
||||
};
|
||||
});
|
||||
|
||||
router.post("documents.delete", auth({ member: true }), async (ctx) => {
|
||||
router.post("documents.delete", auth(), async (ctx) => {
|
||||
const { id, permanent } = ctx.body;
|
||||
assertPresent(id, "id is required");
|
||||
const { user } = ctx.state;
|
||||
@@ -993,7 +988,7 @@ router.post("documents.delete", auth({ member: true }), async (ctx) => {
|
||||
};
|
||||
});
|
||||
|
||||
router.post("documents.unpublish", auth({ member: true }), async (ctx) => {
|
||||
router.post("documents.unpublish", auth(), async (ctx) => {
|
||||
const { id } = ctx.body;
|
||||
assertPresent(id, "id is required");
|
||||
const { user } = ctx.state;
|
||||
@@ -1027,7 +1022,7 @@ router.post("documents.unpublish", auth({ member: true }), async (ctx) => {
|
||||
};
|
||||
});
|
||||
|
||||
router.post("documents.import", auth({ member: true }), async (ctx) => {
|
||||
router.post("documents.import", auth(), async (ctx) => {
|
||||
const { publish, collectionId, parentDocumentId, index } = ctx.body;
|
||||
|
||||
if (!ctx.is("multipart/form-data")) {
|
||||
@@ -1052,7 +1047,6 @@ router.post("documents.import", auth({ member: true }), async (ctx) => {
|
||||
assertPositiveInteger(index, "index must be an integer (>=0)");
|
||||
}
|
||||
const { user } = ctx.state;
|
||||
authorize(user, "createDocument", user.team);
|
||||
|
||||
const collection = await Collection.scope({
|
||||
method: ["withMembership", user.id],
|
||||
@@ -1110,7 +1104,7 @@ router.post("documents.import", auth({ member: true }), async (ctx) => {
|
||||
});
|
||||
});
|
||||
|
||||
router.post("documents.create", auth({ member: true }), async (ctx) => {
|
||||
router.post("documents.create", auth(), async (ctx) => {
|
||||
const {
|
||||
title = "",
|
||||
text = "",
|
||||
@@ -1132,7 +1126,6 @@ router.post("documents.create", auth({ member: true }), async (ctx) => {
|
||||
assertPositiveInteger(index, "index must be an integer (>=0)");
|
||||
}
|
||||
const { user } = ctx.state;
|
||||
authorize(user, "createDocument", user.team);
|
||||
|
||||
const collection = await Collection.scope({
|
||||
method: ["withMembership", user.id],
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { CollectionPermission } from "@shared/types";
|
||||
import { CollectionUser } from "@server/models";
|
||||
import {
|
||||
buildUser,
|
||||
@@ -164,7 +165,7 @@ describe("#shares.create", () => {
|
||||
createdById: user.id,
|
||||
collectionId: collection.id,
|
||||
userId: user.id,
|
||||
permission: "read",
|
||||
permission: CollectionPermission.Read,
|
||||
});
|
||||
const res = await server.post("/api/shares.create", {
|
||||
body: {
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { CollectionPermission } from "@shared/types";
|
||||
import { View, CollectionUser } from "@server/models";
|
||||
import { buildUser } from "@server/test/factories";
|
||||
import { seed, getTestDatabase, getTestServer } from "@server/test/support";
|
||||
@@ -56,7 +57,7 @@ describe("#views.list", () => {
|
||||
createdById: user.id,
|
||||
collectionId: collection.id,
|
||||
userId: user.id,
|
||||
permission: "read",
|
||||
permission: CollectionPermission.Read,
|
||||
});
|
||||
await View.incrementOrCreate({
|
||||
documentId: document.id,
|
||||
@@ -121,7 +122,7 @@ describe("#views.create", () => {
|
||||
createdById: user.id,
|
||||
collectionId: collection.id,
|
||||
userId: user.id,
|
||||
permission: "read",
|
||||
permission: CollectionPermission.Read,
|
||||
});
|
||||
const res = await server.post("/api/views.create", {
|
||||
body: {
|
||||
|
||||
Reference in New Issue
Block a user