mirror of
https://github.com/outline/outline.git
synced 2025-12-20 01:59:56 -06:00
chore: Rename GroupPermission -> GroupMembership (#7214)
* GroupPermission -> GroupMembership * Add group membership source * wip
This commit is contained in:
@@ -41,6 +41,8 @@ const WEBHOOK_EVENTS = {
|
||||
"documents.title_change",
|
||||
"documents.add_user",
|
||||
"documents.remove_user",
|
||||
"documents.add_group",
|
||||
"documents.remove_group",
|
||||
],
|
||||
collections: [
|
||||
"collections.create",
|
||||
|
||||
@@ -20,7 +20,7 @@ import {
|
||||
View,
|
||||
Share,
|
||||
UserMembership,
|
||||
GroupPermission,
|
||||
GroupMembership,
|
||||
GroupUser,
|
||||
Comment,
|
||||
} from "@server/models";
|
||||
@@ -42,6 +42,7 @@ import {
|
||||
presentCollectionGroupMembership,
|
||||
presentComment,
|
||||
} from "@server/presenters";
|
||||
import presentDocumentGroupMembership from "@server/presenters/documentGroupMembership";
|
||||
import BaseTask from "@server/queues/tasks/BaseTask";
|
||||
import {
|
||||
CollectionEvent,
|
||||
@@ -50,6 +51,7 @@ import {
|
||||
CommentEvent,
|
||||
DocumentEvent,
|
||||
DocumentUserEvent,
|
||||
DocumentGroupEvent,
|
||||
Event,
|
||||
FileOperationEvent,
|
||||
GroupEvent,
|
||||
@@ -138,6 +140,10 @@ export default class DeliverWebhookTask extends BaseTask<Props> {
|
||||
case "documents.remove_user":
|
||||
await this.handleDocumentUserEvent(subscription, event);
|
||||
return;
|
||||
case "documents.add_group":
|
||||
case "documents.remove_group":
|
||||
await this.handleDocumentGroupEvent(subscription, event);
|
||||
return;
|
||||
case "documents.update.delayed":
|
||||
case "documents.update.debounced":
|
||||
// Ignored
|
||||
@@ -478,7 +484,7 @@ export default class DeliverWebhookTask extends BaseTask<Props> {
|
||||
subscription: WebhookSubscription,
|
||||
event: CollectionGroupEvent
|
||||
): Promise<void> {
|
||||
const model = await GroupPermission.scope([
|
||||
const model = await GroupMembership.scope([
|
||||
"withGroup",
|
||||
"withCollection",
|
||||
]).findOne({
|
||||
@@ -581,6 +587,36 @@ export default class DeliverWebhookTask extends BaseTask<Props> {
|
||||
});
|
||||
}
|
||||
|
||||
private async handleDocumentGroupEvent(
|
||||
subscription: WebhookSubscription,
|
||||
event: DocumentGroupEvent
|
||||
): Promise<void> {
|
||||
const model = await GroupMembership.scope([
|
||||
"withGroup",
|
||||
"withDocument",
|
||||
]).findOne({
|
||||
where: {
|
||||
documentId: event.documentId,
|
||||
groupId: event.modelId,
|
||||
},
|
||||
paranoid: false,
|
||||
});
|
||||
|
||||
const document =
|
||||
model && (await presentDocument(undefined, model.document!));
|
||||
|
||||
await this.sendWebhook({
|
||||
event,
|
||||
subscription,
|
||||
payload: {
|
||||
id: event.modelId,
|
||||
model: model && presentDocumentGroupMembership(model),
|
||||
document,
|
||||
group: model && presentGroup(model.group),
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
private async handleRevisionEvent(
|
||||
subscription: WebhookSubscription,
|
||||
event: RevisionEvent
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
"use strict";
|
||||
|
||||
module.exports = {
|
||||
async up(queryInterface, Sequelize) {
|
||||
await queryInterface.addColumn("group_permissions", "sourceId", {
|
||||
type: Sequelize.UUID,
|
||||
onDelete: "cascade",
|
||||
references: {
|
||||
model: "group_permissions",
|
||||
},
|
||||
allowNull: true,
|
||||
});
|
||||
|
||||
await queryInterface.removeConstraint("group_permissions", "group_permissions_documentId_fkey")
|
||||
await queryInterface.changeColumn("group_permissions", "documentId", {
|
||||
type: Sequelize.UUID,
|
||||
onDelete: "cascade",
|
||||
references: {
|
||||
model: "documents",
|
||||
},
|
||||
});
|
||||
},
|
||||
async down(queryInterface) {
|
||||
await queryInterface.removeConstraint("group_permissions", "group_permissions_documentId_fkey")
|
||||
await queryInterface.changeColumn("group_permissions", "documentId", {
|
||||
type: Sequelize.UUID,
|
||||
references: {
|
||||
model: "documents",
|
||||
},
|
||||
});
|
||||
await queryInterface.removeColumn("group_permissions", "sourceId");
|
||||
},
|
||||
};
|
||||
@@ -42,7 +42,7 @@ import { ValidationError } from "@server/errors";
|
||||
import Document from "./Document";
|
||||
import FileOperation from "./FileOperation";
|
||||
import Group from "./Group";
|
||||
import GroupPermission from "./GroupPermission";
|
||||
import GroupMembership from "./GroupMembership";
|
||||
import GroupUser from "./GroupUser";
|
||||
import Team from "./Team";
|
||||
import User from "./User";
|
||||
@@ -63,7 +63,7 @@ import NotContainsUrl from "./validators/NotContainsUrl";
|
||||
required: false,
|
||||
},
|
||||
{
|
||||
model: GroupPermission,
|
||||
model: GroupMembership,
|
||||
as: "collectionGroupMemberships",
|
||||
required: false,
|
||||
// use of "separate" property: sequelize breaks when there are
|
||||
@@ -110,7 +110,7 @@ import NotContainsUrl from "./validators/NotContainsUrl";
|
||||
required: false,
|
||||
},
|
||||
{
|
||||
model: GroupPermission,
|
||||
model: GroupMembership,
|
||||
as: "collectionGroupMemberships",
|
||||
required: false,
|
||||
// use of "separate" property: sequelize breaks when there are
|
||||
@@ -322,13 +322,13 @@ class Collection extends ParanoidModel<
|
||||
@HasMany(() => UserMembership, "collectionId")
|
||||
memberships: UserMembership[];
|
||||
|
||||
@HasMany(() => GroupPermission, "collectionId")
|
||||
collectionGroupMemberships: GroupPermission[];
|
||||
@HasMany(() => GroupMembership, "collectionId")
|
||||
collectionGroupMemberships: GroupMembership[];
|
||||
|
||||
@BelongsToMany(() => User, () => UserMembership)
|
||||
users: User[];
|
||||
|
||||
@BelongsToMany(() => Group, () => GroupPermission)
|
||||
@BelongsToMany(() => Group, () => GroupMembership)
|
||||
groups: Group[];
|
||||
|
||||
@BelongsTo(() => User, "createdById")
|
||||
|
||||
@@ -11,7 +11,7 @@ import {
|
||||
DataType,
|
||||
Scopes,
|
||||
} from "sequelize-typescript";
|
||||
import GroupPermission from "./GroupPermission";
|
||||
import GroupMembership from "./GroupMembership";
|
||||
import GroupUser from "./GroupUser";
|
||||
import Team from "./Team";
|
||||
import User from "./User";
|
||||
@@ -90,7 +90,7 @@ class Group extends ParanoidModel<
|
||||
groupId: model.id,
|
||||
},
|
||||
});
|
||||
await GroupPermission.destroy({
|
||||
await GroupMembership.destroy({
|
||||
where: {
|
||||
groupId: model.id,
|
||||
},
|
||||
@@ -109,8 +109,8 @@ class Group extends ParanoidModel<
|
||||
@HasMany(() => GroupUser, { as: "members", foreignKey: "groupId" })
|
||||
groupUsers: GroupUser[];
|
||||
|
||||
@HasMany(() => GroupPermission, "groupId")
|
||||
collectionGroupMemberships: GroupPermission[];
|
||||
@HasMany(() => GroupMembership, "groupId")
|
||||
collectionGroupMemberships: GroupMembership[];
|
||||
|
||||
@BelongsTo(() => Team, "teamId")
|
||||
team: Team;
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
import { buildCollection, buildGroup, buildUser } from "@server/test/factories";
|
||||
import GroupPermission from "./GroupPermission";
|
||||
import GroupMembership from "./GroupMembership";
|
||||
|
||||
describe("GroupPermission", () => {
|
||||
describe("GroupMembership", () => {
|
||||
describe("withCollection scope", () => {
|
||||
it("should return the collection", async () => {
|
||||
const collection = await buildCollection();
|
||||
const group = await buildGroup();
|
||||
const user = await buildUser({ teamId: group.teamId });
|
||||
|
||||
await GroupPermission.create({
|
||||
await GroupMembership.create({
|
||||
createdById: user.id,
|
||||
groupId: group.id,
|
||||
collectionId: collection.id,
|
||||
});
|
||||
|
||||
const permission = await GroupPermission.scope("withCollection").findOne({
|
||||
const permission = await GroupMembership.scope("withCollection").findOne({
|
||||
where: {
|
||||
groupId: group.id,
|
||||
collectionId: collection.id,
|
||||
251
server/models/GroupMembership.ts
Normal file
251
server/models/GroupMembership.ts
Normal file
@@ -0,0 +1,251 @@
|
||||
import {
|
||||
InferAttributes,
|
||||
InferCreationAttributes,
|
||||
Op,
|
||||
type SaveOptions,
|
||||
type FindOptions,
|
||||
} from "sequelize";
|
||||
import {
|
||||
BelongsTo,
|
||||
Column,
|
||||
Default,
|
||||
ForeignKey,
|
||||
IsIn,
|
||||
Table,
|
||||
DataType,
|
||||
Scopes,
|
||||
AfterCreate,
|
||||
AfterUpdate,
|
||||
} from "sequelize-typescript";
|
||||
import { CollectionPermission, DocumentPermission } from "@shared/types";
|
||||
import Collection from "./Collection";
|
||||
import Document from "./Document";
|
||||
import Group from "./Group";
|
||||
import User from "./User";
|
||||
import ParanoidModel from "./base/ParanoidModel";
|
||||
import Fix from "./decorators/Fix";
|
||||
|
||||
/**
|
||||
* Represents a group's permission to access a collection or document.
|
||||
*/
|
||||
@Scopes(() => ({
|
||||
withGroup: {
|
||||
include: [
|
||||
{
|
||||
association: "group",
|
||||
},
|
||||
],
|
||||
},
|
||||
withCollection: {
|
||||
where: {
|
||||
collectionId: {
|
||||
[Op.ne]: null,
|
||||
},
|
||||
},
|
||||
include: [
|
||||
{
|
||||
association: "collection",
|
||||
},
|
||||
],
|
||||
},
|
||||
withDocument: {
|
||||
where: {
|
||||
documentId: {
|
||||
[Op.ne]: null,
|
||||
},
|
||||
},
|
||||
include: [
|
||||
{
|
||||
association: "document",
|
||||
},
|
||||
],
|
||||
},
|
||||
}))
|
||||
@Table({ tableName: "group_permissions", modelName: "group_permission" })
|
||||
@Fix
|
||||
class GroupMembership extends ParanoidModel<
|
||||
InferAttributes<GroupMembership>,
|
||||
Partial<InferCreationAttributes<GroupMembership>>
|
||||
> {
|
||||
@Default(CollectionPermission.ReadWrite)
|
||||
@IsIn([Object.values(CollectionPermission)])
|
||||
@Column(DataType.STRING)
|
||||
permission: CollectionPermission | DocumentPermission;
|
||||
|
||||
// associations
|
||||
|
||||
/** The collection that this permission grants the group access to. */
|
||||
@BelongsTo(() => Collection, "collectionId")
|
||||
collection?: Collection | null;
|
||||
|
||||
/** The collection ID that this permission grants the group access to. */
|
||||
@ForeignKey(() => Collection)
|
||||
@Column(DataType.UUID)
|
||||
collectionId?: string | null;
|
||||
|
||||
/** The document that this permission grants the group access to. */
|
||||
@BelongsTo(() => Document, "documentId")
|
||||
document?: Document | null;
|
||||
|
||||
/** The document ID that this permission grants the group access to. */
|
||||
@ForeignKey(() => Document)
|
||||
@Column(DataType.UUID)
|
||||
documentId?: string | null;
|
||||
|
||||
/** If this represents the permission on a child then this points to the permission on the root */
|
||||
@BelongsTo(() => GroupMembership, "sourceId")
|
||||
source?: GroupMembership | null;
|
||||
|
||||
/** If this represents the permission on a child then this points to the permission on the root */
|
||||
@ForeignKey(() => GroupMembership)
|
||||
@Column(DataType.UUID)
|
||||
sourceId?: string | null;
|
||||
|
||||
/** The group that this permission is granted to. */
|
||||
@BelongsTo(() => Group, "groupId")
|
||||
group: Group;
|
||||
|
||||
/** The group ID that this permission is granted to. */
|
||||
@ForeignKey(() => Group)
|
||||
@Column(DataType.UUID)
|
||||
groupId: string;
|
||||
|
||||
/** The user that created this permission. */
|
||||
@BelongsTo(() => User, "createdById")
|
||||
createdBy: User;
|
||||
|
||||
/** The user ID that created this permission. */
|
||||
@ForeignKey(() => User)
|
||||
@Column(DataType.UUID)
|
||||
createdById: string;
|
||||
|
||||
/**
|
||||
* Find the root membership for a document and (optionally) group.
|
||||
*
|
||||
* @param documentId The document ID to find the membership for.
|
||||
* @param groupId The group ID to find the membership for.
|
||||
* @param options Additional options to pass to the query.
|
||||
* @returns A promise that resolves to the root memberships for the document and group, or null.
|
||||
*/
|
||||
static async findRootMembershipsForDocument(
|
||||
documentId: string,
|
||||
groupId?: string,
|
||||
options?: FindOptions<GroupMembership>
|
||||
): Promise<GroupMembership[]> {
|
||||
const memberships = await this.findAll({
|
||||
where: {
|
||||
documentId,
|
||||
...(groupId ? { groupId } : {}),
|
||||
},
|
||||
});
|
||||
|
||||
const rootMemberships = await Promise.all(
|
||||
memberships.map((membership) =>
|
||||
membership?.sourceId
|
||||
? this.findByPk(membership.sourceId, options)
|
||||
: membership
|
||||
)
|
||||
);
|
||||
|
||||
return rootMemberships.filter(Boolean) as GroupMembership[];
|
||||
}
|
||||
|
||||
@AfterUpdate
|
||||
static async updateSourcedMemberships(
|
||||
model: GroupMembership,
|
||||
options: SaveOptions<GroupMembership>
|
||||
) {
|
||||
if (model.sourceId || !model.documentId) {
|
||||
return;
|
||||
}
|
||||
|
||||
const { transaction } = options;
|
||||
|
||||
if (model.changed("permission")) {
|
||||
await this.update(
|
||||
{
|
||||
permission: model.permission,
|
||||
},
|
||||
{
|
||||
where: {
|
||||
sourceId: model.id,
|
||||
},
|
||||
transaction,
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@AfterCreate
|
||||
static async createSourcedMemberships(
|
||||
model: GroupMembership,
|
||||
options: SaveOptions<GroupMembership>
|
||||
) {
|
||||
if (model.sourceId || !model.documentId) {
|
||||
return;
|
||||
}
|
||||
|
||||
return this.recreateSourcedMemberships(model, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Recreate all sourced permissions for a given permission.
|
||||
*/
|
||||
static async recreateSourcedMemberships(
|
||||
model: GroupMembership,
|
||||
options: SaveOptions<GroupMembership>
|
||||
) {
|
||||
if (!model.documentId) {
|
||||
return;
|
||||
}
|
||||
const { transaction } = options;
|
||||
|
||||
await this.destroy({
|
||||
where: {
|
||||
sourceId: model.id,
|
||||
},
|
||||
transaction,
|
||||
});
|
||||
|
||||
const document = await Document.unscoped().findOne({
|
||||
attributes: ["id"],
|
||||
where: {
|
||||
id: model.documentId,
|
||||
},
|
||||
transaction,
|
||||
});
|
||||
if (!document) {
|
||||
return;
|
||||
}
|
||||
|
||||
const childDocumentIds = await document.findAllChildDocumentIds(
|
||||
{
|
||||
publishedAt: {
|
||||
[Op.ne]: null,
|
||||
},
|
||||
},
|
||||
{
|
||||
transaction,
|
||||
}
|
||||
);
|
||||
|
||||
for (const childDocumentId of childDocumentIds) {
|
||||
await this.create(
|
||||
{
|
||||
documentId: childDocumentId,
|
||||
groupId: model.groupId,
|
||||
permission: model.permission,
|
||||
sourceId: model.id,
|
||||
createdById: model.createdById,
|
||||
createdAt: model.createdAt,
|
||||
updatedAt: model.updatedAt,
|
||||
},
|
||||
{
|
||||
transaction,
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default GroupMembership;
|
||||
@@ -1,83 +0,0 @@
|
||||
import { InferAttributes, InferCreationAttributes, Op } from "sequelize";
|
||||
import {
|
||||
BelongsTo,
|
||||
Column,
|
||||
Default,
|
||||
ForeignKey,
|
||||
IsIn,
|
||||
Table,
|
||||
DataType,
|
||||
Scopes,
|
||||
} from "sequelize-typescript";
|
||||
import { CollectionPermission } from "@shared/types";
|
||||
import Collection from "./Collection";
|
||||
import Document from "./Document";
|
||||
import Group from "./Group";
|
||||
import User from "./User";
|
||||
import ParanoidModel from "./base/ParanoidModel";
|
||||
import Fix from "./decorators/Fix";
|
||||
|
||||
@Scopes(() => ({
|
||||
withGroup: {
|
||||
include: [
|
||||
{
|
||||
association: "group",
|
||||
},
|
||||
],
|
||||
},
|
||||
withCollection: {
|
||||
where: {
|
||||
collectionId: {
|
||||
[Op.ne]: null,
|
||||
},
|
||||
},
|
||||
include: [
|
||||
{
|
||||
association: "collection",
|
||||
},
|
||||
],
|
||||
},
|
||||
}))
|
||||
@Table({ tableName: "group_permissions", modelName: "group_permission" })
|
||||
@Fix
|
||||
class GroupPermission extends ParanoidModel<
|
||||
InferAttributes<GroupPermission>,
|
||||
Partial<InferCreationAttributes<GroupPermission>>
|
||||
> {
|
||||
@Default(CollectionPermission.ReadWrite)
|
||||
@IsIn([Object.values(CollectionPermission)])
|
||||
@Column(DataType.STRING)
|
||||
permission: CollectionPermission;
|
||||
|
||||
// associations
|
||||
|
||||
@BelongsTo(() => Collection, "collectionId")
|
||||
collection?: Collection | null;
|
||||
|
||||
@ForeignKey(() => Collection)
|
||||
@Column(DataType.UUID)
|
||||
collectionId?: string | null;
|
||||
|
||||
@BelongsTo(() => Document, "documentId")
|
||||
document?: Document | null;
|
||||
|
||||
@ForeignKey(() => Document)
|
||||
@Column(DataType.UUID)
|
||||
documentId?: string | null;
|
||||
|
||||
@BelongsTo(() => Group, "groupId")
|
||||
group: Group;
|
||||
|
||||
@ForeignKey(() => Group)
|
||||
@Column(DataType.UUID)
|
||||
groupId: string;
|
||||
|
||||
@BelongsTo(() => User, "createdById")
|
||||
createdBy: User;
|
||||
|
||||
@ForeignKey(() => User)
|
||||
@Column(DataType.UUID)
|
||||
createdById: string;
|
||||
}
|
||||
|
||||
export default GroupPermission;
|
||||
@@ -25,6 +25,9 @@ import User from "./User";
|
||||
import IdModel from "./base/IdModel";
|
||||
import Fix from "./decorators/Fix";
|
||||
|
||||
/**
|
||||
* Represents a users's permission to access a collection or document.
|
||||
*/
|
||||
@Scopes(() => ({
|
||||
withUser: {
|
||||
include: [
|
||||
@@ -69,6 +72,7 @@ class UserMembership extends IdModel<
|
||||
@Column(DataType.STRING)
|
||||
permission: CollectionPermission | DocumentPermission;
|
||||
|
||||
/** The visible sort order in "shared with me" */
|
||||
@AllowNull
|
||||
@Column
|
||||
index: string | null;
|
||||
|
||||
@@ -8,7 +8,7 @@ export { default as Backlink } from "./Backlink";
|
||||
|
||||
export { default as Collection } from "./Collection";
|
||||
|
||||
export { default as GroupPermission } from "./GroupPermission";
|
||||
export { default as GroupMembership } from "./GroupMembership";
|
||||
|
||||
export { default as UserMembership } from "./UserMembership";
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { CollectionPermission } from "@shared/types";
|
||||
import { GroupPermission } from "@server/models";
|
||||
import { GroupMembership } from "@server/models";
|
||||
|
||||
type Membership = {
|
||||
id: string;
|
||||
@@ -9,12 +9,12 @@ type Membership = {
|
||||
};
|
||||
|
||||
export default function presentCollectionGroupMembership(
|
||||
membership: GroupPermission
|
||||
membership: GroupMembership
|
||||
): Membership {
|
||||
return {
|
||||
id: membership.id,
|
||||
groupId: membership.groupId,
|
||||
collectionId: membership.collectionId,
|
||||
permission: membership.permission,
|
||||
permission: membership.permission as CollectionPermission,
|
||||
};
|
||||
}
|
||||
|
||||
20
server/presenters/documentGroupMembership.ts
Normal file
20
server/presenters/documentGroupMembership.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
import { DocumentPermission } from "@shared/types";
|
||||
import { GroupMembership } from "@server/models";
|
||||
|
||||
type Membership = {
|
||||
id: string;
|
||||
groupId: string;
|
||||
documentId?: string | null;
|
||||
permission: DocumentPermission;
|
||||
};
|
||||
|
||||
export default function presentDocumentGroupMembership(
|
||||
membership: GroupMembership
|
||||
): Membership {
|
||||
return {
|
||||
id: membership.id,
|
||||
groupId: membership.groupId,
|
||||
documentId: membership.documentId,
|
||||
permission: membership.permission as DocumentPermission,
|
||||
};
|
||||
}
|
||||
@@ -7,7 +7,7 @@ import {
|
||||
Collection,
|
||||
FileOperation,
|
||||
Group,
|
||||
GroupPermission,
|
||||
GroupMembership,
|
||||
GroupUser,
|
||||
Pin,
|
||||
Star,
|
||||
@@ -487,7 +487,7 @@ export default class WebsocketsProcessor {
|
||||
|
||||
case "groups.add_user": {
|
||||
// do an add user for every collection that the group is a part of
|
||||
const collectionGroupMemberships = await GroupPermission.scope(
|
||||
const collectionGroupMemberships = await GroupMembership.scope(
|
||||
"withCollection"
|
||||
).findAll({
|
||||
where: {
|
||||
@@ -522,7 +522,7 @@ export default class WebsocketsProcessor {
|
||||
}
|
||||
|
||||
case "groups.remove_user": {
|
||||
const collectionGroupMemberships = await GroupPermission.scope(
|
||||
const collectionGroupMemberships = await GroupMembership.scope(
|
||||
"withCollection"
|
||||
).findAll({
|
||||
where: {
|
||||
@@ -593,7 +593,7 @@ export default class WebsocketsProcessor {
|
||||
},
|
||||
},
|
||||
});
|
||||
const collectionGroupMemberships = await GroupPermission.scope(
|
||||
const collectionGroupMemberships = await GroupMembership.scope(
|
||||
"withCollection"
|
||||
).findAll({
|
||||
paranoid: false,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { CollectionPermission } from "@shared/types";
|
||||
import { Document, UserMembership, GroupPermission } from "@server/models";
|
||||
import { Document, UserMembership, GroupMembership } from "@server/models";
|
||||
import {
|
||||
buildUser,
|
||||
buildAdmin,
|
||||
@@ -809,7 +809,7 @@ describe("#collections.group_memberships", () => {
|
||||
userId: user.id,
|
||||
permission: CollectionPermission.ReadWrite,
|
||||
});
|
||||
await GroupPermission.create({
|
||||
await GroupMembership.create({
|
||||
createdById: user.id,
|
||||
collectionId: collection.id,
|
||||
groupId: group.id,
|
||||
@@ -853,13 +853,13 @@ describe("#collections.group_memberships", () => {
|
||||
userId: user.id,
|
||||
permission: CollectionPermission.ReadWrite,
|
||||
});
|
||||
await GroupPermission.create({
|
||||
await GroupMembership.create({
|
||||
createdById: user.id,
|
||||
collectionId: collection.id,
|
||||
groupId: group.id,
|
||||
permission: CollectionPermission.ReadWrite,
|
||||
});
|
||||
await GroupPermission.create({
|
||||
await GroupMembership.create({
|
||||
createdById: user.id,
|
||||
collectionId: collection.id,
|
||||
groupId: group2.id,
|
||||
@@ -896,13 +896,13 @@ describe("#collections.group_memberships", () => {
|
||||
userId: user.id,
|
||||
permission: CollectionPermission.ReadWrite,
|
||||
});
|
||||
await GroupPermission.create({
|
||||
await GroupMembership.create({
|
||||
createdById: user.id,
|
||||
collectionId: collection.id,
|
||||
groupId: group.id,
|
||||
permission: CollectionPermission.ReadWrite,
|
||||
});
|
||||
await GroupPermission.create({
|
||||
await GroupMembership.create({
|
||||
createdById: user.id,
|
||||
collectionId: collection.id,
|
||||
groupId: group2.id,
|
||||
|
||||
@@ -18,7 +18,7 @@ import validate from "@server/middlewares/validate";
|
||||
import {
|
||||
Collection,
|
||||
UserMembership,
|
||||
GroupPermission,
|
||||
GroupMembership,
|
||||
Team,
|
||||
Event,
|
||||
User,
|
||||
@@ -242,7 +242,7 @@ router.post(
|
||||
const group = await Group.findByPk(groupId);
|
||||
authorize(user, "read", group);
|
||||
|
||||
let membership = await GroupPermission.findOne({
|
||||
let membership = await GroupMembership.findOne({
|
||||
where: {
|
||||
collectionId: id,
|
||||
groupId,
|
||||
@@ -250,7 +250,7 @@ router.post(
|
||||
});
|
||||
|
||||
if (!membership) {
|
||||
membership = await GroupPermission.create({
|
||||
membership = await GroupMembership.create({
|
||||
collectionId: id,
|
||||
groupId,
|
||||
permission,
|
||||
@@ -343,7 +343,7 @@ router.post(
|
||||
}).findByPk(id);
|
||||
authorize(user, "read", collection);
|
||||
|
||||
let where: WhereOptions<GroupPermission> = {
|
||||
let where: WhereOptions<GroupMembership> = {
|
||||
collectionId: id,
|
||||
};
|
||||
let groupWhere;
|
||||
@@ -373,8 +373,8 @@ router.post(
|
||||
};
|
||||
|
||||
const [total, memberships] = await Promise.all([
|
||||
GroupPermission.count(options),
|
||||
GroupPermission.findAll({
|
||||
GroupMembership.count(options),
|
||||
GroupMembership.findAll({
|
||||
...options,
|
||||
order: [["createdAt", "DESC"]],
|
||||
offset: ctx.state.pagination.offset,
|
||||
|
||||
@@ -15,7 +15,7 @@ import {
|
||||
SearchQuery,
|
||||
Event,
|
||||
User,
|
||||
GroupPermission,
|
||||
GroupMembership,
|
||||
} from "@server/models";
|
||||
import { DocumentHelper } from "@server/models/helpers/DocumentHelper";
|
||||
import {
|
||||
@@ -4096,7 +4096,7 @@ describe("#documents.users", () => {
|
||||
permission: CollectionPermission.Read,
|
||||
createdById: user.id,
|
||||
}),
|
||||
GroupPermission.create({
|
||||
GroupMembership.create({
|
||||
collectionId: collection.id,
|
||||
groupId: group.id,
|
||||
permission: CollectionPermission.ReadWrite,
|
||||
|
||||
@@ -35,7 +35,7 @@ import type {
|
||||
View,
|
||||
Notification,
|
||||
Share,
|
||||
GroupPermission,
|
||||
GroupMembership,
|
||||
} from "./models";
|
||||
|
||||
export enum AuthenticationType {
|
||||
@@ -246,7 +246,7 @@ export type CollectionUserEvent = BaseEvent<UserMembership> & {
|
||||
};
|
||||
};
|
||||
|
||||
export type CollectionGroupEvent = BaseEvent<GroupPermission> & {
|
||||
export type CollectionGroupEvent = BaseEvent<GroupMembership> & {
|
||||
name: "collections.add_group" | "collections.remove_group";
|
||||
collectionId: string;
|
||||
modelId: string;
|
||||
@@ -265,6 +265,13 @@ export type DocumentUserEvent = BaseEvent<UserMembership> & {
|
||||
};
|
||||
};
|
||||
|
||||
export type DocumentGroupEvent = BaseEvent<GroupMembership> & {
|
||||
name: "documents.add_group" | "documents.remove_group";
|
||||
documentId: string;
|
||||
modelId: string;
|
||||
data: { name: string };
|
||||
};
|
||||
|
||||
export type CollectionEvent = BaseEvent<Collection> &
|
||||
(
|
||||
| {
|
||||
@@ -428,6 +435,7 @@ export type Event =
|
||||
| AuthenticationProviderEvent
|
||||
| DocumentEvent
|
||||
| DocumentUserEvent
|
||||
| DocumentGroupEvent
|
||||
| PinEvent
|
||||
| CommentEvent
|
||||
| StarEvent
|
||||
|
||||
@@ -46,6 +46,8 @@ export class EventHelper {
|
||||
"documents.restore",
|
||||
"documents.add_user",
|
||||
"documents.remove_user",
|
||||
"documents.add_group",
|
||||
"documents.remove_group",
|
||||
"groups.create",
|
||||
"groups.update",
|
||||
"groups.delete",
|
||||
|
||||
Reference in New Issue
Block a user