diff --git a/src/app.d.ts b/src/app.d.ts index da08e6da..695bb525 100644 --- a/src/app.d.ts +++ b/src/app.d.ts @@ -3,11 +3,17 @@ declare global { namespace App { // interface Error {} - // interface Locals {} + interface Locals { + session: { + account: AccountCookie | null + user: UserCookie | null + isAuthenticated: boolean + } + } // interface PageData {} // interface PageState {} // interface Platform {} } } -export {}; +export {} diff --git a/src/hooks.server.ts b/src/hooks.server.ts index 51822109..c15f1292 100644 --- a/src/hooks.server.ts +++ b/src/hooks.server.ts @@ -1,12 +1,48 @@ -import type { Handle } from '@sveltejs/kit'; -import { paraglideMiddleware } from '$lib/paraglide/server'; +import type { Handle, HandleFetch } from '@sveltejs/kit' +import { sequence } from '@sveltejs/kit/hooks' +import { paraglideMiddleware } from '$lib/paraglide/server' +import { getAccountFromCookies, getUserFromCookies } from '$lib/auth/cookies' +import { PUBLIC_SIERO_API_URL } from '$env/static/public' -const handleParaglide: Handle = ({ event, resolve }) => paraglideMiddleware(event.request, ({ request, locale }) => { - event.request = request; +export const handleSession: Handle = async ({ event, resolve }) => { + const account = getAccountFromCookies(event.cookies) + const user = getUserFromCookies(event.cookies) - return resolve(event, { - transformPageChunk: ({ html }) => html.replace('%paraglide.lang%', locale) - }); -}); + event.locals.session = { + account, + user, + isAuthenticated: Boolean(account?.token) + } -export const handle: Handle = handleParaglide; + return resolve(event) +} + +const handleParaglide: Handle = ({ event, resolve }) => + paraglideMiddleware(event.request, ({ request, locale }) => { + event.request = request + + return resolve(event, { + transformPageChunk: ({ html }) => html.replace('%paraglide.lang%', locale) + }) + }) + +export const handle: Handle = sequence(handleSession, handleParaglide) + +const apiOrigin = new URL(PUBLIC_SIERO_API_URL || 'http://localhost:3000/api/v1').origin + +export const handleFetch: HandleFetch = async ({ event, request, fetch }) => { + const url = new URL(request.url) + if (url.origin === apiOrigin) { + const token = event.locals.session?.account?.token + if (token) { + request = new Request(request, { + headers: new Headers({ + ...Object.fromEntries(request.headers), + authorization: `Bearer ${token}` + }) + }) + } + } + + return fetch(request) +} diff --git a/src/routes/+layout.server.ts b/src/routes/+layout.server.ts new file mode 100644 index 00000000..7152a145 --- /dev/null +++ b/src/routes/+layout.server.ts @@ -0,0 +1,20 @@ +import type { LayoutServerLoad } from './$types' + +export const load: LayoutServerLoad = async ({ locals }) => { + const account = locals.session.account + ? { + userId: locals.session.account.userId, + username: locals.session.account.username, + role: locals.session.account.role + } + : null + + const currentUser = locals.session.user ?? null + const isAuthenticated = locals.session.isAuthenticated + + return { + isAuthenticated, + account, + currentUser + } +} diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte index 20f8d044..ee4962e5 100644 --- a/src/routes/+layout.svelte +++ b/src/routes/+layout.svelte @@ -1,7 +1,10 @@