mirror of
https://github.com/kmc7468/arkvault.git
synced 2025-12-14 22:08:45 +00:00
Merge branch 'dev' into refactor-to-atomic-patterns
This commit is contained in:
@@ -15,6 +15,7 @@ import type {
|
|||||||
DuplicateFileScanRequest,
|
DuplicateFileScanRequest,
|
||||||
DuplicateFileScanResponse,
|
DuplicateFileScanResponse,
|
||||||
FileUploadRequest,
|
FileUploadRequest,
|
||||||
|
FileUploadResponse,
|
||||||
} from "$lib/server/schemas";
|
} from "$lib/server/schemas";
|
||||||
import {
|
import {
|
||||||
fileUploadStatusStore,
|
fileUploadStatusStore,
|
||||||
@@ -131,7 +132,7 @@ const requestFileUpload = limitFunction(
|
|||||||
return value;
|
return value;
|
||||||
});
|
});
|
||||||
|
|
||||||
await axios.post("/api/file/upload", form, {
|
const res = await axios.post("/api/file/upload", form, {
|
||||||
onUploadProgress: ({ progress, rate, estimated }) => {
|
onUploadProgress: ({ progress, rate, estimated }) => {
|
||||||
status.update((value) => {
|
status.update((value) => {
|
||||||
value.progress = progress;
|
value.progress = progress;
|
||||||
@@ -141,11 +142,14 @@ const requestFileUpload = limitFunction(
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
const { file }: FileUploadResponse = res.data;
|
||||||
|
|
||||||
status.update((value) => {
|
status.update((value) => {
|
||||||
value.status = "uploaded";
|
value.status = "uploaded";
|
||||||
return value;
|
return value;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
return { fileId: file };
|
||||||
},
|
},
|
||||||
{ concurrency: 1 },
|
{ concurrency: 1 },
|
||||||
);
|
);
|
||||||
@@ -156,7 +160,7 @@ export const uploadFile = async (
|
|||||||
hmacSecret: HmacSecret,
|
hmacSecret: HmacSecret,
|
||||||
masterKey: MasterKey,
|
masterKey: MasterKey,
|
||||||
onDuplicate: () => Promise<boolean>,
|
onDuplicate: () => Promise<boolean>,
|
||||||
) => {
|
): Promise<{ fileId: number; fileBuffer: ArrayBuffer } | undefined> => {
|
||||||
const status = writable<FileUploadStatus>({
|
const status = writable<FileUploadStatus>({
|
||||||
name: file.name,
|
name: file.name,
|
||||||
parentId,
|
parentId,
|
||||||
@@ -182,7 +186,7 @@ export const uploadFile = async (
|
|||||||
value = value.filter((v) => v !== status);
|
value = value.filter((v) => v !== status);
|
||||||
return value;
|
return value;
|
||||||
});
|
});
|
||||||
return false;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
const {
|
const {
|
||||||
@@ -219,8 +223,8 @@ export const uploadFile = async (
|
|||||||
form.set("content", new Blob([fileEncrypted.ciphertext]));
|
form.set("content", new Blob([fileEncrypted.ciphertext]));
|
||||||
form.set("checksum", fileEncryptedHash);
|
form.set("checksum", fileEncryptedHash);
|
||||||
|
|
||||||
await requestFileUpload(status, form);
|
const { fileId } = await requestFileUpload(status, form);
|
||||||
return true;
|
return { fileId, fileBuffer };
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
status.update((value) => {
|
status.update((value) => {
|
||||||
value.status = "error";
|
value.status = "error";
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ export const createClient = async (encPubKey: string, sigPubKey: string, userId:
|
|||||||
.insertInto("user_client")
|
.insertInto("user_client")
|
||||||
.values({ user_id: userId, client_id: clientId })
|
.values({ user_id: userId, client_id: clientId })
|
||||||
.execute();
|
.execute();
|
||||||
return { clientId };
|
return { id: clientId };
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -203,7 +203,7 @@ export const registerFile = async (params: NewFile) => {
|
|||||||
throw new Error("Invalid arguments");
|
throw new Error("Invalid arguments");
|
||||||
}
|
}
|
||||||
|
|
||||||
await db.transaction().execute(async (trx) => {
|
return await db.transaction().execute(async (trx) => {
|
||||||
const mek = await trx
|
const mek = await trx
|
||||||
.selectFrom("master_encryption_key")
|
.selectFrom("master_encryption_key")
|
||||||
.select("version")
|
.select("version")
|
||||||
@@ -259,6 +259,7 @@ export const registerFile = async (params: NewFile) => {
|
|||||||
new_name: params.encName,
|
new_name: params.encName,
|
||||||
})
|
})
|
||||||
.execute();
|
.execute();
|
||||||
|
return { id: fileId };
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -60,3 +60,8 @@ export const fileUploadRequest = z.object({
|
|||||||
lastModifiedAtIv: z.string().base64().nonempty(),
|
lastModifiedAtIv: z.string().base64().nonempty(),
|
||||||
});
|
});
|
||||||
export type FileUploadRequest = z.infer<typeof fileUploadRequest>;
|
export type FileUploadRequest = z.infer<typeof fileUploadRequest>;
|
||||||
|
|
||||||
|
export const fileUploadResponse = z.object({
|
||||||
|
file: z.number().int().positive(),
|
||||||
|
});
|
||||||
|
export type FileUploadResponse = z.infer<typeof fileUploadResponse>;
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ export const registerUserClient = async (
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const { clientId } = await createClient(encPubKey, sigPubKey, userId);
|
const { id: clientId } = await createClient(encPubKey, sigPubKey, userId);
|
||||||
return { challenge: await createUserClientChallenge(ip, userId, clientId, encPubKey) };
|
return { challenge: await createUserClientChallenge(ip, userId, clientId, encPubKey) };
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (e instanceof IntegrityError && e.message === "Public key(s) already registered") {
|
if (e instanceof IntegrityError && e.message === "Public key(s) already registered") {
|
||||||
|
|||||||
@@ -131,11 +131,12 @@ export const uploadFile = async (
|
|||||||
throw new Error("Invalid checksum");
|
throw new Error("Invalid checksum");
|
||||||
}
|
}
|
||||||
|
|
||||||
await registerFile({
|
const { id: fileId } = await registerFile({
|
||||||
...params,
|
...params,
|
||||||
path,
|
path,
|
||||||
encContentHash: hash,
|
encContentHash: hash,
|
||||||
});
|
});
|
||||||
|
return { fileId };
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
await safeUnlink(path);
|
await safeUnlink(path);
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { getContext, setContext } from "svelte";
|
|||||||
import { callGetApi, callPostApi } from "$lib/hooks";
|
import { callGetApi, callPostApi } from "$lib/hooks";
|
||||||
import { storeHmacSecrets } from "$lib/indexedDB";
|
import { storeHmacSecrets } from "$lib/indexedDB";
|
||||||
import { generateDataKey, wrapDataKey, unwrapHmacSecret, encryptString } from "$lib/modules/crypto";
|
import { generateDataKey, wrapDataKey, unwrapHmacSecret, encryptString } from "$lib/modules/crypto";
|
||||||
import { deleteFileCache, uploadFile } from "$lib/modules/file";
|
import { storeFileCache, deleteFileCache, uploadFile } from "$lib/modules/file";
|
||||||
import type {
|
import type {
|
||||||
DirectoryRenameRequest,
|
DirectoryRenameRequest,
|
||||||
DirectoryCreateRequest,
|
DirectoryCreateRequest,
|
||||||
@@ -77,7 +77,11 @@ export const requestFileUpload = async (
|
|||||||
masterKey: MasterKey,
|
masterKey: MasterKey,
|
||||||
onDuplicate: () => Promise<boolean>,
|
onDuplicate: () => Promise<boolean>,
|
||||||
) => {
|
) => {
|
||||||
return await uploadFile(file, parentId, hmacSecret, masterKey, onDuplicate);
|
const res = await uploadFile(file, parentId, hmacSecret, masterKey, onDuplicate);
|
||||||
|
if (!res) return false;
|
||||||
|
|
||||||
|
storeFileCache(res.fileId, res.fileBuffer); // Intended
|
||||||
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const requestEntryRename = async (entry: SelectedEntry, newName: string) => {
|
export const requestEntryRename = async (entry: SelectedEntry, newName: string) => {
|
||||||
|
|||||||
@@ -1,8 +1,12 @@
|
|||||||
import Busboy from "@fastify/busboy";
|
import Busboy from "@fastify/busboy";
|
||||||
import { error, text } from "@sveltejs/kit";
|
import { error, json } from "@sveltejs/kit";
|
||||||
import { Readable, Writable } from "stream";
|
import { Readable, Writable } from "stream";
|
||||||
import { authorize } from "$lib/server/modules/auth";
|
import { authorize } from "$lib/server/modules/auth";
|
||||||
import { fileUploadRequest } from "$lib/server/schemas";
|
import {
|
||||||
|
fileUploadRequest,
|
||||||
|
fileUploadResponse,
|
||||||
|
type FileUploadResponse,
|
||||||
|
} from "$lib/server/schemas";
|
||||||
import { uploadFile } from "$lib/server/services/file";
|
import { uploadFile } from "$lib/server/services/file";
|
||||||
import type { RequestHandler } from "./$types";
|
import type { RequestHandler } from "./$types";
|
||||||
|
|
||||||
@@ -87,8 +91,8 @@ export const POST: RequestHandler = async ({ locals, request }) => {
|
|||||||
if (!metadata || content) error(400, "Invalid request body");
|
if (!metadata || content) error(400, "Invalid request body");
|
||||||
content = file;
|
content = file;
|
||||||
|
|
||||||
await uploadFile(metadata, content, checksum);
|
const { fileId } = await uploadFile(metadata, content, checksum);
|
||||||
resolve(text("File uploaded", { headers: { "Content-Type": "text/plain" } }));
|
resolve(json(fileUploadResponse.parse({ file: fileId } satisfies FileUploadResponse)));
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
bb.on("finish", () => rejectChecksum(new Error("Invalid request body")));
|
bb.on("finish", () => rejectChecksum(new Error("Invalid request body")));
|
||||||
|
|||||||
Reference in New Issue
Block a user