Files
arkvault/src/routes/(fullscreen)/key/export/+page.svelte
2025-01-27 19:33:38 +09:00

117 lines
3.5 KiB
Svelte

<script lang="ts">
import FileSaver from "file-saver";
import { goto } from "$app/navigation";
import { Button, TextButton, BottomDiv, FullscreenDiv } from "$lib/components/atoms";
import { TitledDiv } from "$lib/components/molecules";
import { clientKeyStore } from "$lib/stores";
import BeforeContinueBottomSheet from "./BeforeContinueBottomSheet.svelte";
import BeforeContinueModal from "./BeforeContinueModal.svelte";
import {
serializeClientKeys,
requestClientRegistration,
storeClientKeys,
requestSessionUpgrade,
requestInitialMasterKeyAndHmacSecretRegistration,
} from "./service";
import IconKey from "~icons/material-symbols/key";
let { data } = $props();
let isBeforeContinueModalOpen = $state(false);
let isBeforeContinueBottomSheetOpen = $state(false);
const exportClientKeys = () => {
const clientKeysSerialized = serializeClientKeys(
data.encryptKeyBase64,
data.decryptKeyBase64,
data.signKeyBase64,
data.verifyKeyBase64,
);
const clientKeysBlob = new Blob([JSON.stringify(clientKeysSerialized)], {
type: "application/json",
});
FileSaver.saveAs(clientKeysBlob, "arkvault-clientkey.json");
if (!isBeforeContinueBottomSheetOpen) {
setTimeout(() => {
isBeforeContinueBottomSheetOpen = true;
}, 1000);
}
};
const registerPubKeys = async () => {
if (!$clientKeyStore) {
throw new Error("Failed to find client keys");
}
try {
if (
!(await requestClientRegistration(
data.encryptKeyBase64,
$clientKeyStore.decryptKey,
data.verifyKeyBase64,
$clientKeyStore.signKey,
))
)
throw new Error("Failed to register client");
await storeClientKeys($clientKeyStore);
if (
!(await requestSessionUpgrade(
data.encryptKeyBase64,
$clientKeyStore.decryptKey,
data.verifyKeyBase64,
$clientKeyStore.signKey,
))
)
throw new Error("Failed to upgrade session");
if (
!(await requestInitialMasterKeyAndHmacSecretRegistration(
data.masterKeyWrapped,
data.hmacSecretWrapped,
$clientKeyStore.signKey,
))
)
throw new Error("Failed to register initial MEK and HSK");
await goto("/client/pending?redirect=" + encodeURIComponent(data.redirectPath));
} catch (e) {
// TODO: Error handling
throw e;
}
};
</script>
<svelte:head>
<title>암호 키 생성하기</title>
</svelte:head>
<FullscreenDiv>
<TitledDiv icon={IconKey}>
{#snippet title()}
암호 키를 파일로 내보낼까요?
{/snippet}
<div class="space-y-2 break-keep text-lg text-gray-800">
<p>
모든 디바이스의 암호 키가 유실되면, 서버에 저장된 데이터를 영원히 복호화할 수 없게 돼요.
</p>
<p>만약의 상황을 위해 암호 키를 파일로 내보낼 수 있어요.</p>
</div>
</TitledDiv>
<BottomDiv class="flex flex-col items-center gap-y-2">
<Button onclick={exportClientKeys} class="w-full">암호 키 내보내기</Button>
<TextButton onclick={() => (isBeforeContinueModalOpen = true)}>내보내지 않을래요</TextButton>
</BottomDiv>
</FullscreenDiv>
<BeforeContinueModal bind:isOpen={isBeforeContinueModalOpen} onContinueClick={registerPubKeys} />
<BeforeContinueBottomSheet
bind:isOpen={isBeforeContinueBottomSheetOpen}
onRetryClick={exportClientKeys}
onContinueClick={registerPubKeys}
/>