mirror of
https://github.com/kmc7468/arkvault.git
synced 2026-02-04 08:06:56 +00:00
88 lines
2.5 KiB
TypeScript
88 lines
2.5 KiB
TypeScript
import { getAllFileInfos } from "$lib/indexedDB/filesystem";
|
|
import { decryptData } from "$lib/modules/crypto";
|
|
import {
|
|
getFileCache,
|
|
storeFileCache,
|
|
deleteFileCache,
|
|
getFileThumbnailCache,
|
|
storeFileThumbnailCache,
|
|
deleteFileThumbnailCache,
|
|
downloadFile,
|
|
} from "$lib/modules/file";
|
|
import { getThumbnailUrl } from "$lib/modules/thumbnail";
|
|
import type { FileThumbnailUploadRequest } from "$lib/server/schemas";
|
|
import { trpc } from "$trpc/client";
|
|
|
|
export const requestFileDownload = async (
|
|
fileId: number,
|
|
fileEncryptedIv: string,
|
|
dataKey: CryptoKey,
|
|
) => {
|
|
const cache = await getFileCache(fileId);
|
|
if (cache) return cache;
|
|
|
|
const fileBuffer = await downloadFile(fileId, fileEncryptedIv, dataKey);
|
|
storeFileCache(fileId, fileBuffer); // Intended
|
|
return fileBuffer;
|
|
};
|
|
|
|
export const requestFileThumbnailUpload = async (
|
|
fileId: number,
|
|
dataKeyVersion: Date,
|
|
thumbnailEncrypted: { ciphertext: ArrayBuffer; iv: string },
|
|
) => {
|
|
const form = new FormData();
|
|
form.set(
|
|
"metadata",
|
|
JSON.stringify({
|
|
dekVersion: dataKeyVersion.toISOString(),
|
|
contentIv: thumbnailEncrypted.iv,
|
|
} satisfies FileThumbnailUploadRequest),
|
|
);
|
|
form.set("content", new Blob([thumbnailEncrypted.ciphertext]));
|
|
|
|
return await fetch(`/api/file/${fileId}/thumbnail/upload`, { method: "POST", body: form });
|
|
};
|
|
|
|
export const requestFileThumbnailDownload = async (fileId: number, dataKey?: CryptoKey) => {
|
|
const cache = await getFileThumbnailCache(fileId);
|
|
if (cache || !dataKey) return cache;
|
|
|
|
let thumbnailInfo;
|
|
try {
|
|
thumbnailInfo = await trpc().file.thumbnail.query({ id: fileId });
|
|
} catch {
|
|
// TODO: Error Handling
|
|
return null;
|
|
}
|
|
const { contentIv: thumbnailEncryptedIv } = thumbnailInfo;
|
|
|
|
const res = await fetch(`/api/file/${fileId}/thumbnail/download`);
|
|
if (!res.ok) return null;
|
|
|
|
const thumbnailEncrypted = await res.arrayBuffer();
|
|
const thumbnailBuffer = await decryptData(thumbnailEncrypted, thumbnailEncryptedIv, dataKey);
|
|
|
|
storeFileThumbnailCache(fileId, thumbnailBuffer); // Intended
|
|
return getThumbnailUrl(thumbnailBuffer);
|
|
};
|
|
|
|
export const requestDeletedFilesCleanup = async () => {
|
|
let liveFiles;
|
|
try {
|
|
liveFiles = await trpc().file.list.query();
|
|
} catch {
|
|
// TODO: Error Handling
|
|
return;
|
|
}
|
|
|
|
const liveFilesSet = new Set(liveFiles);
|
|
const maybeCachedFiles = await getAllFileInfos();
|
|
|
|
await Promise.all(
|
|
maybeCachedFiles
|
|
.filter(({ id }) => !liveFilesSet.has(id))
|
|
.flatMap(({ id }) => [deleteFileCache(id), deleteFileThumbnailCache(id)]),
|
|
);
|
|
};
|