diff --git a/frontend/src/hooks.server.ts b/frontend/src/hooks.server.ts index 080f177ce..c61d4c9bc 100644 --- a/frontend/src/hooks.server.ts +++ b/frontend/src/hooks.server.ts @@ -1,53 +1,30 @@ import { BASE_API_URL } from '$lib/utils/constants'; import type { User } from '$lib/utils/types'; -import { redirect, type Handle, type HandleFetch } from '@sveltejs/kit'; +import { redirect, type Handle, type RequestEvent, type HandleFetch } from '@sveltejs/kit'; -const LOGIN_REQUIRED_ROUTING_GROUP = new Set(['app']); // List of route group that require login to be accessed -const ROUTE_GROUP_REGEX = /^\([a-zA-Z0-9_]+\)/; - -export const handle: Handle = async ({ event, resolve }) => { - const route: string | null = event.route.id; - let group = null; - - const session = event.cookies.get('sessionid'); - - if (route) { - group = route.substring(1).match(ROUTE_GROUP_REGEX)?.[0]; - group = group?.substring(1, group.length - 1); - } - if (!session && group && LOGIN_REQUIRED_ROUTING_GROUP.has(group)) { - redirect(302, `/login?next=${event.url.pathname}`); - } - - let csrfToken = event.cookies.get('csrftoken'); +async function ensureCsrfToken(event: RequestEvent): Promise { + let csrfToken = event.cookies.get('csrftoken') || ''; if (!csrfToken) { - csrfToken = await fetch(`${BASE_API_URL}/csrf/`, { + const response = await fetch(`${BASE_API_URL}/csrf/`, { credentials: 'include', - headers: { - 'content-type': 'application/json' - } - }) - .then((res) => res.json()) - .then((res) => res.csrfToken); + headers: { 'content-type': 'application/json' } + }); + const data = await response.json(); + csrfToken = data.csrfToken; + event.cookies.set('csrftoken', csrfToken, { + httpOnly: false, + sameSite: 'lax', + path: '/', + secure: true + }); } - event.cookies.set('csrftoken', csrfToken!, { - httpOnly: false, - sameSite: 'lax', - path: '/', - secure: true - }); + return csrfToken; +} - if (event.locals.user) { - // There is already a logged-in user. Load page as normal. - return await resolve(event); - } - - if (!session) { - // There is no session, so no logged-in user. Load page as normal. - return await resolve(event); - } +async function validateUserSession(event: RequestEvent): Promise { + const session = event.cookies.get('sessionid'); + if (!session) return null; - // Fetch the user corresponding to the session. const res = await fetch(`${BASE_API_URL}/iam/current-user/`, { credentials: 'include', headers: { @@ -57,14 +34,23 @@ export const handle: Handle = async ({ event, resolve }) => { }); if (!res.ok) { - console.log('bad response:', await res.text()); - // The session is invalid. Load page as normal. - return await resolve(event); + event.cookies.delete('sessionid', { + path: '/' + }); + redirect(302, `/login?next=${event.url.pathname}`); } + return res.json(); +} - // User exists, set `events.locals.user` and load page. - const response: User = (await res.json()) as User; - event.locals.user = response; +export const handle: Handle = async ({ event, resolve }) => { + await ensureCsrfToken(event); + + if (event.locals.user) return await resolve(event); + + const user = await validateUserSession(event); + if (user) { + event.locals.user = user; + } return await resolve(event); };