language-learning-app/frontend/src/hooks.server.ts
2026-05-04 08:00:06 +01:00

44 lines
1.4 KiB
TypeScript

import { decodeJwt, jwtVerify } from 'jose';
import { redirect, type Handle } from '@sveltejs/kit';
import { PRIVATE_JWT_SECRET } from '$env/static/private';
import { client } from './lib/apiClient.ts';
import { COOKIE_NAME_AUTH_TOKEN } from '$lib/auth/index.ts';
async function verifyJwt(token: string, secret: string): Promise<boolean> {
const encodedSecret = new TextEncoder().encode(secret);
return await jwtVerify(token, encodedSecret)
.then(() => true)
.catch((e) => {
console.log(`Caught error while validating JWT: ${e}`);
return false;
});
}
function getJwtPayload(jwt: string): { isAdmin: boolean } {
const decodeResult = decodeJwt<{ is_admin: boolean }>(jwt);
return { isAdmin: decodeResult.is_admin };
}
export const handle: Handle = async ({ event, resolve }) => {
event.locals.apiClient = client;
const rawToken = event.cookies.get(COOKIE_NAME_AUTH_TOKEN);
const isValid = rawToken ? await verifyJwt(rawToken, PRIVATE_JWT_SECRET) : false;
event.locals.authToken = isValid ? rawToken! : null;
if (isValid && rawToken) {
const payload = getJwtPayload(rawToken);
event.locals.isAdmin = payload.isAdmin;
} else {
event.locals.isAdmin = false;
console.log(`Not valid and no token`);
}
const { pathname } = event.url;
if ((pathname.startsWith('/app') || pathname.startsWith('/admin')) && !isValid) {
console.log(`Redirecting to login`);
return redirect(307, '/login');
}
return resolve(event);
};