delete associated notes on account deletion

This commit is contained in:
Namekuji 2023-09-02 06:04:50 -04:00
parent 494243cba8
commit 91762bb8ca
No known key found for this signature in database
GPG key ID: 1D62332C07FBA532

View file

@ -1,6 +1,20 @@
import type Bull from "bull";
import { queueLogger } from "../../logger.js";
import { DriveFiles, Notes, UserProfiles, Users } from "@/models/index.js";
import {
ChannelNotePinings,
ClipNotes,
DriveFiles,
MutedNotes,
NoteFavorites,
NoteUnreads,
NoteWatchings,
Notes,
PromoNotes,
PromoReads,
UserNotePinings,
UserProfiles,
Users,
} from "@/models/index.js";
import type { DbUserDeleteJobData } from "@/queue/types.js";
import type { Note } from "@/models/entities/note.js";
import type { DriveFile } from "@/models/entities/drive-file.js";
@ -8,8 +22,14 @@ import { MoreThan } from "typeorm";
import { deleteFileSync } from "@/services/drive/delete-file.js";
import { sendEmail } from "@/services/send-email.js";
import meilisearch from "@/db/meilisearch.js";
import { acctToUserIdCache, userByIdCache, userDenormalizedCache } from "@/services/user-cache.js";
import config from "@/config/index.js";
import { userByIdCache, userDenormalizedCache } from "@/services/user-cache.js";
import {
parseHomeTimeline,
parseScyllaNote,
prepared,
scyllaClient,
} from "@/db/scylla.js";
import type { Client } from "cassandra-driver";
const logger = queueLogger.createSubLogger("delete-account");
@ -25,30 +45,101 @@ export async function deleteAccount(
// Delete notes
let cursor: Note["id"] | null = null;
while (true) {
const notes = (await Notes.find({
where: {
userId: user.id,
...(cursor ? { id: MoreThan(cursor) } : {}),
if (scyllaClient) {
scyllaClient.eachRow(
prepared.note.select.byUserId,
[user.id],
{ prepare: true },
(_, row) => {
const client = scyllaClient as Client;
const note = parseScyllaNote(row);
const noteDeleteParams = [
note.createdAt,
note.createdAt,
note.userId,
note.userHost ?? "local",
note.visibility,
] as [Date, Date, string, string, string];
client.execute(prepared.note.delete, noteDeleteParams, {
prepare: true,
});
client.eachRow(
prepared.homeTimeline.select.byId,
[note.id],
{
prepare: true,
},
(_, row) => {
const timeline = parseHomeTimeline(row);
client.execute(
prepared.homeTimeline.delete,
[
timeline.feedUserId,
timeline.createdAtDate,
timeline.createdAt,
timeline.userId,
],
{ prepare: true },
);
},
);
if (meilisearch) {
meilisearch.deleteNotes([note]);
}
ChannelNotePinings.delete({
noteId: note.id,
});
ClipNotes.delete({
noteId: note.id,
});
MutedNotes.delete({
noteId: note.id,
});
NoteFavorites.delete({
noteId: note.id,
});
NoteUnreads.delete({
noteId: note.id,
});
NoteWatchings.delete({
noteId: note.id,
});
PromoNotes.delete({
noteId: note.id,
});
PromoReads.delete({
noteId: note.id,
});
UserNotePinings.delete({
noteId: note.id,
});
},
take: 10,
order: {
id: 1,
},
})) as Note[];
);
} else {
while (true) {
const notes = (await Notes.find({
where: {
userId: user.id,
...(cursor ? { id: MoreThan(cursor) } : {}),
},
take: 10,
order: {
id: 1,
},
})) as Note[];
if (notes.length === 0) {
break;
}
if (notes.length === 0) {
break;
}
cursor = notes[notes.length - 1].id;
cursor = notes[notes.length - 1].id;
await Notes.delete(notes.map((note) => note.id));
if (meilisearch) {
await meilisearch.deleteNotes(notes);
await Notes.delete(notes.map((note) => note.id));
if (meilisearch) {
await meilisearch.deleteNotes(notes);
}
}
}
logger.succ("All of notes deleted");
}