Individual document sharing with permissions (#5814)

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: Tom Moor <tom@getoutline.com>
This commit is contained in:
Apoorv Mishra
2024-01-31 07:18:22 +05:30
committed by GitHub
parent 717c9b5d64
commit 1490c3a14b
91 changed files with 4004 additions and 1166 deletions

View File

@@ -156,7 +156,10 @@ export default async function documentCreator({
// reload to get all of the data needed to present (user, collection etc)
// we need to specify publishedAt to bypass default scope that only returns
// published documents
return await Document.findOne({
return await Document.scope([
"withDrafts",
{ method: ["withMembership", user.id] },
]).findOne({
where: {
id: document.id,
publishedAt: document.publishedAt,

View File

@@ -2,7 +2,14 @@ import invariant from "invariant";
import { Transaction } from "sequelize";
import { ValidationError } from "@server/errors";
import { traceFunction } from "@server/logging/tracing";
import { User, Document, Collection, Pin, Event } from "@server/models";
import {
User,
Document,
Collection,
Pin,
Event,
UserMembership,
} from "@server/models";
import pinDestroyer from "./pinDestroyer";
type Props = {
@@ -224,6 +231,24 @@ async function documentMover({
await document.save({ transaction });
result.documents.push(document);
// If there are any sourced permissions for this document, we need to go to the source
// permission and recalculate
const [documentPermissions, parentDocumentPermissions] = await Promise.all([
UserMembership.findRootMembershipsForDocument(document.id, undefined, {
transaction,
}),
parentDocumentId
? UserMembership.findRootMembershipsForDocument(
parentDocumentId,
undefined,
{ transaction }
)
: [],
]);
await recalculatePermissions(documentPermissions, transaction);
await recalculatePermissions(parentDocumentPermissions, transaction);
await Event.create(
{
name: "documents.move",
@@ -247,6 +272,15 @@ async function documentMover({
return result;
}
async function recalculatePermissions(
permissions: UserMembership[],
transaction?: Transaction
) {
for (const permission of permissions) {
await UserMembership.createSourcedMemberships(permission, { transaction });
}
}
export default traceFunction({
spanName: "documentMover",
})(documentMover);

View File

@@ -1,5 +1,5 @@
import { CollectionPermission, UserRole } from "@shared/types";
import { UserPermission } from "@server/models";
import { UserMembership } from "@server/models";
import { buildUser, buildAdmin, buildCollection } from "@server/test/factories";
import userDemoter from "./userDemoter";
@@ -11,7 +11,7 @@ describe("userDemoter", () => {
const user = await buildUser({ teamId: admin.teamId });
const collection = await buildCollection({ teamId: admin.teamId });
const membership = await UserPermission.create({
const membership = await UserMembership.create({
createdById: admin.id,
userId: user.id,
collectionId: collection.id,