feat(#9): Add sign up

This commit is contained in:
Josh Creek
2024-04-06 21:10:37 +01:00
parent d55dcb066d
commit 496cdb6666
10 changed files with 327 additions and 8 deletions
+45 -5
View File
@@ -1,9 +1,49 @@
import { PUBLIC_SUPABASE_URL, PUBLIC_SUPABASE_ANON_KEY } from '$env/static/public';
import { createServerClient } from '@supabase/ssr';
import type { Handle } from '@sveltejs/kit';
import { dbConnect } from '$lib/utils/db';
await dbConnect();
export const handle: Handle = async ({ event, resolve }) => {
const response = await resolve(event);
return response;
event.locals.supabase = createServerClient(PUBLIC_SUPABASE_URL, PUBLIC_SUPABASE_ANON_KEY, {
cookies: {
get: (key) => event.cookies.get(key),
/**
* Note: You have to add the `path` variable to the
* set and remove method due to sveltekit's cookie API
* requiring this to be set, setting the path to an empty string
* will replicate previous/standard behaviour (https://kit.svelte.dev/docs/types#public-types-cookies)
*/
set: (key, value, options) => {
event.cookies.set(key, value, { ...options, path: '/' });
},
remove: (key, options) => {
event.cookies.delete(key, { ...options, path: '/' });
}
}
});
/**
* Unlike `supabase.auth.getSession`, which is unsafe on the server because it
* doesn't validate the JWT, this function validates the JWT by first calling
* `getUser` and aborts early if the JWT signature is invalid.
*/
event.locals.safeGetSession = async () => {
const {
data: { user },
error
} = await event.locals.supabase.auth.getUser();
if (error) {
return { session: null, user: null };
}
const {
data: { session }
} = await event.locals.supabase.auth.getSession();
return { session, user };
};
return resolve(event, {
filterSerializedResponseHeaders(name) {
return name === 'content-range';
}
});
};
+33
View File
@@ -0,0 +1,33 @@
<script lang="ts">
let email = '';
let password = '';
// Access the supabase client from the layout data
export let supabase: any;
async function signUpNewUser() {
try {
const { data, error } = await supabase.auth.signUp({
email: email,
password: password,
options: {
// Redirect URL after successful sign-up
redirectTo: '/welcome'
}
});
if (error) {
throw error;
}
// Handle success (optional)
} catch (error) {
console.error('Sign up error:', error.message);
// Handle error
}
}
</script>
<input type="email" bind:value={email} placeholder="Email" />
<input type="password" bind:value={password} placeholder="Password" />
<button on:click={signUpNewUser}>Sign Up</button>
+10
View File
@@ -0,0 +1,10 @@
import type { LayoutServerLoad } from './$types';
export const load: LayoutServerLoad = async ({ locals: { safeGetSession } }) => {
const { session, user } = await safeGetSession();
return {
session,
user
};
};
+6
View File
@@ -0,0 +1,6 @@
<script lang="ts">
</script>
<main>
<slot />
</main>
+34
View File
@@ -0,0 +1,34 @@
import { PUBLIC_SUPABASE_ANON_KEY, PUBLIC_SUPABASE_URL } from '$env/static/public';
import type { LayoutLoad } from './$types';
import { createBrowserClient, isBrowser, parse } from '@supabase/ssr';
export const load: LayoutLoad = async ({ fetch, data, depends }) => {
depends('supabase:auth');
const supabase = createBrowserClient(PUBLIC_SUPABASE_URL, PUBLIC_SUPABASE_ANON_KEY, {
global: {
fetch
},
cookies: {
get(key) {
if (!isBrowser()) {
return JSON.stringify(data.session);
}
const cookie = parse(document.cookie);
return cookie[key];
}
}
});
/**
* It's fine to use `getSession` here, because on the client, `getSession` is
* safe, and on the server, it reads `session` from the `LayoutData`, which
* safely checked the session using `safeGetSession`.
*/
const {
data: { session }
} = await supabase.auth.getSession();
return { supabase, session };
};
+9 -2
View File
@@ -1,2 +1,9 @@
<h1>Welcome to SvelteKit</h1>
<p>Visit <a href="https://kit.svelte.dev">kit.svelte.dev</a> to read the documentation</p>
<script lang="ts">
import SignUp from '$lib/components/SignUp.svelte';
export let data;
let { supabase } = data;
$: ({ supabase } = data);
</script>
<SignUp {supabase} />
+22
View File
@@ -0,0 +1,22 @@
import { redirect } from '@sveltejs/kit';
import { type EmailOtpType } from '@supabase/supabase-js';
export const GET = async (event) => {
const {
url,
locals: { supabase }
} = event;
const token_hash = url.searchParams.get('token_hash') as string;
const type = url.searchParams.get('type') as EmailOtpType | null;
const next = url.searchParams.get('next') ?? '/';
if (token_hash && type) {
const { error } = await supabase.auth.verifyOtp({ token_hash, type });
if (!error) {
throw redirect(303, `/${next.slice(1)}`);
}
}
// return the user to an error page with some instructions
throw redirect(303, '/auth/auth-code-error');
};