fix: Make attachments unique when downloaded

Fixes the issue with attachments replacing each other locally so files with same filename appears as the same file
This commit is contained in:
2026-03-30 00:08:53 +02:00
parent 8162e0444a
commit 11917f3412
3 changed files with 29 additions and 5 deletions

View File

@@ -1,4 +1,5 @@
const ROOM_NAME_SANITIZER = /[^\w.-]+/g;
const STORED_FILENAME_SANITIZER = /[^\w.-]+/g;
export function sanitizeAttachmentRoomName(roomName: string): string {
const sanitizedRoomName = roomName.trim().replace(ROOM_NAME_SANITIZER, '_');
@@ -6,6 +7,25 @@ export function sanitizeAttachmentRoomName(roomName: string): string {
return sanitizedRoomName || 'room';
}
export function resolveAttachmentStoredFilename(attachmentId: string, filename: string): string {
const sanitizedAttachmentId = attachmentId.trim().replace(STORED_FILENAME_SANITIZER, '_') || 'attachment';
const basename = filename.trim().split(/[\\/]/)
.pop() ?? '';
const extensionIndex = basename.lastIndexOf('.');
if (extensionIndex <= 0 || extensionIndex === basename.length - 1) {
return sanitizedAttachmentId;
}
const sanitizedExtension = basename.slice(extensionIndex)
.replace(STORED_FILENAME_SANITIZER, '_')
.toLowerCase();
return sanitizedExtension === '.'
? sanitizedAttachmentId
: `${sanitizedAttachmentId}${sanitizedExtension}`;
}
export function resolveAttachmentStorageBucket(mime: string): 'video' | 'audio' | 'image' | 'files' {
if (mime.startsWith('video/')) {
return 'video';

View File

@@ -1,7 +1,11 @@
import { Injectable, inject } from '@angular/core';
import { ElectronBridgeService } from '../../../core/platform/electron/electron-bridge.service';
import type { Attachment } from '../domain/attachment.models';
import { resolveAttachmentStorageBucket, sanitizeAttachmentRoomName } from './attachment-storage.helpers';
import {
resolveAttachmentStorageBucket,
resolveAttachmentStoredFilename,
sanitizeAttachmentRoomName
} from './attachment-storage.helpers';
@Injectable({ providedIn: 'root' })
export class AttachmentStorageService {
@@ -38,7 +42,7 @@ export class AttachmentStorageService {
}
async saveBlob(
attachment: Pick<Attachment, 'filename' | 'mime'>,
attachment: Pick<Attachment, 'id' | 'filename' | 'mime'>,
blob: Blob,
roomName: string
): Promise<string | null> {
@@ -55,7 +59,7 @@ export class AttachmentStorageService {
await electronApi.ensureDir(directoryPath);
const arrayBuffer = await blob.arrayBuffer();
const diskPath = `${directoryPath}/${attachment.filename}`;
const diskPath = `${directoryPath}/${resolveAttachmentStoredFilename(attachment.id, attachment.filename)}`;
await electronApi.writeFile(diskPath, this.arrayBufferToBase64(arrayBuffer));