refactor form stuff

This commit is contained in:
Skye 2022-11-26 14:14:10 +09:00
parent 0425586027
commit 29807d104c
Signed by: me
GPG key ID: 0104BC05F41B77B8
9 changed files with 168 additions and 231 deletions

148
src/lib/KratosForm.svelte Normal file
View file

@ -0,0 +1,148 @@
<script lang="ts">
import { browser } from '$app/environment';
import type { UiContainer, UiNodeInputAttributesTypeEnum } from '@ory/client';
import {
getNodeLabel,
isUiNodeAnchorAttributes,
isUiNodeImageAttributes,
isUiNodeInputAttributes,
isUiNodeScriptAttributes,
isUiNodeTextAttributes
} from '@ory/integrations/ui';
export let ui: UiContainer;
</script>
{#if ui.messages}
{#each ui.messages as message}
{#if message.type == 'info'}
<div class="alert alert-info">
<div>
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
class="stroke-current flex-shrink-0 w-6 h-6"
><path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"
/></svg
>
<span>{message.text}</span>
</div>
</div>
{:else if message.type == 'error'}
<div class="alert alert-error">
<div>
<svg
xmlns="http://www.w3.org/2000/svg"
class="stroke-current flex-shrink-0 h-6 w-6"
fill="none"
viewBox="0 0 24 24"
><path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M10 14l2-2m0 0l2-2m-2 2l-2-2m2 2l2 2m7-2a9 9 0 11-18 0 9 9 0 0118 0z"
/></svg
>
<span>{message.text}</span>
</div>
</div>
{:else}
<div class="alert">
<div>
<span>{message.text}</span>
</div>
</div>
{/if}
{/each}
{/if}
<form action={ui.action} method={ui.method} class="space-y-3">
{#each ui.nodes as node}
{#if isUiNodeTextAttributes(node.attributes)}
{node.attributes.text.text}
{:else if isUiNodeInputAttributes(node.attributes)}
{#if node.attributes.type == 'button' || node.attributes.type == 'submit'}
<div class="form-control">
<button
class="btn btn-primary"
on:click={eval(node.attributes.onclick ?? '')}
disabled={node.attributes.disabled}
name={node.attributes.name}
type={node.attributes.type}
value={node.attributes.value ?? ''}
>
{getNodeLabel(node)}
</button>
</div>
{:else if node.attributes.type == 'text' || node.attributes.type == 'password' || node.attributes.type == 'number' || node.attributes.type == 'email' || node.attributes.type == 'tel' || node.attributes.type == 'datetime-local' || node.attributes.type == 'date' || node.attributes.type == 'url'}
<div class="form-control">
{#if node.meta.label}
<label class="label" for={node.attributes.name}>
<span class="label-text">{getNodeLabel(node)}</span>
{#if node.attributes.required}
<span class="label-text-alt">Required</span>
{/if}
</label>
{/if}
<input
on:click={eval(node.attributes.onclick ?? '')}
class="input input-bordered"
id={node.attributes.name}
autocomplete={node.attributes.autocomplete}
disabled={node.attributes.disabled}
name={node.attributes.name}
pattern={node.attributes.pattern}
required={node.attributes.required}
type={node.attributes.type}
value={node.attributes.value ?? ''}
/>
</div>
{:else if node.attributes.type == 'checkbox'}
<div class="form-control">
<label class="label cursor-pointer">
<span class="label-text">{getNodeLabel(node)}</span>
<input
on:click={eval(node.attributes.onclick ?? '')}
class="checkbox"
autocomplete={node.attributes.autocomplete}
disabled={node.attributes.disabled}
name={node.attributes.name}
pattern={node.attributes.pattern}
required={node.attributes.required}
type={node.attributes.type}
value={node.attributes.value ?? ''}
/>
</label>
</div>
{:else if node.attributes.type == 'hidden'}
<input
on:click={eval(node.attributes.onclick ?? '')}
class="checkbox"
autocomplete={node.attributes.autocomplete}
disabled={node.attributes.disabled}
name={node.attributes.name}
pattern={node.attributes.pattern}
required={node.attributes.required}
type={node.attributes.type}
value={node.attributes.value ?? ''}
/>
{/if}
{:else if isUiNodeImageAttributes(node.attributes)}
<img alt={getNodeLabel(node)} {...node.attributes} />
{:else if isUiNodeAnchorAttributes(node.attributes)}
<a class="btn btn-primary" href={node.attributes.href} id={node.attributes.id}>
{getNodeLabel(node)}
</a>
{:else if isUiNodeScriptAttributes(node.attributes)}
{#if browser}
<script {...node.attributes}></script>
{/if}
{/if}
{/each}
</form>

View file

@ -57,7 +57,6 @@ export const load: PageServerLoad = async ({ url, request }) => {
)}/self-service/registration/browser?${initFlowQuery.toString()}`; )}/self-service/registration/browser?${initFlowQuery.toString()}`;
return { return {
nodes: login_flow.ui.nodes,
KRATOS_PUBLIC_URL: KRATOS_PUBLIC_URL, KRATOS_PUBLIC_URL: KRATOS_PUBLIC_URL,
flow: login_flow as SelfServiceLoginFlow, flow: login_flow as SelfServiceLoginFlow,
title: !(login_flow.refresh || login_flow.requested_aal === 'aal2') title: !(login_flow.refresh || login_flow.requested_aal === 'aal2')

View file

@ -1,83 +1,21 @@
<script lang="ts"> <script lang="ts">
import KratosForm from '$lib/KratosForm.svelte';
import type { PageData } from './$types'; import type { PageData } from './$types';
export let data: PageData; export let data: PageData;
</script> </script>
<div class="flex min-h-screen justify-center"> <div class="flex min-h-screen justify-center">
<form <div class="place-self-center space-y-2 max-w-sm">
action={data.flow.ui.action}
method={data.flow.ui.method}
class="place-self-center form-control space-y-2 max-w-sm"
>
<h1 class="text-lg font-bold">{data.title}</h1> <h1 class="text-lg font-bold">{data.title}</h1>
{#if data.subtitle} {#if data.subtitle}
<h1 class="text-lg">{data.subtitle}</h1> <h1 class="text-lg">{data.subtitle}</h1>
{/if} {/if}
{#if data.flow.ui.messages} <KratosForm ui={data.flow.ui} />
{#each data.flow.ui.messages as message}
<div class="alert alert-error">
<div>
<svg
xmlns="http://www.w3.org/2000/svg"
class="stroke-current flex-shrink-0 h-6 w-6"
fill="none"
viewBox="0 0 24 24"
><path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M10 14l2-2m0 0l2-2m-2 2l-2-2m2 2l2 2m7-2a9 9 0 11-18 0 9 9 0 0118 0z"
/></svg
>
<span>{message.text}</span>
</div>
</div>
{/each}
{/if}
{#each data.nodes as node}
<!-- <code>{JSON.stringify(node)}</code> -->
{#if node.attributes.type == 'submit'}
<button class="btn btn-primary" {...node.attributes}>{node.meta.label.text}</button>
{:else if node.meta.label}
<div class="form-control">
<label class="label" for={node.attributes.name}>
<span class="label-text">{node.meta.label.text}</span>
</label>
{#if node.attributes.type == 'text' || node.attributes.type == 'password'}
<input class="input input-bordered" id={node.attributes.name} {...node.attributes} />
{:else}
<input id={node.attributes.name} {...node.attributes} />
{/if}
</div>
{:else}
<input {...node.attributes} />
{/if}
{#each node.messages as message}
<div class="alert alert-error">
<div>
<svg
xmlns="http://www.w3.org/2000/svg"
class="stroke-current flex-shrink-0 h-6 w-6"
fill="none"
viewBox="0 0 24 24"
><path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M10 14l2-2m0 0l2-2m-2 2l-2-2m2 2l2 2m7-2a9 9 0 11-18 0 9 9 0 0118 0z"
/></svg
>
<span>{message.text}</span>
</div>
</div>
{/each}
{/each}
{#if data.title == 'Two-Factor Authentication'} {#if data.title == 'Two-Factor Authentication'}
<a class="text-xs" href={data.logoutURL}>Log out</a> <a class="text-xs" href={data.logoutURL}>Log out</a>
{:else} {:else}
<a class="text-xs" href={data.forgotPasswordURL}>Forgot password?</a> <a class="text-xs" href={data.forgotPasswordURL}>Forgot password?</a><br />
<a class="text-xs" href={data.signupURL}>Sign up instead</a> <a class="text-xs" href={data.signupURL}>Sign up instead</a>
{/if} {/if}
</form> </div>
<script src="{data.KRATOS_PUBLIC_URL}/.well-known/ory/webauthn.js" async></script>
</div> </div>

View file

@ -33,7 +33,6 @@ export const load: PageServerLoad = async ({ url, request }) => {
}).toString()}`; }).toString()}`;
return { return {
nodes: recovery_flow.ui.nodes,
KRATOS_PUBLIC_URL: KRATOS_PUBLIC_URL, KRATOS_PUBLIC_URL: KRATOS_PUBLIC_URL,
flow: recovery_flow, flow: recovery_flow,
loginURL: initLoginUrl loginURL: initLoginUrl

View file

@ -1,57 +1,18 @@
<script lang="ts"> <script lang="ts">
import KratosForm from '$lib/KratosForm.svelte';
import type { PageData } from './$types'; import type { PageData } from './$types';
export let data: PageData; export let data: PageData;
</script> </script>
<div class="flex min-h-screen justify-center"> <div class="flex min-h-screen justify-center">
<form <div
action={data.flow.ui.action} action={data.flow.ui.action}
method={data.flow.ui.method} method={data.flow.ui.method}
class="place-self-center form-control space-y-2 max-w-sm" class="place-self-center space-y-2 max-w-sm"
> >
<h1 class="text-lg font-bold">Recover Account</h1> <h1 class="text-lg font-bold">Recover Account</h1>
{#if data.flow.ui.messages} <KratosForm ui={data.flow.ui} />
{#each data.flow.ui.messages as message}
<div class="alert alert-error">
<div>
<svg
xmlns="http://www.w3.org/2000/svg"
class="stroke-current flex-shrink-0 h-6 w-6"
fill="none"
viewBox="0 0 24 24"
><path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M10 14l2-2m0 0l2-2m-2 2l-2-2m2 2l2 2m7-2a9 9 0 11-18 0 9 9 0 0118 0z"
/></svg
>
<span>{message.text}</span>
</div>
</div>
{/each}
{/if}
{#each data.nodes as node}
<!-- <code>{JSON.stringify(node)}</code> -->
{#if node.type == 'a'}
<a class="btn btn-primary" {...node.attributes}>{node.meta.label?.text}</a>
{:else if node.attributes.type == 'submit'}
<button class="btn btn-primary" {...node.attributes}>{node.meta.label?.text}</button>
{:else if node.meta.label}
<div class="form-control">
<label class="label" for={node.attributes.name}>
<span class="label-text">{node.meta.label.text}</span>
</label>
{#if node.attributes.type == 'text' || node.attributes.type == 'password' || node.attributes.type == 'email'}
<input class="input input-bordered" id={node.attributes.name} {...node.attributes} />
{:else}
<input id={node.attributes.name} {...node.attributes} />
{/if}
</div>
{:else}
<input {...node.attributes} />
{/if}
{/each}
<a class="text-xs" href={data.loginURL}>Sign up</a> <a class="text-xs" href={data.loginURL}>Sign up</a>
</form> </div>
</div> </div>

View file

@ -46,7 +46,6 @@ export const load: PageServerLoad = async ({ url, request }) => {
)}/self-service/login/browser?${initFlowQuery.toString()}`; )}/self-service/login/browser?${initFlowQuery.toString()}`;
return { return {
nodes: registration_flow.ui.nodes,
KRATOS_PUBLIC_URL: KRATOS_PUBLIC_URL, KRATOS_PUBLIC_URL: KRATOS_PUBLIC_URL,
flow: registration_flow as SelfServiceRegistrationFlow, flow: registration_flow as SelfServiceRegistrationFlow,
title: 'Register Account', title: 'Register Account',

View file

@ -1,78 +1,16 @@
<script lang="ts"> <script lang="ts">
import KratosForm from '$lib/KratosForm.svelte';
import type { PageData } from '../../../.svelte-kit/types/src/routes/signup/$types'; import type { PageData } from '../../../.svelte-kit/types/src/routes/signup/$types';
export let data: PageData; export let data: PageData;
</script> </script>
<div class="flex min-h-screen justify-center"> <div class="flex min-h-screen justify-center">
<form <div class="place-self-center space-y-2 max-w-sm">
action={data.flow.ui.action}
method={data.flow.ui.method}
class="place-self-center form-control space-y-2 max-w-sm"
>
<h1 class="text-lg font-bold">{data.title}</h1> <h1 class="text-lg font-bold">{data.title}</h1>
{#if data.subtitle} {#if data.subtitle}
<h1 class="text-lg">{data.subtitle}</h1> <h1 class="text-lg">{data.subtitle}</h1>
{/if} {/if}
{#if data.flow.ui.messages} <KratosForm ui={data.flow.ui} />
{#each data.flow.ui.messages as message} <a class="text-xs" href={data.loginURL}>Log in instead</a>
<div class="alert alert-error">
<div>
<svg
xmlns="http://www.w3.org/2000/svg"
class="stroke-current flex-shrink-0 h-6 w-6"
fill="none"
viewBox="0 0 24 24"
><path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M10 14l2-2m0 0l2-2m-2 2l-2-2m2 2l2 2m7-2a9 9 0 11-18 0 9 9 0 0118 0z"
/></svg
>
<span>{message.text}</span>
</div> </div>
</div>
{/each}
{/if}
{#each data.nodes as node}
<!-- <code>{JSON.stringify(node)}</code> -->
{#if node.attributes.type == 'submit'}
<button class="btn btn-primary" {...node.attributes}>{node.meta.label.text}</button>
{:else if node.meta.label}
<div class="form-control">
<label class="label" for={node.attributes.name}>
<span class="label-text">{node.meta.label.text}</span>
</label>
{#if node.attributes.type == 'text' || node.attributes.type == 'password' || node.attributes.type == 'email'}
<input class="input input-bordered" id={node.attributes.name} {...node.attributes} />
{:else}
<input id={node.attributes.name} {...node.attributes} />
{/if}
</div>
{:else}
<input {...node.attributes} />
{/if}
{#each node.messages as message}
<div class="alert alert-error">
<div>
<svg
xmlns="http://www.w3.org/2000/svg"
class="stroke-current flex-shrink-0 h-6 w-6"
fill="none"
viewBox="0 0 24 24"
><path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M10 14l2-2m0 0l2-2m-2 2l-2-2m2 2l2 2m7-2a9 9 0 11-18 0 9 9 0 0118 0z"
/></svg
>
<span>{message.text}</span>
</div>
</div>
{/each}
{/each}
<a class="text-xs" href={data.loginURL}>Log out</a>
</form>
<script src="{data.KRATOS_PUBLIC_URL}/.well-known/ory/webauthn.js" async></script>
</div> </div>

View file

@ -34,7 +34,6 @@ export const load: PageServerLoad = async ({ url, request }) => {
}).toString()}`; }).toString()}`;
return { return {
nodes: verification_flow.ui.nodes,
KRATOS_PUBLIC_URL: KRATOS_PUBLIC_URL, KRATOS_PUBLIC_URL: KRATOS_PUBLIC_URL,
flow: verification_flow, flow: verification_flow,
signupURL: initRegistrationUrl signupURL: initRegistrationUrl

View file

@ -1,57 +1,13 @@
<script lang="ts"> <script lang="ts">
import KratosForm from '$lib/KratosForm.svelte';
import type { PageData } from './$types'; import type { PageData } from './$types';
export let data: PageData; export let data: PageData;
</script> </script>
<div class="flex min-h-screen justify-center"> <div class="flex min-h-screen justify-center">
<form <div class="place-self-center space-y-2 max-w-sm">
action={data.flow.ui.action}
method={data.flow.ui.method}
class="place-self-center form-control space-y-2 max-w-sm"
>
<h1 class="text-lg font-bold">Verify Account</h1> <h1 class="text-lg font-bold">Verify Account</h1>
{#if data.flow.ui.messages} <KratosForm ui={data.flow.ui} />
{#each data.flow.ui.messages as message}
<div class="alert alert-error">
<div>
<svg
xmlns="http://www.w3.org/2000/svg"
class="stroke-current flex-shrink-0 h-6 w-6"
fill="none"
viewBox="0 0 24 24"
><path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M10 14l2-2m0 0l2-2m-2 2l-2-2m2 2l2 2m7-2a9 9 0 11-18 0 9 9 0 0118 0z"
/></svg
>
<span>{message.text}</span>
</div>
</div>
{/each}
{/if}
{#each data.nodes as node}
<!-- <code>{JSON.stringify(node)}</code> -->
{#if node.type == 'a'}
<a class="btn btn-primary" {...node.attributes}>{node.meta.label?.text}</a>
{:else if node.attributes.type == 'submit'}
<button class="btn btn-primary" {...node.attributes}>{node.meta.label?.text}</button>
{:else if node.meta.label}
<div class="form-control">
<label class="label" for={node.attributes.name}>
<span class="label-text">{node.meta.label.text}</span>
</label>
{#if node.attributes.type == 'text' || node.attributes.type == 'password' || node.attributes.type == 'email'}
<input class="input input-bordered" id={node.attributes.name} {...node.attributes} />
{:else}
<input id={node.attributes.name} {...node.attributes} />
{/if}
</div>
{:else}
<input {...node.attributes} />
{/if}
{/each}
<a class="text-xs" href={data.signupURL}>Sign up</a> <a class="text-xs" href={data.signupURL}>Sign up</a>
</form> </div>
</div> </div>