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:
@@ -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],
|
||||
|
||||
Reference in New Issue
Block a user