Fix login page endpoint, implement session passing, redirect on protected routes and login.

This commit is contained in:
Bradley Shellnut 2022-05-12 23:19:30 -07:00
parent 4672da6f4a
commit f9aae20f91
7 changed files with 170 additions and 93 deletions

8
src/app.d.ts vendored
View file

@ -3,8 +3,12 @@
// See https://kit.svelte.dev/docs/types#app // See https://kit.svelte.dev/docs/types#app
// for information about these interfaces // for information about these interfaces
declare namespace App { declare namespace App {
// interface Locals {} interface Locals {
user?: { username: string }
}
// interface Platform {} // interface Platform {}
// interface Session {} interface Session {
user?: { username: string }
}
// interface Stuff {} // interface Stuff {}
} }

33
src/hooks.ts Normal file
View file

@ -0,0 +1,33 @@
import type { GetSession, Handle } from "@sveltejs/kit"
import * as cookie from 'cookie'
import { db } from '$lib/database'
export const handle: Handle = async ({ event, resolve }) => {
const cookieHeader = event.request.headers.get('cookie')
const cookies = cookie.parse(cookieHeader ?? '')
if (!cookies.session) {
return await resolve(event)
}
const session = await db.user.findUnique({
where: { id: cookies.session },
})
if (session) {
event.locals.user = { username: session.username }
}
return await resolve(event)
}
export const getSession: GetSession = ({ locals }) => {
if (!locals.user) return {}
return {
user: {
username: locals.user.username
}
}
}

View file

@ -8,8 +8,7 @@ export async function send(form: HTMLFormElement): Send {
const response = await fetch(form.action, { const response = await fetch(form.action, {
method: form.method, method: form.method,
body: new FormData(form), body: new FormData(form),
headers: { accept: 'application/json' } headers: { accept: 'application/json' },
}) })
return await response.json() return await response.json()
} }

View file

@ -1,57 +1,57 @@
<script lang="ts"> <script context="module" lang="ts">
import { session } from '$app/stores' export const load: Load = ({ session, props }) => {
import { send } from '$lib/api' if (session.user) {
return {
status: 302,
redirect: '/'
};
}
export let error: string return { props };
};
async function login(event: SubmitEvent) {
const formEl = event.target as HTMLFormElement
const response = await send(formEl)
if (response.error) {
error = response.error
}
$session.user = response.user
formEl.reset()
}
</script> </script>
<form <script lang="ts">
on:submit|preventDefault={login} import { session } from '$app/stores';
method="post" import { send } from '$lib/api';
autocomplete="off" import type { Load } from '@sveltejs/kit';
>
<div>
<label for="username">Username</label>
<input
id="username"
name="username"
type="username"
required
/>
</div>
<div> export let error: string;
<label for="password">Password</label>
<input
id="password"
name="password"
type="password"
required
/>
</div>
{#if error} async function login(event: SubmitEvent) {
<p class="error">{error}</p> const formEl = event.target as HTMLFormElement;
{/if} const response = await send(formEl);
<button type="submit">Sign In</button> if (response.error) {
error = response.error;
}
$session.user = response.user;
formEl.reset();
}
</script>
<form on:submit|preventDefault={login} method="post" autocomplete="off">
<div>
<label for="username">Username</label>
<input id="username" name="username" type="username" required />
</div>
<div>
<label for="password">Password</label>
<input id="password" name="password" type="password" required />
</div>
{#if error}
<p class="error">{error}</p>
{/if}
<button type="submit">Sign In</button>
</form> </form>
<style> <style>
.error { .error {
color: tomato; color: tomato;
} }
</style> </style>

View file

@ -7,9 +7,7 @@ import { db } from '$lib/database'
export const post: RequestHandler = async ({ request }) => { export const post: RequestHandler = async ({ request }) => {
const form = await request.formData() const form = await request.formData()
const username = form.get('username') const username = form.get('username')
console.log('username', username);
const password = form.get('password') const password = form.get('password')
console.log('password', password);
if ( if (
typeof username !== 'string' || typeof username !== 'string' ||

View file

@ -1,55 +1,71 @@
<script context="module" lang="ts">
export const load: Load = ({ session, props }) => {
if (session.user) {
return {
status: 302,
redirect: '/'
};
}
return { props };
};
</script>
<script type="ts"> <script type="ts">
import {send} from '$lib/api'; import { send } from '$lib/api';
import type { Load } from '@sveltejs/kit';
export let error: string; export let error: string;
export let success: string; export let success: string;
async function register(event: SubmitEvent) { async function register(event: SubmitEvent) {
error = '' error = '';
const formEl = event.target as HTMLFormElement const formEl = event.target as HTMLFormElement;
const response = await send(formEl) const response = await send(formEl);
if (response.error) { if (response.error) {
error = response.error error = response.error;
} }
if (response.success) { if (response.success) {
success = response.success success = response.success;
} }
formEl.reset() formEl.reset();
} }
</script> </script>
<form on:submit|preventDefault={register} method="post" autocomplete="off"> <form on:submit|preventDefault={register} method="post" autocomplete="off">
<div> <div>
<label for="username">Username <label for="username"
<input id="username" name="username" type="text" required /> >Username
</label> <input id="username" name="username" type="text" required />
</div> </label>
<div> </div>
<label for="password">Password <div>
<input id="password" name="password" type="password" required /> <label for="password"
</label> >Password
</div> <input id="password" name="password" type="password" required />
</label>
</div>
{#if error} {#if error}
<p class="error">{error}</p> <p class="error">{error}</p>
{/if} {/if}
{#if success} {#if success}
<div> <div>
<p>Thank you for signing up!</p> <p>Thank you for signing up!</p>
<p><a href="/auth/login">You can log in.</a></p> <p><a href="/auth/login">You can log in.</a></p>
</div> </div>
{/if} {/if}
<button type="submit">Sign Up</button> <button type="submit">Sign Up</button>
</form> </form>
<style> <style>
.error { .error {
color: tomato; color: tomato;
} }
</style> </style>

View file

@ -0,0 +1,27 @@
<script context="module" lang="ts">
import type { Load } from '@sveltejs/kit';
export const load: Load = ({ session }) => {
if (!session.user) {
return {
status: 302,
redirect: '/auth/login'
};
}
return {
status: 200,
props: {
user: session.user.username
}
};
};
</script>
<script lang="ts">
export let user: string;
</script>
<h1>Protected</h1>
<p>Weclome {user}</p>