mirror of
https://github.com/pocket-id/pocket-id.git
synced 2026-02-04 15:39:45 +00:00
83 lines
2.5 KiB
Svelte
83 lines
2.5 KiB
Svelte
<script lang="ts">
|
|
import { goto } from '$app/navigation';
|
|
import SignInWrapper from '$lib/components/login-wrapper.svelte';
|
|
import { Button } from '$lib/components/ui/button';
|
|
import { m } from '$lib/paraglide/messages';
|
|
import WebAuthnService from '$lib/services/webauthn-service';
|
|
import appConfigStore from '$lib/stores/application-configuration-store';
|
|
import { getWebauthnErrorMessage } from '$lib/utils/error-util';
|
|
import { tryCatch } from '$lib/utils/try-catch-util';
|
|
import { startRegistration } from '@simplewebauthn/browser';
|
|
import { fade } from 'svelte/transition';
|
|
import LoginLogoErrorSuccessIndicator from '../../login/components/login-logo-error-success-indicator.svelte';
|
|
|
|
const webauthnService = new WebAuthnService();
|
|
|
|
let isLoading = $state(false);
|
|
let error: string | undefined = $state();
|
|
|
|
async function createPasskeyAndContinue() {
|
|
isLoading = true;
|
|
error = undefined;
|
|
|
|
const optsResult = await tryCatch(webauthnService.getRegistrationOptions());
|
|
if (optsResult.error) {
|
|
error = getWebauthnErrorMessage(optsResult.error);
|
|
isLoading = false;
|
|
return;
|
|
}
|
|
|
|
const attRespResult = await tryCatch(startRegistration({ optionsJSON: optsResult.data }));
|
|
if (attRespResult.error) {
|
|
error = getWebauthnErrorMessage(attRespResult.error);
|
|
isLoading = false;
|
|
return;
|
|
}
|
|
|
|
const finishResult = await tryCatch(webauthnService.finishRegistration(attRespResult.data));
|
|
if (finishResult.error) {
|
|
error = getWebauthnErrorMessage(finishResult.error);
|
|
isLoading = false;
|
|
return;
|
|
}
|
|
|
|
goto('/settings/account');
|
|
isLoading = false;
|
|
}
|
|
</script>
|
|
|
|
<svelte:head>
|
|
<title>{m.add_passkey()}</title>
|
|
</svelte:head>
|
|
|
|
<SignInWrapper animate={!$appConfigStore.disableAnimations}>
|
|
<div class="w-full text-center">
|
|
<div class="flex justify-center">
|
|
<LoginLogoErrorSuccessIndicator error={!!error} />
|
|
</div>
|
|
<h1 class="font-playfair mt-5 text-3xl font-bold sm:text-4xl">
|
|
{m.setup_your_passkey()}
|
|
</h1>
|
|
<p class="text-muted-foreground mt-2" in:fade>
|
|
{#if !error}
|
|
{m.create_a_passkey_to_securely_access_your_account()}
|
|
{:else}
|
|
{error}. {m.please_try_again()}
|
|
{/if}
|
|
</p>
|
|
<div class="mt-10 flex w-full justify-between gap-2">
|
|
<Button
|
|
variant="secondary"
|
|
onclick={() => goto('/settings/account')}
|
|
disabled={isLoading}
|
|
class="flex-1"
|
|
>
|
|
{m.skip_for_now()}
|
|
</Button>
|
|
<Button onclick={createPasskeyAndContinue} {isLoading} class="flex-1">
|
|
{m.add_passkey()}
|
|
</Button>
|
|
</div>
|
|
</div>
|
|
</SignInWrapper>
|