2026-04-17 08:39:42 +00:00
|
|
|
import { decodeJwt, jwtVerify } from 'jose';
|
2026-03-26 20:46:15 +00:00
|
|
|
import { redirect, type Handle } from '@sveltejs/kit';
|
|
|
|
|
import { PRIVATE_JWT_SECRET } from '$env/static/private';
|
2026-03-25 21:09:38 +00:00
|
|
|
import { client } from './lib/apiClient.ts';
|
2026-04-17 08:39:42 +00:00
|
|
|
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;
|
|
|
|
|
});
|
|
|
|
|
}
|
2026-03-25 21:09:38 +00:00
|
|
|
|
2026-04-17 08:39:42 +00:00
|
|
|
function getJwtPayload(jwt: string): { isAdmin: boolean } {
|
|
|
|
|
const decodeResult = decodeJwt<{ is_admin: boolean }>(jwt);
|
|
|
|
|
return { isAdmin: decodeResult.is_admin };
|
2026-03-26 20:46:15 +00:00
|
|
|
}
|
|
|
|
|
|
2026-03-25 21:09:38 +00:00
|
|
|
export const handle: Handle = async ({ event, resolve }) => {
|
|
|
|
|
event.locals.apiClient = client;
|
|
|
|
|
|
2026-04-17 08:39:42 +00:00
|
|
|
const rawToken = event.cookies.get(COOKIE_NAME_AUTH_TOKEN);
|
|
|
|
|
const isValid = rawToken ? await verifyJwt(rawToken, PRIVATE_JWT_SECRET) : false;
|
2026-03-26 20:46:15 +00:00
|
|
|
event.locals.authToken = isValid ? rawToken! : null;
|
2026-03-25 21:09:38 +00:00
|
|
|
|
2026-04-17 08:39:42 +00:00
|
|
|
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`);
|
2026-03-26 20:46:15 +00:00
|
|
|
return redirect(307, '/login');
|
|
|
|
|
}
|
2026-03-25 21:09:38 +00:00
|
|
|
|
2026-03-26 20:46:15 +00:00
|
|
|
return resolve(event);
|
2026-03-25 21:09:38 +00:00
|
|
|
};
|