mirror of
https://github.com/kmc7468/arkvault.git
synced 2025-12-16 23:18:48 +00:00
파일/디렉터리 목록 캐싱 추가
This commit is contained in:
90
src/lib/modules/file.ts
Normal file
90
src/lib/modules/file.ts
Normal file
@@ -0,0 +1,90 @@
|
||||
import { writable } from "svelte/store";
|
||||
import { callGetApi } from "$lib/hooks";
|
||||
import { unwrapDataKey, decryptString } from "$lib/modules/crypto";
|
||||
import type { DirectoryInfoResponse, FileInfoResponse } from "$lib/server/schemas";
|
||||
import {
|
||||
directoryInfoStore,
|
||||
fileInfoStore,
|
||||
type DirectoryInfo,
|
||||
type FileInfo,
|
||||
} from "$lib/stores/file";
|
||||
|
||||
const fetchDirectoryInfo = async (directoryId: "root" | number, masterKey: CryptoKey) => {
|
||||
const res = await callGetApi(`/api/directory/${directoryId}`);
|
||||
if (!res.ok) throw new Error("Failed to fetch directory information");
|
||||
const { metadata, subDirectories, files }: DirectoryInfoResponse = await res.json();
|
||||
|
||||
let newInfo: DirectoryInfo;
|
||||
if (directoryId === "root") {
|
||||
newInfo = {
|
||||
id: "root",
|
||||
subDirectoryIds: subDirectories,
|
||||
fileIds: files,
|
||||
};
|
||||
} else {
|
||||
const { dataKey } = await unwrapDataKey(metadata!.dek, masterKey);
|
||||
newInfo = {
|
||||
id: directoryId,
|
||||
dataKey,
|
||||
dataKeyVersion: metadata!.dekVersion,
|
||||
name: await decryptString(metadata!.name, metadata!.nameIv, dataKey),
|
||||
subDirectoryIds: subDirectories,
|
||||
fileIds: files,
|
||||
};
|
||||
}
|
||||
|
||||
const info = directoryInfoStore.get(directoryId);
|
||||
if (info) {
|
||||
info.update(() => newInfo);
|
||||
} else {
|
||||
directoryInfoStore.set(directoryId, writable(newInfo));
|
||||
}
|
||||
};
|
||||
|
||||
export const getDirectoryInfo = (directoryId: "root" | number, masterKey: CryptoKey) => {
|
||||
// TODO: MEK rotation
|
||||
|
||||
let info = directoryInfoStore.get(directoryId);
|
||||
if (!info) {
|
||||
info = writable(null);
|
||||
directoryInfoStore.set(directoryId, info);
|
||||
}
|
||||
|
||||
fetchDirectoryInfo(directoryId, masterKey);
|
||||
return info;
|
||||
};
|
||||
|
||||
const fetchFileInfo = async (fileId: number, masterKey: CryptoKey) => {
|
||||
const res = await callGetApi(`/api/file/${fileId}`);
|
||||
if (!res.ok) throw new Error("Failed to fetch file information");
|
||||
const metadata: FileInfoResponse = await res.json();
|
||||
|
||||
const { dataKey } = await unwrapDataKey(metadata.dek, masterKey);
|
||||
const newInfo: FileInfo = {
|
||||
id: fileId,
|
||||
dataKey,
|
||||
dataKeyVersion: metadata.dekVersion,
|
||||
contentIv: metadata.contentIv,
|
||||
name: await decryptString(metadata.name, metadata.nameIv, dataKey),
|
||||
};
|
||||
|
||||
const info = fileInfoStore.get(fileId);
|
||||
if (info) {
|
||||
info.update(() => newInfo);
|
||||
} else {
|
||||
fileInfoStore.set(fileId, writable(newInfo));
|
||||
}
|
||||
};
|
||||
|
||||
export const getFileInfo = (fileId: number, masterKey: CryptoKey) => {
|
||||
// TODO: MEK rotation
|
||||
|
||||
let info = fileInfoStore.get(fileId);
|
||||
if (!info) {
|
||||
info = writable(null);
|
||||
fileInfoStore.set(fileId, info);
|
||||
}
|
||||
|
||||
fetchFileInfo(fileId, masterKey);
|
||||
return info;
|
||||
};
|
||||
@@ -1,11 +0,0 @@
|
||||
import { unwrapDataKey, decryptString } from "$lib/modules/crypto";
|
||||
import type { FileInfoResponse } from "$lib/server/schemas";
|
||||
|
||||
export const decryptFileMetadata = async (metadata: FileInfoResponse, masterKey: CryptoKey) => {
|
||||
const { dataKey } = await unwrapDataKey(metadata.dek, masterKey);
|
||||
return {
|
||||
dataKey,
|
||||
dataKeyVersion: metadata.dekVersion,
|
||||
name: await decryptString(metadata.name, metadata.nameIv, dataKey),
|
||||
};
|
||||
};
|
||||
30
src/lib/stores/file.ts
Normal file
30
src/lib/stores/file.ts
Normal file
@@ -0,0 +1,30 @@
|
||||
import type { Writable } from "svelte/store";
|
||||
|
||||
export type DirectoryInfo =
|
||||
| {
|
||||
id: "root";
|
||||
dataKey?: undefined;
|
||||
dataKeyVersion?: undefined;
|
||||
name?: undefined;
|
||||
subDirectoryIds: number[];
|
||||
fileIds: number[];
|
||||
}
|
||||
| {
|
||||
id: number;
|
||||
dataKey: CryptoKey;
|
||||
dataKeyVersion: Date;
|
||||
name: string;
|
||||
subDirectoryIds: number[];
|
||||
fileIds: number[];
|
||||
};
|
||||
|
||||
export interface FileInfo {
|
||||
id: number;
|
||||
dataKey: CryptoKey;
|
||||
dataKeyVersion: Date;
|
||||
contentIv: string;
|
||||
name: string;
|
||||
}
|
||||
|
||||
export const directoryInfoStore = new Map<"root" | number, Writable<DirectoryInfo | null>>();
|
||||
export const fileInfoStore = new Map<number, Writable<FileInfo | null>>();
|
||||
@@ -1 +1,2 @@
|
||||
export * from "./file";
|
||||
export * from "./key";
|
||||
|
||||
Reference in New Issue
Block a user