Files
outline/server/commands/teamPermanentDeleter.ts
Tom Moor 45831e9469 Remove NotificationSettings table (#5036
* helper

* Add script to move notification settings

* wip, removal of NotificationSettings

* event name

* iteration

* test

* test

* Remove last of NotificationSettings model

* refactor

* More fixes

* snapshots

* Change emails to class instances for type safety

* test

* docs

* Update migration for self-hosted

* tsc
2023-03-18 06:32:41 -07:00

196 lines
3.8 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { Transaction } from "sequelize";
import { sequelize } from "@server/database/sequelize";
import Logger from "@server/logging/Logger";
import { traceFunction } from "@server/logging/tracing";
import {
ApiKey,
Attachment,
AuthenticationProvider,
Collection,
Document,
Event,
FileOperation,
Group,
Team,
User,
UserAuthentication,
Integration,
IntegrationAuthentication,
SearchQuery,
Share,
} from "@server/models";
async function teamPermanentDeleter(team: Team) {
if (!team.deletedAt) {
throw new Error(
`Cannot permanently delete ${team.id} team. Please delete it and try again.`
);
}
Logger.info(
"commands",
`Permanently deleting team ${team.name} (${team.id})`
);
const teamId = team.id;
let transaction!: Transaction;
try {
transaction = await sequelize.transaction();
await Attachment.findAllInBatches<Attachment>(
{
where: {
teamId,
},
limit: 100,
offset: 0,
},
async (attachments, options) => {
Logger.info(
"commands",
`Deleting attachments ${options.offset} ${
(options.offset || 0) + (options?.limit || 0)
}`
);
await Promise.all(
attachments.map((attachment) =>
attachment.destroy({
transaction,
})
)
);
}
);
// Destroy user-relation models
await User.findAllInBatches<User>(
{
attributes: ["id"],
where: {
teamId,
},
limit: 100,
offset: 0,
},
async (users) => {
const userIds = users.map((user) => user.id);
await UserAuthentication.destroy({
where: {
userId: userIds,
},
force: true,
transaction,
});
await ApiKey.destroy({
where: {
userId: userIds,
},
force: true,
transaction,
});
await Event.destroy({
where: {
actorId: userIds,
},
force: true,
transaction,
});
}
);
// Destory team-relation models
await AuthenticationProvider.destroy({
where: {
teamId,
},
force: true,
transaction,
});
// events must be first due to db constraints
await Event.destroy({
where: {
teamId,
},
force: true,
transaction,
});
await FileOperation.destroy({
where: {
teamId,
},
force: true,
transaction,
});
await Collection.destroy({
where: {
teamId,
},
force: true,
transaction,
});
await Document.unscoped().destroy({
where: {
teamId,
},
force: true,
transaction,
});
await Group.unscoped().destroy({
where: {
teamId,
},
force: true,
transaction,
});
await Integration.destroy({
where: {
teamId,
},
force: true,
transaction,
});
await IntegrationAuthentication.destroy({
where: {
teamId,
},
force: true,
transaction,
});
await SearchQuery.destroy({
where: {
teamId,
},
force: true,
transaction,
});
await Share.destroy({
where: {
teamId,
},
force: true,
transaction,
});
await team.destroy({
force: true,
transaction,
});
await Event.create(
{
name: "teams.destroy",
modelId: teamId,
},
{
transaction,
}
);
await transaction.commit();
} catch (err) {
if (transaction) {
await transaction.rollback();
}
throw err;
}
}
export default traceFunction({
spanName: "teamPermanentDeleter",
})(teamPermanentDeleter);