Fix private calls

This commit is contained in:
2026-05-17 15:14:52 +02:00
parent 0f6cb3ee77
commit e769a6ee4a
71 changed files with 5821 additions and 349 deletions

View File

@@ -7,10 +7,24 @@ import {
sanitizeAttachmentRoomName
} from '../util/attachment-storage.util';
const DIRECT_MESSAGE_STORAGE_PREFIX = 'direct-message:';
@Injectable({ providedIn: 'root' })
export class AttachmentStorageService {
private readonly electronBridge = inject(ElectronBridgeService);
canWriteFiles(): boolean {
const electronApi = this.electronBridge.getApi();
return !!electronApi?.appendFile && !!electronApi.writeFile && !!electronApi.getAppDataPath;
}
canReadFileChunks(): boolean {
const electronApi = this.electronBridge.getApi();
return !!electronApi?.readFileChunk && !!electronApi.getFileSize;
}
async resolveExistingPath(
attachment: Pick<Attachment, 'filePath' | 'savedPath'>
): Promise<string | null> {
@@ -41,10 +55,73 @@ export class AttachmentStorageService {
}
}
async getFileSize(filePath: string): Promise<number | null> {
const electronApi = this.electronBridge.getApi();
if (!electronApi?.getFileSize || !filePath) {
return null;
}
try {
return await electronApi.getFileSize(filePath);
} catch {
return null;
}
}
async readFileChunk(filePath: string, start: number, end: number): Promise<string | null> {
const electronApi = this.electronBridge.getApi();
if (!electronApi?.readFileChunk || !filePath) {
return null;
}
try {
return await electronApi.readFileChunk(filePath, start, end);
} catch {
return null;
}
}
async getFileUrl(filePath: string): Promise<string | null> {
const electronApi = this.electronBridge.getApi();
if (!electronApi?.getFileUrl || !filePath) {
return null;
}
try {
return await electronApi.getFileUrl(filePath);
} catch {
return null;
}
}
async saveBlob(
attachment: Pick<Attachment, 'id' | 'filename' | 'mime'>,
blob: Blob,
roomName: string
): Promise<string | null> {
const diskPath = await this.createWritableFile(attachment, roomName);
if (!diskPath) {
return null;
}
try {
const arrayBuffer = await blob.arrayBuffer();
await this.writeBase64(diskPath, this.arrayBufferToBase64(arrayBuffer));
return diskPath;
} catch {
return null;
}
}
async createWritableFile(
attachment: Pick<Attachment, 'id' | 'filename' | 'mime'>,
roomName: string
): Promise<string | null> {
const electronApi = this.electronBridge.getApi();
const appDataPath = await this.resolveAppDataPath();
@@ -54,14 +131,12 @@ export class AttachmentStorageService {
}
try {
const directoryPath = `${appDataPath}/server/${sanitizeAttachmentRoomName(roomName)}/${resolveAttachmentStorageBucket(attachment.mime)}`;
const directoryPath = this.resolveStorageDirectoryPath(appDataPath, roomName, attachment.mime);
await electronApi.ensureDir(directoryPath);
const arrayBuffer = await blob.arrayBuffer();
const diskPath = `${directoryPath}/${resolveAttachmentStoredFilename(attachment.id, attachment.filename)}`;
await electronApi.writeFile(diskPath, this.arrayBufferToBase64(arrayBuffer));
await this.writeBase64(diskPath, '');
return diskPath;
} catch {
@@ -69,6 +144,20 @@ export class AttachmentStorageService {
}
}
async appendBase64(filePath: string, base64Data: string): Promise<boolean> {
const electronApi = this.electronBridge.getApi();
if (!electronApi?.appendFile || !filePath) {
return false;
}
try {
return await electronApi.appendFile(filePath, base64Data);
} catch {
return false;
}
}
async deleteFile(filePath: string): Promise<void> {
const electronApi = this.electronBridge.getApi();
@@ -95,6 +184,18 @@ export class AttachmentStorageService {
}
}
private resolveStorageDirectoryPath(appDataPath: string, containerName: string, mime: string): string {
const bucket = resolveAttachmentStorageBucket(mime);
if (containerName.startsWith(DIRECT_MESSAGE_STORAGE_PREFIX)) {
const conversationId = containerName.slice(DIRECT_MESSAGE_STORAGE_PREFIX.length);
return `${appDataPath}/direct-messages/${sanitizeAttachmentRoomName(conversationId)}/${bucket}`;
}
return `${appDataPath}/server/${sanitizeAttachmentRoomName(containerName)}/${bucket}`;
}
private async findExistingPath(candidates: (string | null | undefined)[]): Promise<string | null> {
const electronApi = this.electronBridge.getApi();
@@ -117,6 +218,16 @@ export class AttachmentStorageService {
return null;
}
private async writeBase64(filePath: string, base64Data: string): Promise<boolean> {
const electronApi = this.electronBridge.getApi();
if (!electronApi || !filePath) {
return false;
}
return await electronApi.writeFile(filePath, base64Data);
}
private arrayBufferToBase64(buffer: ArrayBuffer): string {
let binary = '';