-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat!: implement auth and navigation guard
- Loading branch information
1 parent
62aa634
commit 847a4fc
Showing
12 changed files
with
212 additions
and
8 deletions.
There are no files selected for viewing
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
import type { PageServerLoad } from './$types' | ||
|
||
export const load: PageServerLoad = async ({ locals: { supabase } }) => { | ||
const { data: countries } = await supabase | ||
.from('countries') | ||
.select('name') | ||
.limit(5) | ||
.order('name') | ||
return { countries: countries ?? [] } | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,22 @@ | ||
<h1 class="text-center text-3xl font-bold underline"> | ||
Hello world! | ||
</h1> | ||
<button class="btn btn-primary size-full h-full | ||
text-3xl text-white" | ||
> | ||
BIG HELLO | ||
</button> | ||
<script> | ||
export let data | ||
$: ({countries} = data) | ||
</script> | ||
<div class="size-full flex flex-col justify-center items-center gap-4"> | ||
<h1 class="text-center text-3xl font-bold underline"> | ||
Supavelte! | ||
</h1> | ||
<div class="flex flex-col gap-4"> | ||
<a class="btn btn-primary w-full" href="/auth"> | ||
Authenticate | ||
</a> | ||
<a class="btn btn-outline w-full" href="/private"> | ||
Private | ||
</a> | ||
</div> | ||
<ul> | ||
{#each countries as country} | ||
<li>{country.name}</li> | ||
{/each} | ||
</ul> | ||
</div> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
import type { EmailOtpType } from "@supabase/supabase-js" | ||
import { redirect } from "@sveltejs/kit" | ||
import type { RequestHandler } from "./$types" | ||
|
||
export const GET: RequestHandler = async ({ url, locals: { supabase } }) => { | ||
const token_hash = url.searchParams.get("token_hash") | ||
const type = url.searchParams.get("type") as EmailOtpType | null | ||
const next = url.searchParams.get("next") ?? "/" | ||
|
||
/** | ||
* Clean up the redirect URL by deleting the Auth flow parameters. | ||
* | ||
* `next` is preserved for now, because it"s needed in the error case. | ||
*/ | ||
const redirectTo = new URL(url) | ||
redirectTo.pathname = next | ||
redirectTo.searchParams.delete("token_hash") | ||
redirectTo.searchParams.delete("type") | ||
|
||
if (token_hash && type) { | ||
const { error } = await supabase.auth.verifyOtp({ type, token_hash }) | ||
if (!error) { | ||
redirectTo.searchParams.delete("next") | ||
return redirect(303, redirectTo) | ||
} | ||
} | ||
|
||
redirectTo.pathname = "/auth/error" | ||
return redirect(303, redirectTo) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
<header> | ||
<nav> | ||
<a href="/">Home</a> | ||
</nav> | ||
</header> | ||
<slot/> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
import { redirect } from "@sveltejs/kit" | ||
|
||
import type { Actions } from './$types' | ||
|
||
export const actions: Actions = { | ||
signup: async ({ request, locals: { supabase } }) => { | ||
const formData = await request.formData() | ||
const email = formData.get("email") as string | ||
const password = formData.get("password") as string | ||
|
||
const { error } = await supabase.auth.signUp({ email, password }) | ||
if (error) { | ||
console.error(error) | ||
return redirect(303, "/auth/error") | ||
} else { | ||
return redirect(303, "/") | ||
} | ||
}, | ||
login: async ({ request, locals: { supabase } }) => { | ||
const formData = await request.formData() | ||
const email = formData.get("email") as string | ||
const password = formData.get("password") as string | ||
|
||
const { error } = await supabase.auth.signInWithPassword({ email, password }) | ||
if (error) { | ||
console.error(error) | ||
return redirect(303, "/auth/error") | ||
} else { | ||
return redirect(303, "/private") | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
<div class="size-full flex flex-col justify-center items-center gap-8"> | ||
<form action="?/login" class="flex flex-col gap-2 bg-base-300 rounded-box px-10 py-8 shadow-2xl" | ||
method="POST" | ||
> | ||
<label class="input input-bordered flex items-center gap-2"> | ||
<svg class="w-4 h-4 opacity-70" fill="currentColor" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"> | ||
<path | ||
d="M2.5 3A1.5 1.5 0 0 0 1 4.5v.793c.026.009.051.02.076.032L7.674 8.51c.206.1.446.1.652 0l6.598-3.185A.755.755 0 0 1 15 5.293V4.5A1.5 1.5 0 0 0 13.5 3h-11Z"/> | ||
<path | ||
d="M15 6.954 8.978 9.86a2.25 2.25 0 0 1-1.956 0L1 6.954V11.5A1.5 1.5 0 0 0 2.5 13h11a1.5 1.5 0 0 0 1.5-1.5V6.954Z"/> | ||
</svg> | ||
<input class="grow" | ||
name="email" | ||
placeholder="example@gmail.com" | ||
type="email" | ||
/> | ||
</label> | ||
<label class="input input-bordered flex items-center gap-2"> | ||
<svg class="w-4 h-4 opacity-70" fill="currentColor" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"> | ||
<path clip-rule="evenodd" | ||
d="M14 6a4 4 0 0 1-4.899 3.899l-1.955 1.955a.5.5 0 0 1-.353.146H5v1.5a.5.5 0 0 1-.5.5h-2a.5.5 0 0 1-.5-.5v-2.293a.5.5 0 0 1 .146-.353l3.955-3.955A4 4 0 1 1 14 6Zm-4-2a.75.75 0 0 0 0 1.5.5.5 0 0 1 .5.5.75.75 0 0 0 1.5 0 2 2 0 0 0-2-2Z" | ||
fill-rule="evenodd"/> | ||
</svg> | ||
<input class="grow" | ||
name="password" | ||
type="password" | ||
/> | ||
</label> | ||
<div class="divider my-0"></div> | ||
<button class="btn btn-primary text-white" formaction="?/signup"> | ||
Continue | ||
</button> | ||
</form> | ||
</div> | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
<p>Login error</p> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
/** | ||
* This file is necessary to ensure protection of all routes in the `private` | ||
* directory. It makes the routes in this directory _dynamic_ routes, which | ||
* send a server request, and thus trigger `hooks.server.ts`. | ||
**/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
<script> | ||
export let data | ||
$: ({ supabase } = data) | ||
$: logout = async () => { | ||
const { error } = await supabase.auth.signOut() | ||
if (error) { | ||
console.error(error) | ||
} | ||
} | ||
</script> | ||
|
||
<header> | ||
<nav> | ||
<a href="/">Home</a> | ||
</nav> | ||
<button on:click={logout}>Logout</button> | ||
</header> | ||
<main> | ||
<slot /> | ||
</main> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
import type { PageServerLoad } from "./$types" | ||
|
||
export const load: PageServerLoad = async ({ depends, locals: { supabase } }) => { | ||
depends("supabase:db:notes") | ||
const { data: notes } = await supabase | ||
.from("notes") | ||
.select("id,note") | ||
.order("id") | ||
return { notes: notes ?? [] } | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
<script lang="ts"> | ||
import { invalidate } from "$app/navigation" | ||
import type { EventHandler } from "svelte/elements" | ||
import type { PageData } from "./$types" | ||
export let data: PageData | ||
$: ({ notes, supabase, user } = data) | ||
let handleSubmit: EventHandler<SubmitEvent, HTMLFormElement> | ||
$: handleSubmit = async (evt) => { | ||
evt.preventDefault() | ||
if (!evt.target) return | ||
const form = evt.target as HTMLFormElement | ||
const note = (new FormData(form).get("note") ?? "") as string | ||
if (!note) return | ||
const { error } = await supabase.from("notes").insert({ note }) | ||
if (error) console.error(error) | ||
await invalidate("supabase:db:notes") | ||
form.reset() | ||
} | ||
</script> | ||
|
||
<h1>Private page for user: {user?.email}</h1> | ||
<h2>Notes</h2> | ||
<ul> | ||
{#each notes as note} | ||
<li>{note.note}</li> | ||
{/each} | ||
</ul> | ||
<form on:submit={handleSubmit}> | ||
<label> | ||
Add a note | ||
<input name="note" type="text" /> | ||
</label> | ||
</form> |