fix: Cleanup relationships when user is deleted (#6343)
* fix: Cleanup relationships when user is deleted * Update tests * Update User.test.ts
This commit is contained in:
@@ -1,7 +1,6 @@
|
||||
import { faker } from "@faker-js/faker";
|
||||
import { CollectionPermission } from "@shared/types";
|
||||
import { buildUser, buildTeam, buildCollection } from "@server/test/factories";
|
||||
import UserAuthentication from "./UserAuthentication";
|
||||
import UserPermission from "./UserPermission";
|
||||
|
||||
beforeAll(() => {
|
||||
@@ -36,23 +35,11 @@ describe("user model", () => {
|
||||
});
|
||||
|
||||
describe("destroy", () => {
|
||||
it("should delete user authentications", async () => {
|
||||
it("should clear PII", async () => {
|
||||
const user = await buildUser();
|
||||
expect(
|
||||
await UserAuthentication.count({
|
||||
where: {
|
||||
userId: user.id,
|
||||
},
|
||||
})
|
||||
).toBe(1);
|
||||
await user.destroy();
|
||||
expect(
|
||||
await UserAuthentication.count({
|
||||
where: {
|
||||
userId: user.id,
|
||||
},
|
||||
})
|
||||
).toBe(0);
|
||||
expect(user.email).toBe(null);
|
||||
expect(user.name).toBe("Unknown");
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -43,11 +43,9 @@ import env from "@server/env";
|
||||
import DeleteAttachmentTask from "@server/queues/tasks/DeleteAttachmentTask";
|
||||
import parseAttachmentIds from "@server/utils/parseAttachmentIds";
|
||||
import { ValidationError } from "../errors";
|
||||
import ApiKey from "./ApiKey";
|
||||
import Attachment from "./Attachment";
|
||||
import AuthenticationProvider from "./AuthenticationProvider";
|
||||
import Collection from "./Collection";
|
||||
import Star from "./Star";
|
||||
import Team from "./Team";
|
||||
import UserAuthentication from "./UserAuthentication";
|
||||
import UserPermission from "./UserPermission";
|
||||
@@ -586,24 +584,6 @@ class User extends ParanoidModel {
|
||||
model: User,
|
||||
options: { transaction: Transaction }
|
||||
) => {
|
||||
await ApiKey.destroy({
|
||||
where: {
|
||||
userId: model.id,
|
||||
},
|
||||
transaction: options.transaction,
|
||||
});
|
||||
await Star.destroy({
|
||||
where: {
|
||||
userId: model.id,
|
||||
},
|
||||
transaction: options.transaction,
|
||||
});
|
||||
await UserAuthentication.destroy({
|
||||
where: {
|
||||
userId: model.id,
|
||||
},
|
||||
transaction: options.transaction,
|
||||
});
|
||||
model.email = null;
|
||||
model.name = "Unknown";
|
||||
model.avatarUrl = null;
|
||||
|
||||
35
server/queues/processors/UserDeletedProcessor.test.ts
Normal file
35
server/queues/processors/UserDeletedProcessor.test.ts
Normal file
@@ -0,0 +1,35 @@
|
||||
import UserAuthentication from "@server/models/UserAuthentication";
|
||||
import { buildUser } from "@server/test/factories";
|
||||
import UserDeletedProcessor from "./UserDeletedProcessor";
|
||||
|
||||
const ip = "127.0.0.1";
|
||||
|
||||
describe("UserDeletedProcessor", () => {
|
||||
test("should remove relationships", async () => {
|
||||
const user = await buildUser();
|
||||
expect(
|
||||
await UserAuthentication.count({
|
||||
where: {
|
||||
userId: user.id,
|
||||
},
|
||||
})
|
||||
).toBe(1);
|
||||
|
||||
const processor = new UserDeletedProcessor();
|
||||
await processor.perform({
|
||||
name: "users.delete",
|
||||
userId: user.id,
|
||||
actorId: user.id,
|
||||
teamId: user.teamId,
|
||||
ip,
|
||||
});
|
||||
|
||||
expect(
|
||||
await UserAuthentication.count({
|
||||
where: {
|
||||
userId: user.id,
|
||||
},
|
||||
})
|
||||
).toBe(0);
|
||||
});
|
||||
});
|
||||
56
server/queues/processors/UserDeletedProcessor.ts
Normal file
56
server/queues/processors/UserDeletedProcessor.ts
Normal file
@@ -0,0 +1,56 @@
|
||||
import {
|
||||
ApiKey,
|
||||
GroupUser,
|
||||
Star,
|
||||
Subscription,
|
||||
UserAuthentication,
|
||||
UserPermission,
|
||||
} from "@server/models";
|
||||
import { sequelize } from "@server/storage/database";
|
||||
import { Event as TEvent, UserEvent } from "@server/types";
|
||||
import BaseProcessor from "./BaseProcessor";
|
||||
|
||||
export default class UsersDeletedProcessor extends BaseProcessor {
|
||||
static applicableEvents: TEvent["name"][] = ["users.delete"];
|
||||
|
||||
async perform(event: UserEvent) {
|
||||
await sequelize.transaction(async (transaction) => {
|
||||
await GroupUser.destroy({
|
||||
where: {
|
||||
userId: event.userId,
|
||||
},
|
||||
transaction,
|
||||
});
|
||||
await UserAuthentication.destroy({
|
||||
where: {
|
||||
userId: event.userId,
|
||||
},
|
||||
transaction,
|
||||
});
|
||||
await UserPermission.destroy({
|
||||
where: {
|
||||
userId: event.userId,
|
||||
},
|
||||
transaction,
|
||||
});
|
||||
await Subscription.destroy({
|
||||
where: {
|
||||
userId: event.userId,
|
||||
},
|
||||
transaction,
|
||||
});
|
||||
await ApiKey.destroy({
|
||||
where: {
|
||||
userId: event.userId,
|
||||
},
|
||||
transaction,
|
||||
});
|
||||
await Star.destroy({
|
||||
where: {
|
||||
userId: event.userId,
|
||||
},
|
||||
transaction,
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user