Add user login logout
This commit is contained in:
Vendored
+13
-1
@@ -3,7 +3,19 @@
|
||||
declare global {
|
||||
namespace App {
|
||||
// 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 PageState {}
|
||||
// interface Platform {}
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
@@ -1,8 +1,13 @@
|
||||
<script>
|
||||
<script lang="ts">
|
||||
let { user } = $props();
|
||||
let room_link: string = $state('/');
|
||||
if (user) {
|
||||
room_link = '/gameroom/';
|
||||
}
|
||||
</script>
|
||||
|
||||
<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"
|
||||
><enhanced:img
|
||||
@@ -11,11 +16,15 @@
|
||||
alt="Paska joululeffa 2024"
|
||||
/></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>
|
||||
</a>
|
||||
<span>
|
||||
<a href="/login">Sisään</a>
|
||||
<!-- <button>Ulos</button> -->
|
||||
{#if user}
|
||||
{user.username}
|
||||
<a href="/logout" data-sveltekit-preload-data="tap">Ulos</a>
|
||||
{:else}
|
||||
<a href="/login">Sisään</a>
|
||||
{/if}
|
||||
</span>
|
||||
</header>
|
||||
|
||||
@@ -1,15 +1,22 @@
|
||||
<script lang="ts">
|
||||
import { enhance } from '$app/forms';
|
||||
const backend = import.meta.env.VITE_API_URL;
|
||||
</script>
|
||||
|
||||
<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>
|
||||
<form method="POST" action="?/login" class="flex flex-col gap-6" use:enhance>
|
||||
<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>
|
||||
<input
|
||||
type="password"
|
||||
@@ -17,6 +24,7 @@
|
||||
id="password"
|
||||
class="input-text"
|
||||
required
|
||||
value="password"
|
||||
minlength="5"
|
||||
/>
|
||||
<hr class="my-4 border-0" />
|
||||
|
||||
@@ -1 +1,9 @@
|
||||
// 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;
|
||||
}
|
||||
@@ -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');
|
||||
}
|
||||
@@ -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
|
||||
};
|
||||
};
|
||||
@@ -2,7 +2,8 @@
|
||||
import '../app.css';
|
||||
import Header from '$lib/components/Header.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>
|
||||
|
||||
<svelte:head>
|
||||
@@ -10,7 +11,7 @@
|
||||
</svelte:head>
|
||||
|
||||
<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">
|
||||
{@render children()}
|
||||
</main>
|
||||
|
||||
@@ -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
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,6 @@
|
||||
<script lang="ts">
|
||||
import MovieDetails from '$lib/components/MovieDetails.svelte';
|
||||
let data = $props();
|
||||
</script>
|
||||
|
||||
<MovieDetails {...data} />
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
import type { PageServerLoad } from "./$types";
|
||||
|
||||
export const load: PageServerLoad = async (event) => {
|
||||
return {
|
||||
user: event.locals.user
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,6 @@
|
||||
<script lang="ts">
|
||||
import type { PageData } from './$types';
|
||||
let { data }: { data: PageData } = $props();
|
||||
</script>
|
||||
|
||||
<h1>gameroom</h1>
|
||||
@@ -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');
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
@@ -1,5 +1,22 @@
|
||||
<script>
|
||||
<script lang="ts">
|
||||
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>
|
||||
|
||||
<Login />
|
||||
|
||||
@@ -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');
|
||||
};
|
||||
Reference in New Issue
Block a user