From 0d35f0b60730d730be0c29d8cb4ab8dd4a0f28c5 Mon Sep 17 00:00:00 2001 From: static Date: Sat, 12 Jul 2025 04:57:15 +0900 Subject: [PATCH] =?UTF-8?q?=EC=82=AC=EC=86=8C=ED=95=9C=20=EB=A6=AC?= =?UTF-8?q?=ED=8C=A9=ED=86=A0=EB=A7=81=202?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../organisms/modals}/ForceLoginModal.svelte | 2 +- src/lib/components/organisms/modals/index.ts | 1 + src/lib/services/file.ts | 24 ++++++++++++++++++- .../(fullscreen)/auth/login/+page.svelte | 2 +- src/routes/(fullscreen)/file/[id]/service.ts | 16 +++---------- .../(fullscreen)/key/generate/+page.svelte | 2 +- .../key/generate/ForceLoginModal.svelte | 20 ---------------- .../settings/thumbnail/service.svelte.ts | 15 ++---------- 8 files changed, 32 insertions(+), 50 deletions(-) rename src/{routes/(fullscreen)/auth/login => lib/components/organisms/modals}/ForceLoginModal.svelte (95%) delete mode 100644 src/routes/(fullscreen)/key/generate/ForceLoginModal.svelte diff --git a/src/routes/(fullscreen)/auth/login/ForceLoginModal.svelte b/src/lib/components/organisms/modals/ForceLoginModal.svelte similarity index 95% rename from src/routes/(fullscreen)/auth/login/ForceLoginModal.svelte rename to src/lib/components/organisms/modals/ForceLoginModal.svelte index fc88a4a..e6aa82b 100644 --- a/src/routes/(fullscreen)/auth/login/ForceLoginModal.svelte +++ b/src/lib/components/organisms/modals/ForceLoginModal.svelte @@ -3,7 +3,7 @@ interface Props { isOpen: boolean; - oncancel: () => void; + oncancel?: () => void; onLoginClick: () => void; } diff --git a/src/lib/components/organisms/modals/index.ts b/src/lib/components/organisms/modals/index.ts index 2fa9422..56c64a1 100644 --- a/src/lib/components/organisms/modals/index.ts +++ b/src/lib/components/organisms/modals/index.ts @@ -1,3 +1,4 @@ export { default as CategoryCreateModal } from "./CategoryCreateModal.svelte"; +export { default as ForceLoginModal } from "./ForceLoginModal.svelte"; export { default as RenameModal } from "./RenameModal.svelte"; export { default as TextInputModal } from "./TextInputModal.svelte"; diff --git a/src/lib/services/file.ts b/src/lib/services/file.ts index 64d9fd4..11742c8 100644 --- a/src/lib/services/file.ts +++ b/src/lib/services/file.ts @@ -11,7 +11,11 @@ import { downloadFile, } from "$lib/modules/file"; import { getThumbnailUrl } from "$lib/modules/thumbnail"; -import type { FileThumbnailInfoResponse, FileListResponse } from "$lib/server/schemas"; +import type { + FileThumbnailInfoResponse, + FileThumbnailUploadRequest, + FileListResponse, +} from "$lib/server/schemas"; export const requestFileDownload = async ( fileId: number, @@ -26,6 +30,24 @@ export const requestFileDownload = async ( 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) return cache; diff --git a/src/routes/(fullscreen)/auth/login/+page.svelte b/src/routes/(fullscreen)/auth/login/+page.svelte index 813b130..b4f3d32 100644 --- a/src/routes/(fullscreen)/auth/login/+page.svelte +++ b/src/routes/(fullscreen)/auth/login/+page.svelte @@ -2,8 +2,8 @@ import { goto } from "$app/navigation"; import { BottomDiv, Button, FullscreenDiv, TextButton, TextInput } from "$lib/components/atoms"; import { TitledDiv } from "$lib/components/molecules"; + import { ForceLoginModal } from "$lib/components/organisms"; import { clientKeyStore, masterKeyStore } from "$lib/stores"; - import ForceLoginModal from "./ForceLoginModal.svelte"; import { requestLogout, requestLogin, diff --git a/src/routes/(fullscreen)/file/[id]/service.ts b/src/routes/(fullscreen)/file/[id]/service.ts index 83a57c6..00614d6 100644 --- a/src/routes/(fullscreen)/file/[id]/service.ts +++ b/src/routes/(fullscreen)/file/[id]/service.ts @@ -1,7 +1,8 @@ import { callPostApi } from "$lib/hooks"; import { encryptData } from "$lib/modules/crypto"; import { storeFileThumbnailCache } from "$lib/modules/file"; -import type { CategoryFileAddRequest, FileThumbnailUploadRequest } from "$lib/server/schemas"; +import type { CategoryFileAddRequest } from "$lib/server/schemas"; +import { requestFileThumbnailUpload } from "$lib/services/file"; export { requestCategoryCreation, requestFileRemovalFromCategory } from "$lib/services/category"; export { requestFileDownload } from "$lib/services/file"; @@ -14,18 +15,7 @@ export const requestThumbnailUpload = async ( ) => { const thumbnailBuffer = await thumbnail.arrayBuffer(); const thumbnailEncrypted = await encryptData(thumbnailBuffer, dataKey); - - const form = new FormData(); - form.set( - "metadata", - JSON.stringify({ - dekVersion: dataKeyVersion.toISOString(), - contentIv: thumbnailEncrypted.iv, - } satisfies FileThumbnailUploadRequest), - ); - form.set("content", new Blob([thumbnailEncrypted.ciphertext])); - - const res = await fetch(`/api/file/${fileId}/thumbnail/upload`, { method: "POST", body: form }); + const res = await requestFileThumbnailUpload(fileId, dataKeyVersion, thumbnailEncrypted); if (!res.ok) return false; storeFileThumbnailCache(fileId, thumbnailBuffer); // Intended diff --git a/src/routes/(fullscreen)/key/generate/+page.svelte b/src/routes/(fullscreen)/key/generate/+page.svelte index 090651f..1155577 100644 --- a/src/routes/(fullscreen)/key/generate/+page.svelte +++ b/src/routes/(fullscreen)/key/generate/+page.svelte @@ -3,10 +3,10 @@ import { goto } from "$app/navigation"; import { BottomDiv, Button, FullscreenDiv, TextButton } from "$lib/components/atoms"; import { TitledDiv } from "$lib/components/molecules"; + import { ForceLoginModal } from "$lib/components/organisms"; import { gotoStateful } from "$lib/hooks"; import { storeClientKeys } from "$lib/modules/key"; import { clientKeyStore } from "$lib/stores"; - import ForceLoginModal from "./ForceLoginModal.svelte"; import Order from "./Order.svelte"; import { generateClientKeys, diff --git a/src/routes/(fullscreen)/key/generate/ForceLoginModal.svelte b/src/routes/(fullscreen)/key/generate/ForceLoginModal.svelte deleted file mode 100644 index f488603..0000000 --- a/src/routes/(fullscreen)/key/generate/ForceLoginModal.svelte +++ /dev/null @@ -1,20 +0,0 @@ - - - -

다른 디바이스에서는 로그아웃하고, 이 디바이스에서 로그인할까요?

-
diff --git a/src/routes/(fullscreen)/settings/thumbnail/service.svelte.ts b/src/routes/(fullscreen)/settings/thumbnail/service.svelte.ts index 79a4022..6bb37b1 100644 --- a/src/routes/(fullscreen)/settings/thumbnail/service.svelte.ts +++ b/src/routes/(fullscreen)/settings/thumbnail/service.svelte.ts @@ -4,8 +4,7 @@ import { encryptData } from "$lib/modules/crypto"; import { storeFileThumbnailCache } from "$lib/modules/file"; import type { FileInfo } from "$lib/modules/filesystem"; import { generateThumbnail as doGenerateThumbnail } from "$lib/modules/thumbnail"; -import type { FileThumbnailUploadRequest } from "$lib/server/schemas"; -import { requestFileDownload } from "$lib/services/file"; +import { requestFileDownload, requestFileThumbnailUpload } from "$lib/services/file"; export type GenerationStatus = | "queued" @@ -68,17 +67,7 @@ const requestThumbnailUpload = limitFunction( ) => { status.set("uploading"); - const form = new FormData(); - form.set( - "metadata", - JSON.stringify({ - dekVersion: dataKeyVersion.toISOString(), - contentIv: thumbnail.iv, - } satisfies FileThumbnailUploadRequest), - ); - form.set("content", new Blob([thumbnail.ciphertext])); - - const res = await fetch(`/api/file/${fileId}/thumbnail/upload`, { method: "POST", body: form }); + const res = await requestFileThumbnailUpload(fileId, dataKeyVersion, thumbnail); if (!res.ok) return false; status.set("uploaded");