Interceptors, redirectTo, refactor #17

Merged
glazk0 merged 4 commits from dev into main 2024-04-01 00:33:52 +02:00
13 changed files with 86 additions and 94 deletions
Showing only changes of commit 3c12603404 - Show all commits

8
src/app.d.ts vendored
View file

@ -5,7 +5,10 @@ import type { User } from '$lib/types';
// for information about these interfaces // for information about these interfaces
declare global { declare global {
namespace App { namespace App {
// interface Error {} interface Error {
message: string;
errorId: string;
}
interface Locals { interface Locals {
user: User | null; user: User | null;
} }
@ -16,4 +19,5 @@ declare global {
} }
} }
export {}; export { };

View file

@ -1,4 +1,4 @@
import type { Handle } from '@sveltejs/kit'; import type { Handle, HandleFetch, HandleServerError } from '@sveltejs/kit';
import { API_URL } from '$env/static/private'; import { API_URL } from '$env/static/private';
@ -30,3 +30,32 @@ export const handle: Handle = async ({ event, resolve }) => {
return resolve(event); return resolve(event);
}; };
export const handleFetch: HandleFetch = async ({ request, fetch, event: { cookies } }) => {
const session = cookies.get('session');
if (!session) {
return fetch(request);
}
request = new Request(request, {
headers: {
...request.headers,
Authorization: `Bearer ${session}`
},
});
return fetch(request);
}
export const handleError: HandleServerError = async ({ error, status }) => {
const errorId = crypto.randomUUID();
console.error(`Error ID: ${errorId} - Status: ${status} - ${error}`);
return {
message: 'Whoops!',
errorId,
};
};

View file

@ -6,17 +6,11 @@ import type { PageServerLoad } from './$types';
import type { Chapter } from '$lib/types'; import type { Chapter } from '$lib/types';
import { handleRedirect } from '$lib/utils'; import { handleRedirect } from '$lib/utils';
export const load = (async ({ url, fetch, cookies, locals: { user } }) => { export const load = (async ({ url, fetch, locals: { user } }) => {
if (!user) redirect(302, handleRedirect('login', url)); if (!user) redirect(302, handleRedirect('login', url));
const session = cookies.get('session'); const res = await fetch(`${API_URL}/chapters`);
const res = await fetch(`${API_URL}/chapters`, {
headers: {
Authorization: `Bearer ${session}`
}
});
if (!res.ok) { if (!res.ok) {
return { return {

View file

@ -6,17 +6,11 @@ import type { PageServerLoad } from './$types';
import type { Chapter } from '$lib/types'; import type { Chapter } from '$lib/types';
import { handleRedirect } from '$lib/utils'; import { handleRedirect } from '$lib/utils';
export const load = (async ({ url, locals: { user }, fetch, cookies }) => { export const load = (async ({ url, locals: { user }, fetch }) => {
if (!user) redirect(302, handleRedirect('login', url)); if (!user) redirect(302, handleRedirect('login', url));
const session = cookies.get('session'); const res = await fetch(`${API_URL}/chapters`);
const res = await fetch(`${API_URL}/chapters`, {
headers: {
Authorization: `Bearer ${session}`
}
});
if (!res.ok) { if (!res.ok) {
return { return {

View file

@ -6,17 +6,11 @@ import type { Chapter } from '$lib/types';
import { handleRedirect } from '$lib/utils'; import { handleRedirect } from '$lib/utils';
import { redirect } from '@sveltejs/kit'; import { redirect } from '@sveltejs/kit';
export const load = (async ({ url, locals: { user }, fetch, cookies, params: { chapterId } }) => { export const load = (async ({ url, locals: { user }, fetch, params: { chapterId } }) => {
if (!user) redirect(302, handleRedirect('login', url)); if (!user) redirect(302, handleRedirect('login', url));
const session = cookies.get('session'); const res = await fetch(`${API_URL}/chapter/${chapterId}`);
const res = await fetch(`${API_URL}/chapter/${chapterId}`, {
headers: {
Authorization: `Bearer ${session}`
}
});
if (!res.ok) { if (!res.ok) {
redirect(302, '/chapters'); redirect(302, '/chapters');

View file

@ -6,17 +6,11 @@ import type { Chapter, Group } from '$lib/types';
import { handleRedirect } from '$lib/utils'; import { handleRedirect } from '$lib/utils';
import { redirect } from '@sveltejs/kit'; import { redirect } from '@sveltejs/kit';
export const load: PageServerLoad = async ({ url, locals: { user }, fetch, cookies, params: { chapterId } }) => { export const load: PageServerLoad = async ({ url, locals: { user }, fetch, params: { chapterId } }) => {
if (!user) redirect(302, handleRedirect('login', url)); if (!user) redirect(302, handleRedirect('login', url));
const session = cookies.get('session'); let res = await fetch(`${API_URL}/chapter/${chapterId}`);
let res = await fetch(`${API_URL}/chapter/${chapterId}`, {
headers: {
Authorization: `Bearer ${session}`
}
});
if (!res.ok) { if (!res.ok) {
redirect(302, '/chapters'); redirect(302, '/chapters');
@ -28,12 +22,7 @@ export const load: PageServerLoad = async ({ url, locals: { user }, fetch, cooki
redirect(302, '/chapters'); redirect(302, '/chapters');
} }
res = await fetch(`${API_URL}/groups/${chapter.id}`, { res = await fetch(`${API_URL}/groups/${chapter.id}`);
headers:
{
Authorization: `Bearer ${session}`
}
});
if (!res.ok) { if (!res.ok) {
redirect(302, `/chapters/${chapterId}`); redirect(302, `/chapters/${chapterId}`);
@ -50,19 +39,14 @@ export const load: PageServerLoad = async ({ url, locals: { user }, fetch, cooki
export const actions: Actions = { export const actions: Actions = {
join: async ({ fetch, params: { chapterId }, cookies, request }) => { join: async ({ fetch, params: { chapterId }, request }) => {
const data = await request.formData(); const data = await request.formData();
const name = data.get('name') as string; const name = data.get('name') as string;
const session = cookies.get('session');
const res = await fetch(`${API_URL}/groupJoin`, { const res = await fetch(`${API_URL}/groupJoin`, {
method: 'POST', method: 'POST',
headers: {
Authorization: `Bearer ${session}`
},
body: JSON.stringify({ body: JSON.stringify({
name, name,
chapter: parseInt(chapterId), chapter: parseInt(chapterId),
@ -95,19 +79,14 @@ export const actions: Actions = {
message: "Une erreur s'est produite" message: "Une erreur s'est produite"
}; };
}, },
leave: async ({ fetch, params: { chapterId }, cookies, request }) => { leave: async ({ fetch, params: { chapterId }, request }) => {
const data = await request.formData(); const data = await request.formData();
const name = data.get('name') as string; const name = data.get('name') as string;
const session = cookies.get('session');
const res = await fetch(`${API_URL}/groupQuit`, { const res = await fetch(`${API_URL}/groupQuit`, {
method: 'POST', method: 'POST',
headers: {
Authorization: `Bearer ${session}`
},
body: JSON.stringify({ body: JSON.stringify({
name, name,
chapter: parseInt(chapterId), chapter: parseInt(chapterId),

View file

@ -25,14 +25,12 @@ export const load: PageServerLoad = async ({ url, params: { chapterId }, locals:
}; };
export const actions: Actions = { export const actions: Actions = {
default: async ({ url, locals: { user }, fetch, request, cookies, params: { chapterId } }) => { default: async ({ url, locals: { user }, fetch, request, params: { chapterId } }) => {
if (!user) redirect(302, handleRedirect('login', url)); if (!user) redirect(302, handleRedirect('login', url));
if (!chapterId) redirect(302, '/chapters'); if (!chapterId) redirect(302, '/chapters');
const session = cookies.get('session');
const form = await superValidate(request, zod(groupSchema)); const form = await superValidate(request, zod(groupSchema));
if (!form.valid) { if (!form.valid) {
@ -41,9 +39,6 @@ export const actions: Actions = {
const res = await fetch(`${API_URL}/groupCreate`, { const res = await fetch(`${API_URL}/groupCreate`, {
method: 'POST', method: 'POST',
headers: {
Authorization: `Bearer ${session}`
},
body: JSON.stringify({ body: JSON.stringify({
...form.data, ...form.data,
chapter: parseInt(chapterId) chapter: parseInt(chapterId)

View file

@ -5,19 +5,13 @@ import type { PageServerLoad } from './$types';
import type { LeaderboardEvent } from '$lib/types'; import type { LeaderboardEvent } from '$lib/types';
import { handleRedirect } from '$lib/utils'; import { handleRedirect } from '$lib/utils';
export const load: PageServerLoad = async ({ url, locals: { user }, fetch, cookies, params: { chapterId } }) => { export const load: PageServerLoad = async ({ url, locals: { user }, fetch, params: { chapterId } }) => {
if (!user) redirect(302, handleRedirect('login', url)); if (!user) redirect(302, handleRedirect('login', url));
if (!chapterId) redirect(302, '/'); if (!chapterId) redirect(302, '/');
const session = cookies.get('session'); const res = await fetch(`${API_URL}/leaderboard/${chapterId}`);
const res = await fetch(`${API_URL}/leaderboard/${chapterId}`, {
headers: {
Authorization: `Bearer ${session}`
}
});
if (!res.ok) return { if (!res.ok) return {
leaderboard: [] leaderboard: []

View file

@ -16,11 +16,7 @@ export const load = (async ({ url, locals: { user }, fetch, cookies, params: { c
redirect(302, `/chapters/${chapterId}`); redirect(302, `/chapters/${chapterId}`);
} }
let res = await fetch(`${API_URL}/chapter/${chapterId}`, { let res = await fetch(`${API_URL}/chapter/${chapterId}`);
headers: {
Authorization: `Bearer ${session}`
}
});
if (!res.ok) { if (!res.ok) {
redirect(302, `/chapters`); redirect(302, `/chapters`);
@ -39,20 +35,22 @@ export const load = (async ({ url, locals: { user }, fetch, cookies, params: { c
redirect(302, `/chapters/${chapterId}`); redirect(302, `/chapters/${chapterId}`);
} }
res = await fetch(`${API_URL}/puzzle/${puzzleId}`, { res = await fetch(`${API_URL}/puzzle/${puzzleId}`);
headers: {
Authorization: `Bearer ${session}`
}
});
if (!res.ok) { if (!res.ok) {
error(404, 'Puzzle not found'); error(404, {
errorId: 'puzzle_not_found',
message: 'Puzzle not found'
});
} }
const puzzle: Puzzle = await res.json(); const puzzle: Puzzle = await res.json();
if (!puzzle) { if (!puzzle) {
error(404, 'Puzzle not found'); error(404, {
errorId: 'puzzle_not_found',
message: 'Puzzle not found'
});
} }
const content = await compile(puzzle.content); const content = await compile(puzzle.content);

View file

@ -6,17 +6,11 @@ import type { PageServerLoad } from './$types';
import type { Leaderboard } from '$lib/types'; import type { Leaderboard } from '$lib/types';
import { handleRedirect } from '$lib/utils'; import { handleRedirect } from '$lib/utils';
export const load = (async ({ url, locals: { user }, fetch, cookies }) => { export const load = (async ({ url, locals: { user }, fetch }) => {
if (!user) redirect(302, handleRedirect('login', url)); if (!user) redirect(302, handleRedirect('login', url));
const session = cookies.get('session'); const res = await fetch(`${API_URL}/leaderboard`);
const res = await fetch(`${API_URL}/leaderboard`, {
headers: {
Authorization: `Bearer ${session}`
}
});
if (!res.ok) { if (!res.ok) {
return { return {

View file

@ -1,5 +1,7 @@
<script lang="ts"> <script lang="ts">
import { page } from '$app/stores';
import { Button } from '$lib/components/ui/button'; import { Button } from '$lib/components/ui/button';
import { cn } from '$lib/utils';
let routes = [ let routes = [
{ {
@ -14,7 +16,13 @@
<ul class="flex gap-2 lg:flex-col"> <ul class="flex gap-2 lg:flex-col">
{#each routes as { name, href } (name)} {#each routes as { name, href } (name)}
<li> <li>
<Button class="w-full" variant="outline" {href}>{name}</Button> <Button
class={cn('w-full', {
'bg-secondary': $page.url.pathname === href
})}
variant="outline"
{href}>{name}</Button
>
</li> </li>
{/each} {/each}
</ul> </ul>

View file

@ -20,12 +20,10 @@ export const load: PageServerLoad = async ({ url, locals: { user } }) => {
}; };
export const actions: Actions = { export const actions: Actions = {
default: async ({ request, cookies, locals: { user } }) => { default: async ({ request, fetch, locals: { user } }) => {
if (!user) return fail(401); if (!user) return fail(401);
const session = cookies.get('session');
const form = await superValidate(request, zod(settingSchema)); const form = await superValidate(request, zod(settingSchema));
if (!form.valid) { if (!form.valid) {
@ -34,9 +32,6 @@ export const actions: Actions = {
const res = await fetch(`${API_URL}/user/settings`, { const res = await fetch(`${API_URL}/user/settings`, {
method: 'POST', method: 'POST',
headers: {
Authorization: `Bearer ${session}`
},
body: JSON.stringify({ body: JSON.stringify({
...form.data ...form.data
}) })

14
src/routes/+error.svelte Normal file
View file

@ -0,0 +1,14 @@
<script lang="ts">
import { page } from '$app/stores';
import Button from '$lib/components/ui/button/button.svelte';
</script>
<div class="flex min-h-screen items-center justify-center">
<div class="text-center">
<h1 class="text-6xl font-bold text-red-500">Oops!</h1>
<p class="mt-4 text-xl">Apparement tu as navigué en eau trouble...</p>
<Button class="mt-4" href="/">Retour au port</Button>
<p class="mt-4 text-xs text-muted-foreground">{$page.error?.errorId}</p>
</div>
</div>