diff --git a/packages/backend/src/queue/processors/DeleteAccountProcessorService.ts b/packages/backend/src/queue/processors/DeleteAccountProcessorService.ts index 1893af5532..660e1d1ca4 100644 --- a/packages/backend/src/queue/processors/DeleteAccountProcessorService.ts +++ b/packages/backend/src/queue/processors/DeleteAccountProcessorService.ts @@ -4,13 +4,11 @@ */ import { Inject, Injectable } from '@nestjs/common'; -import { MoreThan } from 'typeorm'; import { DI } from '@/di-symbols.js'; import type { DriveFilesRepository, NotesRepository, UserProfilesRepository, UsersRepository } from '@/models/_.js'; import type Logger from '@/logger.js'; import { DriveService } from '@/core/DriveService.js'; -import type { MiDriveFile } from '@/models/DriveFile.js'; -import type { MiNote } from '@/models/Note.js'; +import type { MiUser } from '@/models/User.js'; import { EmailService } from '@/core/EmailService.js'; import { bindThis } from '@/decorators.js'; import { SearchService } from '@/core/SearchService.js'; @@ -43,6 +41,50 @@ export class DeleteAccountProcessorService { this.logger = this.queueLoggerService.logger.createSubLogger('delete-account'); } + private async deleteNotes(user: MiUser) { + while (true) { + const notes = await this.notesRepository.find({ + where: { + userId: user.id, + }, + take: 100, + }); + + if (notes.length === 0) { + break; + } + + await this.notesRepository.delete(notes.map(note => note.id)); + + for (const note of notes) { + await this.searchService.unindexNote(note); + } + } + + this.logger.succ('All of notes deleted'); + } + + private async deleteFiles(user: MiUser) { + while (true) { + const files = await this.driveFilesRepository.find({ + where: { + userId: user.id, + }, + take: 10, + }); + + if (files.length === 0) { + break; + } + + for (const file of files) { + await this.driveService.deleteFileSync(file); + } + } + + this.logger.succ('All of files deleted'); + } + @bindThis public async process(job: Bull.Job): Promise { this.logger.info(`Deleting account of ${job.data.user.id} ...`); @@ -52,70 +94,15 @@ export class DeleteAccountProcessorService { return; } - { // Delete notes - let cursor: MiNote['id'] | null = null; - - while (true) { - const notes = await this.notesRepository.find({ - where: { - userId: user.id, - ...(cursor ? { id: MoreThan(cursor) } : {}), - }, - take: 100, - order: { - id: 1, - }, - }) as MiNote[]; - - if (notes.length === 0) { - break; - } - - cursor = notes[notes.length - 1].id; - - await this.notesRepository.delete(notes.map(note => note.id)); - - for (const note of notes) { - await this.searchService.unindexNote(note); - } - } - - this.logger.succ('All of notes deleted'); - } - - { // Delete files - let cursor: MiDriveFile['id'] | null = null; - - while (true) { - const files = await this.driveFilesRepository.find({ - where: { - userId: user.id, - ...(cursor ? { id: MoreThan(cursor) } : {}), - }, - take: 10, - order: { - id: 1, - }, - }) as MiDriveFile[]; - - if (files.length === 0) { - break; - } - - cursor = files[files.length - 1].id; - - for (const file of files) { - await this.driveService.deleteFileSync(file); - } - } - - this.logger.succ('All of files deleted'); - } + await Promise.all([ + this.deleteNotes(user), + this.deleteFiles(user), + ]); { // Send email notification const profile = await this.userProfilesRepository.findOneByOrFail({ userId: user.id }); if (profile.email && profile.emailVerified) { - this.emailService.sendEmail(profile.email, 'Account deleted', + await this.emailService.sendEmail(profile.email, 'Account deleted', 'Your account has been deleted.', 'Your account has been deleted.'); }