Allow creating published share record, closes #5902
This commit is contained in:
@@ -68,6 +68,14 @@ export const SharesCreateSchema = BaseSchema.extend({
|
||||
.refine((val) => isUUID(val) || SLUG_URL_REGEX.test(val), {
|
||||
message: "must be uuid or url slug",
|
||||
}),
|
||||
published: z.boolean().default(false),
|
||||
urlId: z
|
||||
.string()
|
||||
.regex(SHARE_URL_SLUG_REGEX, {
|
||||
message: "must contain only alphanumeric and dashes",
|
||||
})
|
||||
.optional(),
|
||||
includeChildDocuments: z.boolean().default(false),
|
||||
}),
|
||||
});
|
||||
|
||||
|
||||
@@ -226,7 +226,66 @@ describe("#shares.create", () => {
|
||||
expect(body.data.documentTitle).toBe(document.title);
|
||||
});
|
||||
|
||||
it("should allow creating a share record with read-only permissions but no publishing", async () => {
|
||||
it("should allow creating a published share record for document", async () => {
|
||||
const user = await buildUser();
|
||||
const document = await buildDocument({
|
||||
userId: user.id,
|
||||
teamId: user.teamId,
|
||||
});
|
||||
const res = await server.post("/api/shares.create", {
|
||||
body: {
|
||||
token: user.getJwtToken(),
|
||||
documentId: document.id,
|
||||
includeChildDocuments: true,
|
||||
published: true,
|
||||
urlId: "test",
|
||||
},
|
||||
});
|
||||
const body = await res.json();
|
||||
expect(res.status).toEqual(200);
|
||||
expect(body.data.published).toBe(true);
|
||||
expect(body.data.includeChildDocuments).toBe(true);
|
||||
expect(body.data.urlId).toBe("test");
|
||||
expect(body.data.documentTitle).toBe(document.title);
|
||||
});
|
||||
|
||||
it("should fail creating a share record with read-only permissions and publishing", async () => {
|
||||
const team = await buildTeam();
|
||||
const user = await buildUser({ teamId: team.id });
|
||||
const collection = await buildCollection({
|
||||
userId: user.id,
|
||||
teamId: team.id,
|
||||
});
|
||||
const document = await buildDocument({
|
||||
userId: user.id,
|
||||
collectionId: collection.id,
|
||||
teamId: team.id,
|
||||
});
|
||||
collection.permission = null;
|
||||
await collection.save();
|
||||
await UserPermission.update(
|
||||
{
|
||||
userId: user.id,
|
||||
permission: CollectionPermission.Read,
|
||||
},
|
||||
{
|
||||
where: {
|
||||
createdById: user.id,
|
||||
collectionId: collection.id,
|
||||
},
|
||||
}
|
||||
);
|
||||
const res = await server.post("/api/shares.create", {
|
||||
body: {
|
||||
token: user.getJwtToken(),
|
||||
documentId: document.id,
|
||||
published: true,
|
||||
},
|
||||
});
|
||||
expect(res.status).toEqual(403);
|
||||
});
|
||||
|
||||
it("should allow creating a share record with read-only permissions but not publishing", async () => {
|
||||
const team = await buildTeam();
|
||||
const user = await buildUser({ teamId: team.id });
|
||||
const collection = await buildCollection({
|
||||
|
||||
@@ -161,6 +161,69 @@ router.post(
|
||||
}
|
||||
);
|
||||
|
||||
router.post(
|
||||
"shares.create",
|
||||
auth(),
|
||||
validate(T.SharesCreateSchema),
|
||||
async (ctx: APIContext<T.SharesCreateReq>) => {
|
||||
const { documentId, published, urlId, includeChildDocuments } =
|
||||
ctx.input.body;
|
||||
const { user } = ctx.state.auth;
|
||||
const document = await Document.findByPk(documentId, {
|
||||
userId: user.id,
|
||||
});
|
||||
|
||||
// user could be creating the share link to share with team members
|
||||
authorize(user, "read", document);
|
||||
|
||||
if (published) {
|
||||
authorize(user, "share", user.team);
|
||||
authorize(user, "share", document);
|
||||
}
|
||||
|
||||
const [share, isCreated] = await Share.findOrCreate({
|
||||
where: {
|
||||
documentId,
|
||||
teamId: user.teamId,
|
||||
revokedAt: null,
|
||||
},
|
||||
defaults: {
|
||||
userId: user.id,
|
||||
published,
|
||||
includeChildDocuments,
|
||||
urlId,
|
||||
},
|
||||
});
|
||||
|
||||
if (isCreated) {
|
||||
await Event.create({
|
||||
name: "shares.create",
|
||||
documentId,
|
||||
collectionId: document.collectionId,
|
||||
modelId: share.id,
|
||||
teamId: user.teamId,
|
||||
actorId: user.id,
|
||||
data: {
|
||||
name: document.title,
|
||||
published,
|
||||
includeChildDocuments,
|
||||
urlId,
|
||||
},
|
||||
ip: ctx.request.ip,
|
||||
});
|
||||
}
|
||||
|
||||
share.team = user.team;
|
||||
share.user = user;
|
||||
share.document = document;
|
||||
|
||||
ctx.body = {
|
||||
data: presentShare(share),
|
||||
policies: presentPolicies(user, [share]),
|
||||
};
|
||||
}
|
||||
);
|
||||
|
||||
router.post(
|
||||
"shares.update",
|
||||
auth(),
|
||||
@@ -169,8 +232,7 @@ router.post(
|
||||
const { id, includeChildDocuments, published, urlId } = ctx.input.body;
|
||||
|
||||
const { user } = ctx.state.auth;
|
||||
const team = await Team.findByPk(user.teamId);
|
||||
authorize(user, "share", team);
|
||||
authorize(user, "share", user.team);
|
||||
|
||||
// fetch the share with document and collection.
|
||||
const share = await Share.scope({
|
||||
@@ -218,61 +280,6 @@ router.post(
|
||||
}
|
||||
);
|
||||
|
||||
router.post(
|
||||
"shares.create",
|
||||
auth(),
|
||||
validate(T.SharesCreateSchema),
|
||||
async (ctx: APIContext<T.SharesCreateReq>) => {
|
||||
const { documentId } = ctx.input.body;
|
||||
const { user } = ctx.state.auth;
|
||||
const document = await Document.findByPk(documentId, {
|
||||
userId: user.id,
|
||||
});
|
||||
|
||||
// user could be creating the share link to share with team members
|
||||
authorize(user, "read", document);
|
||||
|
||||
const team = await Team.findByPk(user.teamId);
|
||||
|
||||
const [share, isCreated] = await Share.findOrCreate({
|
||||
where: {
|
||||
documentId,
|
||||
teamId: user.teamId,
|
||||
revokedAt: null,
|
||||
},
|
||||
defaults: {
|
||||
userId: user.id,
|
||||
},
|
||||
});
|
||||
|
||||
if (isCreated) {
|
||||
await Event.create({
|
||||
name: "shares.create",
|
||||
documentId,
|
||||
collectionId: document.collectionId,
|
||||
modelId: share.id,
|
||||
teamId: user.teamId,
|
||||
actorId: user.id,
|
||||
data: {
|
||||
name: document.title,
|
||||
},
|
||||
ip: ctx.request.ip,
|
||||
});
|
||||
}
|
||||
|
||||
if (team) {
|
||||
share.team = team;
|
||||
}
|
||||
share.user = user;
|
||||
share.document = document;
|
||||
|
||||
ctx.body = {
|
||||
data: presentShare(share),
|
||||
policies: presentPolicies(user, [share]),
|
||||
};
|
||||
}
|
||||
);
|
||||
|
||||
router.post(
|
||||
"shares.revoke",
|
||||
auth(),
|
||||
|
||||
Reference in New Issue
Block a user