// @flow import Logger from "../logging/logger"; import { ApiKey, Attachment, AuthenticationProvider, Collection, Document, Event, FileOperation, Group, Team, NotificationSetting, User, UserAuthentication, Integration, IntegrationAuthentication, SearchQuery, Share, } from "../models"; import { sequelize } from "../sequelize"; export default 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; try { transaction = await sequelize.transaction(); await Attachment.findAllInBatches( { where: { teamId, }, limit: 100, offset: 0, }, async (attachments, options) => { Logger.info( "commands", `Deleting attachments ${options.offset} – ${ options.offset + options.limit }…` ); await Promise.all( attachments.map((attachment) => attachment.destroy({ transaction })) ); } ); // Destroy user-relation models await User.findAllInBatches( { 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, }); } ); // 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 Collection.destroy({ where: { teamId }, force: true, transaction, }); await Document.unscoped().destroy({ where: { teamId }, force: true, transaction, }); await FileOperation.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 NotificationSetting.destroy({ where: { teamId }, force: true, transaction, }); await SearchQuery.destroy({ where: { teamId }, force: true, transaction, }); await Share.destroy({ where: { teamId }, force: true, transaction, }); await User.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; } }