Add user login logout

This commit is contained in:
Esa Kataja
2024-11-19 22:08:38 +02:00
parent c22f44b483
commit 38afd41ca0
15 changed files with 218 additions and 12 deletions
+13 -1
View File
@@ -3,7 +3,19 @@
declare global { declare global {
namespace App { namespace App {
// interface Error {} // interface Error {}
// interface Locals {} interface Locals {
user: {
id: string;
username: string;
email: string;
avatar_url: string;
is_active: boolean;
is_admin: boolean;
last_login: string;
created_at: string;
modified_at: string;
};
}
// interface PageData {} // interface PageData {}
// interface PageState {} // interface PageState {}
// interface Platform {} // interface Platform {}
+18
View File
@@ -0,0 +1,18 @@
import { authenticateUser } from '$lib/server/auth';
import type { Handle } from '@sveltejs/kit';
import { redirect } from '@sveltejs/kit';
export const handle: Handle = async ({ event, resolve }) => {
if (event.url.pathname.startsWith('/gameroom')) {
const current_user = await authenticateUser(event);
if (!current_user) {
throw redirect(302, '/login');
}
event.locals.user = current_user;
}
const response = await resolve(event);
return response;
};
+14 -5
View File
@@ -1,8 +1,13 @@
<script> <script lang="ts">
let { user } = $props();
let room_link: string = $state('/');
if (user) {
room_link = '/gameroom/';
}
</script> </script>
<header <header
class="header bg-primary-FestiveRed-dark mb-10 flex w-full items-center justify-between p-6 drop-shadow-lg" class="header mb-10 flex w-full items-center justify-between bg-primary-FestiveRed-dark p-6 drop-shadow-lg"
> >
<a href="/" aria-label="Paska joululeffa 2024" <a href="/" aria-label="Paska joululeffa 2024"
><enhanced:img ><enhanced:img
@@ -11,11 +16,15 @@
alt="Paska joululeffa 2024" alt="Paska joululeffa 2024"
/></a /></a
> >
<a href="/" aria-label="Shitty Christmas Movie" <a href={room_link} aria-label="Shitty Christmas Movie"
><h1 class="text-primarySnowyWhite-dark text-2xl font-extrabold">Paska Joululeffa 2024</h1> ><h1 class="text-primarySnowyWhite-dark text-2xl font-extrabold">Paska Joululeffa 2024</h1>
</a> </a>
<span> <span>
<a href="/login">Sisään</a> {#if user}
<!-- <button>Ulos</button> --> {user.username}
<a href="/logout" data-sveltekit-preload-data="tap">Ulos</a>
{:else}
<a href="/login">Sisään</a>
{/if}
</span> </span>
</header> </header>
+11 -3
View File
@@ -1,15 +1,22 @@
<script lang="ts"> <script lang="ts">
import { enhance } from '$app/forms'; import { enhance } from '$app/forms';
const backend = import.meta.env.VITE_API_URL;
</script> </script>
<div <div
class="black border-primary-FestiveRed-dark bg-primary-FestiveRed-dark mx-auto flex max-w-sm flex-col gap-8 rounded-xl border-2 p-6 text-center drop-shadow-lg backdrop-blur-md" class="black mx-auto flex max-w-sm flex-col gap-8 rounded-xl border-2 border-primary-FestiveRed-dark bg-primary-FestiveRed-dark p-6 text-center drop-shadow-lg backdrop-blur-md"
> >
<h1 class="text-2xl">Kirjaudu sisään</h1> <h1 class="text-2xl">Kirjaudu sisään</h1>
<form method="POST" action="?/login" class="flex flex-col gap-6" use:enhance> <form method="POST" action="?/login" class="flex flex-col gap-6" use:enhance>
<label for="username">Käyttäjä</label> <label for="username">Käyttäjä</label>
<input type="text" name="username" id="username" class="input-text" required minlength="3" /> <input
type="text"
name="username"
id="username"
class="input-text"
required
minlength="3"
value="admin"
/>
<label for="password">Salasana</label> <label for="password">Salasana</label>
<input <input
type="password" type="password"
@@ -17,6 +24,7 @@
id="password" id="password"
class="input-text" class="input-text"
required required
value="password"
minlength="5" minlength="5"
/> />
<hr class="my-4 border-0" /> <hr class="my-4 border-0" />
+8
View File
@@ -1 +1,9 @@
// place files you want to import through the `$lib` alias in this folder. // place files you want to import through the `$lib` alias in this folder.
export const api_url = "http://localhost:8000";
export function decodeUSerCookie(userCookie: string) {
const decodedCookie = decodeURIComponent(userCookie);
const parsedCookie = JSON.parse(decodedCookie);
return parsedCookie;
}
+28
View File
@@ -0,0 +1,28 @@
import { redirect, type RequestEvent } from '@sveltejs/kit';
export const authenticateUser = (event: RequestEvent) => {
const {cookies} = event;
const userCookie = cookies.get('user');
if (!userCookie) {
return null
}
const decodedCookie = decodeURIComponent(userCookie);
const parsedCookie = JSON.parse(decodedCookie);
if (!parsedCookie) {
return null
}
return parsedCookie
}
export const logoutUser = (event: RequestEvent) => {
const {cookies} = event;
cookies.delete('user', {
path: '/',
sameSite: 'strict',
secure: false,
});
throw redirect(302, '/login');
}
+9
View File
@@ -0,0 +1,9 @@
import type { LayoutServerLoad } from './$types';
import { authenticateUser } from '$lib/server/auth';
export const load: LayoutServerLoad = async (event) => {
const user = await authenticateUser(event);
return {
user: user
};
};
+3 -2
View File
@@ -2,7 +2,8 @@
import '../app.css'; import '../app.css';
import Header from '$lib/components/Header.svelte'; import Header from '$lib/components/Header.svelte';
import Footer from '$lib/components/Footer.svelte'; import Footer from '$lib/components/Footer.svelte';
let { children } = $props(); import type { LayoutData } from './$types';
let { data, children }: { data: LayoutData; children: () => any } = $props();
</script> </script>
<svelte:head> <svelte:head>
@@ -10,7 +11,7 @@
</svelte:head> </svelte:head>
<div class="flex min-h-[100dvh] flex-col"> <div class="flex min-h-[100dvh] flex-col">
<Header /> <Header user={data.user} />
<main class="container mx-auto max-w-4xl flex-grow overflow-hidden"> <main class="container mx-auto max-w-4xl flex-grow overflow-hidden">
{@render children()} {@render children()}
</main> </main>
+33
View File
@@ -0,0 +1,33 @@
import type { PageServerLoad } from "./$types";
import { api_url } from "$lib";
type movie = {
id: string;
name: string;
imdb_id: string;
actors: Array<string>;
plot: string;
poster_url: string;
release_date: string;
showtime: string;
is_watched: boolean;
}
export const load: PageServerLoad = async (event) => {
const get_next_movie_url = `${api_url}/movie/next`;
const response = await fetch(get_next_movie_url);
const data: movie = await response.json();
const year = new Date(data.release_date).getFullYear();
data.release_date = `${year}`;
return {
movie: data,
user: event.locals.user
};
};
+6
View File
@@ -0,0 +1,6 @@
<script lang="ts">
import MovieDetails from '$lib/components/MovieDetails.svelte';
let data = $props();
</script>
<MovieDetails {...data} />
+7
View File
@@ -0,0 +1,7 @@
import type { PageServerLoad } from "./$types";
export const load: PageServerLoad = async (event) => {
return {
user: event.locals.user
};
};
+6
View File
@@ -0,0 +1,6 @@
<script lang="ts">
import type { PageData } from './$types';
let { data }: { data: PageData } = $props();
</script>
<h1>gameroom</h1>
+34
View File
@@ -0,0 +1,34 @@
import { redirect } from '@sveltejs/kit';
import type { Actions } from './$types';
const api_url = import.meta.env.VITE_API_URL
export const actions: Actions = {
login: async ({ request, cookies }) => {
const formData = await request.formData();
const login_data = Object.fromEntries(formData);
const response = await fetch(`${api_url}/user/login`, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(login_data)
});
if (response.ok) {
const user_data = await response.json()
const encodedUserData = encodeURIComponent(JSON.stringify(user_data));
cookies.set('user', encodedUserData, {
path: '/',
sameSite: 'strict',
secure: false,
maxAge: 60 * 60 * 24
});
throw redirect(302, '/gameroom');
}
}
};
+18 -1
View File
@@ -1,5 +1,22 @@
<script> <script lang="ts">
import Login from '$lib/components/Login.svelte'; import Login from '$lib/components/Login.svelte';
const { form } = $props();
if (form) {
console.log('asda', form);
}
const api_url = import.meta.env.VITE_API_URL;
type User = {
id: string;
username: string;
email: string;
avatar_url: string;
is_admin: boolean;
last_login: string;
};
</script> </script>
<Login /> <Login />
+10
View File
@@ -0,0 +1,10 @@
import type { PageServerLoad } from "./$types";
import { redirect } from '@sveltejs/kit';
export const load: PageServerLoad = async (event) => {
event.cookies.delete('user', {
path: '/',
sameSite: 'strict',
secure: false,
});
throw redirect(302, '/login');
};