mirror of
https://github.com/bartvdbraak/omnidash.git
synced 2025-04-27 07:21:20 +00:00
Merge pull request #226 from bartvdbraak/safari-support
Refactor OAuth2Form component
This commit is contained in:
commit
f90f4f42ef
5 changed files with 53 additions and 82 deletions
|
@ -1,3 +1,3 @@
|
|||
export { default as LoginForm } from './login-form.svelte';
|
||||
export { default as RegisterForm } from './register-form.svelte';
|
||||
export { default as SSOForm } from './sso-form.svelte';
|
||||
export { default as Oauth2Form } from './oauth2-form.svelte';
|
||||
|
|
|
@ -14,7 +14,6 @@
|
|||
import SuperDebug from 'sveltekit-superforms';
|
||||
import { zodClient } from 'sveltekit-superforms/adapters';
|
||||
import { browser, dev } from '$app/environment';
|
||||
// import { PUBLIC_DEBUG_FORMS } from '$env/static/public';
|
||||
import { toast } from 'svelte-sonner';
|
||||
import { Icons } from '$lib/components/site';
|
||||
import { cn } from '$lib/utils';
|
||||
|
@ -31,12 +30,22 @@
|
|||
},
|
||||
onUpdated: ({ form: f }) => {
|
||||
isLoading = false;
|
||||
if (f.valid) {
|
||||
toast.success('Succesfully logged in.');
|
||||
} else {
|
||||
if (!f.valid) {
|
||||
toast.error('Please fix the errors.');
|
||||
}
|
||||
},
|
||||
onError: (e) => {
|
||||
toast.error(e.result.error.message);
|
||||
},
|
||||
onResult: (e) => {
|
||||
if (e.result.status === 303) {
|
||||
toast.success('Logged in successfully.');
|
||||
} else {
|
||||
console.log(e)
|
||||
toast.error('Invalid credentials.');
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
const { form: formData, enhance } = form;
|
||||
|
|
|
@ -1,49 +1,14 @@
|
|||
<script lang="ts" context="module">
|
||||
import { z } from 'zod';
|
||||
export const ssoFormSchema = z.object({
|
||||
token: z.string()
|
||||
});
|
||||
export type SsoFormSchema = typeof ssoFormSchema;
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
import * as Form from '$lib/components/ui/form';
|
||||
import { Input } from '$lib/components/ui/input';
|
||||
import { type SuperValidated, type Infer, superForm } from 'sveltekit-superforms';
|
||||
import SuperDebug from 'sveltekit-superforms';
|
||||
import { zodClient } from 'sveltekit-superforms/adapters';
|
||||
import { browser, dev } from '$app/environment';
|
||||
import { toast } from 'svelte-sonner';
|
||||
import { Icons } from '$lib/components/site';
|
||||
import PocketBase from 'pocketbase';
|
||||
import { PUBLIC_CLIENT_PB } from '$env/static/public';
|
||||
import { enhance } from '$app/forms';
|
||||
import { Button } from '$lib/components/ui/button';
|
||||
import { Separator } from '$lib/components/ui/separator';
|
||||
import * as DropdownMenu from '$lib/components/ui/dropdown-menu';
|
||||
import { ChevronDown } from 'radix-icons-svelte';
|
||||
import { debugForms } from '$lib/config/site';
|
||||
|
||||
export let data: SuperValidated<Infer<SsoFormSchema>>;
|
||||
let isLoading = false;
|
||||
|
||||
const form = superForm(data, {
|
||||
validators: zodClient(ssoFormSchema),
|
||||
onSubmit: () => {
|
||||
isLoading = true;
|
||||
toast.loading('Logging in...');
|
||||
},
|
||||
onUpdated: ({ form: f }) => {
|
||||
isLoading = false;
|
||||
if (f.valid) {
|
||||
toast.success('Succesfully logged in.');
|
||||
} else {
|
||||
toast.error('Please fix the errors.');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
const { form: formData, enhance } = form;
|
||||
|
||||
export let isLoading = false;
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
export let providers: { name: string; icon?: any; displayName: string }[];
|
||||
let currentProvider = providers[0];
|
||||
|
@ -52,7 +17,13 @@
|
|||
let oauth2Form: HTMLFormElement;
|
||||
async function loginWithOauth2(provider: string) {
|
||||
try {
|
||||
await pb.collection('users').authWithOAuth2({ provider });
|
||||
let w = window.open();
|
||||
await pb.collection('users').authWithOAuth2({
|
||||
provider: provider,
|
||||
urlCallback: (url) => {
|
||||
if (w) w.location.href = url;
|
||||
}
|
||||
});
|
||||
const input = document.createElement('input');
|
||||
input.type = 'hidden';
|
||||
input.name = 'token';
|
||||
|
@ -65,14 +36,26 @@
|
|||
}
|
||||
</script>
|
||||
|
||||
<form method="POST" action="?/sso" class="grid gap-2" use:enhance>
|
||||
<Form.Field {form} name="token" class="grid gap-2">
|
||||
<Form.Control let:attrs>
|
||||
<Input {...attrs} bind:value={$formData.token} class="hidden" />
|
||||
</Form.Control>
|
||||
<Form.FieldErrors />
|
||||
</Form.Field>
|
||||
|
||||
<form
|
||||
method="POST"
|
||||
action="?/oauth2"
|
||||
bind:this={oauth2Form}
|
||||
use:enhance={() => {
|
||||
isLoading = true;
|
||||
return async ({ update }) => {
|
||||
isLoading = false;
|
||||
update();
|
||||
};
|
||||
}}
|
||||
>
|
||||
<div class="relative">
|
||||
<div class="absolute inset-0 flex items-center">
|
||||
<span class="w-full border-t" />
|
||||
</div>
|
||||
<div class="relative flex justify-center text-xs uppercase">
|
||||
<span class="bg-background px-2 py-4 text-muted-foreground"> Or continue with </span>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="flex items-center justify-between whitespace-nowrap rounded-md border border-input bg-transparent shadow-sm transition-colors hover:bg-accent hover:text-accent-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50"
|
||||
>
|
||||
|
@ -137,9 +120,3 @@
|
|||
{/if}
|
||||
</div>
|
||||
</form>
|
||||
|
||||
{#if dev && debugForms && browser}
|
||||
<div class="pt-4">
|
||||
<SuperDebug data={$formData} />
|
||||
</div>
|
||||
{/if}
|
|
@ -3,14 +3,12 @@ import { superValidate } from 'sveltekit-superforms';
|
|||
import { zod } from 'sveltekit-superforms/adapters';
|
||||
import { loginFormSchema } from './(components)/login-form.svelte';
|
||||
import { registerFormSchema } from './(components)/register-form.svelte';
|
||||
import { ssoFormSchema } from './(components)/sso-form.svelte';
|
||||
import { fail, type Actions, redirect } from '@sveltejs/kit';
|
||||
|
||||
export const load: PageServerLoad = async () => {
|
||||
return {
|
||||
loginForm: await superValidate(zod(loginFormSchema)),
|
||||
registerForm: await superValidate(zod(registerFormSchema)),
|
||||
ssoForm: await superValidate(zod(ssoFormSchema))
|
||||
registerForm: await superValidate(zod(registerFormSchema))
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -54,26 +52,13 @@ export const actions: Actions = {
|
|||
});
|
||||
}
|
||||
},
|
||||
sso: async ({ request, cookies }) => {
|
||||
const form = await superValidate(request, zod(ssoFormSchema));
|
||||
if (!form.valid) {
|
||||
return fail(400, {
|
||||
form
|
||||
});
|
||||
}
|
||||
const token = form.data.token;
|
||||
try {
|
||||
if (!token || typeof token !== 'string') {
|
||||
throw redirect(303, '/auth');
|
||||
}
|
||||
cookies.set('pb_auth', JSON.stringify({ token: token }), { path: '/' });
|
||||
return {
|
||||
form
|
||||
};
|
||||
} catch (err) {
|
||||
return fail(500, {
|
||||
form
|
||||
});
|
||||
oauth2: async ({ request, cookies }) => {
|
||||
const form = await request.formData();
|
||||
const token = form.get('token');
|
||||
if (!token || typeof token !== 'string') {
|
||||
throw redirect(303, '/auth');
|
||||
}
|
||||
cookies.set('pb_auth', JSON.stringify({ token: token }), { path: '/' });
|
||||
throw redirect(303, '/');
|
||||
}
|
||||
};
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
import { Icons } from '$lib/components/site/index.js';
|
||||
import * as Tabs from '$lib/components/ui/tabs';
|
||||
import type { PageData } from './$types.js';
|
||||
import { LoginForm, RegisterForm, SSOForm } from './(components)';
|
||||
import { LoginForm, RegisterForm, Oauth2Form } from './(components)';
|
||||
|
||||
export let data: PageData;
|
||||
|
||||
|
@ -37,7 +37,7 @@
|
|||
Forgot password? <a class="text-primary underline" href="/reset-password">Reset password.</a>
|
||||
</p>
|
||||
{#if providers.length}
|
||||
<SSOForm data={data.ssoForm} providers={providersWithIcons} />
|
||||
<Oauth2Form providers={providersWithIcons} />
|
||||
{/if}
|
||||
</Tabs.Root>
|
||||
</div>
|
||||
|
|
Loading…
Reference in a new issue