feat: orphaned data cleanup, file deletion on message/account removal, and group DM improvements

- Add fileCleanup utility to delete uploaded files from disk on message/account deletion
- Add migration to clean orphaned DM channels, attachments, reactions, read states, and stale moderator refs
- Add FK constraints on dm_message_id in attachments and dm_reactions schema
- Make bans.bannedBy and voiceRestrictions.moderatorId nullable for deleted moderators
- Transfer group DM ownership on member leave or account deletion
- Fully clean up orphaned DM channels (zero members) including files
- Add "Leave Group" context menu for group DMs in ChannelSidebar
- Add leaveDm action to spaceStore
This commit is contained in:
Jannis Braun
2026-03-11 16:54:34 +01:00
parent 8c8767ba2c
commit 1889d45a07
8 changed files with 328 additions and 14 deletions
+30
View File
@@ -0,0 +1,30 @@
import fs from 'fs';
import path from 'path';
import { config } from '../config.js';
/**
* Delete a single uploaded file by its stored filename.
* Uses path.basename() to prevent directory traversal attacks.
* Tolerates ENOENT (file already gone) but logs other errors.
*/
export function deleteUploadFile(filename: string): void {
const safeName = path.basename(filename);
const filePath = path.join(config.uploadDir, safeName);
try {
fs.unlinkSync(filePath);
} catch (err: any) {
if (err.code !== 'ENOENT') {
console.error(`Failed to delete upload file ${safeName}:`, err.message);
}
}
}
/**
* Delete multiple uploaded files from disk.
* Accepts rows with a `filename` property (e.g. attachment query results).
*/
export function deleteAttachmentFiles(rows: { filename: string }[]): void {
for (const row of rows) {
deleteUploadFile(row.filename);
}
}