From 4fcfdc0ee674f15426a11c604ac079da8c6aeb2f Mon Sep 17 00:00:00 2001 From: Eclypsed Date: Thu, 25 Jan 2024 19:50:26 -0500 Subject: [PATCH] started refactoring (app) layout --- src/app.d.ts | 10 +++++++- src/hooks.server.ts | 27 ++++++++++++++++++++++ src/lib/server/users.db | Bin 0 -> 32768 bytes src/lib/server/users.ts | 6 ----- src/routes/(app)/+layout.svelte | 38 +++++++++++++++++++++++++++++++ src/routes/+layout.server.ts | 5 ++++ src/routes/login/+page.server.ts | 6 ++--- 7 files changed, 82 insertions(+), 10 deletions(-) create mode 100644 src/hooks.server.ts create mode 100644 src/routes/(app)/+layout.svelte create mode 100644 src/routes/+layout.server.ts diff --git a/src/app.d.ts b/src/app.d.ts index 5b99784..19204d5 100644 --- a/src/app.d.ts +++ b/src/app.d.ts @@ -3,11 +3,19 @@ declare global { namespace App { // interface Error {} - // interface Locals {} + interface Locals { + user: User + } // interface PageData {} // interface PageState {} // interface Platform {} } + + interface User { + id: string + username: string + password?: string + } } export {} diff --git a/src/hooks.server.ts b/src/hooks.server.ts new file mode 100644 index 0000000..8ab2ee0 --- /dev/null +++ b/src/hooks.server.ts @@ -0,0 +1,27 @@ +import { redirect, type Handle } from '@sveltejs/kit' +import { SECRET_JWT_KEY, SECRET_INTERNAL_API_KEY } from '$env/static/private' +import jwt from 'jsonwebtoken' + +export const handle: Handle = async ({ event, resolve }) => { + const nonJwtProtectedRoutes = ['/login', '/api'] + const urlpath = event.url.pathname + + if (urlpath.startsWith('/api') && event.request.headers.get('apikey') !== SECRET_INTERNAL_API_KEY && event.url.searchParams.get('apikey') !== SECRET_INTERNAL_API_KEY) { + return new Response('Unauthorized', { status: 400 }) + } + + if (!nonJwtProtectedRoutes.some((route) => urlpath.startsWith(route))) { + const authToken = event.cookies.get('lazuli-auth') + if (!authToken) throw redirect(303, `/login?redirect=${urlpath}`) + + try { + const tokenData = jwt.verify(authToken, SECRET_JWT_KEY) as User + event.locals.user = tokenData + } catch { + throw redirect(303, `/login?redirect=${urlpath}`) + } + } + + const response = await resolve(event) + return response +} diff --git a/src/lib/server/users.db b/src/lib/server/users.db index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..4716b4ed139070e084cef7ffece5623b9e2802b3 100644 GIT binary patch literal 32768 zcmeI(U2l_67zc1z-?q68V`A{8$w|7zk+j=d)^@uvku_{qD|EDM&YOk-b!2UsK=GU?=6?d^z&VuX`EhPep|!n=<(Z^uJ8jJ)JawO< zY3eB<6h%e-b=F_Q67ehjV_~7g%7kr{T0Q%?$b6>~3s)5Lkom%VUXqu-EnF=}}BpF*I_)Cd$qHxobA)+Mmk@bNfZVLNlKze?fr&1Rwwb2tWV=5P$## zAOHafK;VA~wCR|d?8S0?(a^R0R;G|Oa+wXo;4|9Rk)GiV&CG6W7K+8pPYp!i4|? zAOHafKmY;|fB*y_009U0R$ib0SG_<0uX=z1Rwwb j2tZ)^1@QcT`tLC^ga8B}009U<00Izz00bZa0SNp6>E1F7 literal 0 HcmV?d00001 diff --git a/src/lib/server/users.ts b/src/lib/server/users.ts index de8d8be..f1e523f 100644 --- a/src/lib/server/users.ts +++ b/src/lib/server/users.ts @@ -11,12 +11,6 @@ db.exec(initUsersTable) db.exec(initServicesTable) db.exec(initConnectionsTable) -interface User { - id: string - username: string - password?: string -} - type UserQueryParams = { includePassword?: boolean } diff --git a/src/routes/(app)/+layout.svelte b/src/routes/(app)/+layout.svelte new file mode 100644 index 0000000..4fb6c98 --- /dev/null +++ b/src/routes/(app)/+layout.svelte @@ -0,0 +1,38 @@ + \ No newline at end of file diff --git a/src/routes/+layout.server.ts b/src/routes/+layout.server.ts new file mode 100644 index 0000000..12a06fd --- /dev/null +++ b/src/routes/+layout.server.ts @@ -0,0 +1,5 @@ +import type { LayoutServerLoad } from './$types' + +export const load: LayoutServerLoad = ({ url, locals }) => { + return { urlPathname: url.pathname, user: locals.user } +} diff --git a/src/routes/login/+page.server.ts b/src/routes/login/+page.server.ts index d22093f..27a56f4 100644 --- a/src/routes/login/+page.server.ts +++ b/src/routes/login/+page.server.ts @@ -3,7 +3,7 @@ import { fail, redirect } from '@sveltejs/kit' import { compare, hash } from 'bcrypt-ts' import type { PageServerLoad, Actions } from './$types' import { Users } from '$lib/server/users' -import { sign } from 'jsonwebtoken' +import jwt from 'jsonwebtoken' export const load: PageServerLoad = async ({ url }) => { const redirectLocation = url.searchParams.get('redirect') @@ -21,7 +21,7 @@ export const actions: Actions = { const passwordValid = await compare(password.toString(), user.password!) if (!passwordValid) return fail(400, { message: 'Invalid Password' }) - const authToken = sign({ id: user.id, username: user.username }, SECRET_JWT_KEY, { expiresIn: '100d' }) + const authToken = jwt.sign({ id: user.id, username: user.username }, SECRET_JWT_KEY, { expiresIn: '100d' }) cookies.set('lazuli-auth', authToken, { path: '/', httpOnly: true, sameSite: 'strict', secure: false, maxAge: 60 * 60 * 24 * 100 }) @@ -40,7 +40,7 @@ export const actions: Actions = { const passwordHash = await hash(password.toString(), 10) const newUser = Users.addUser(username.toString(), passwordHash) - const authToken = sign({ id: newUser.id, username: newUser.username }, SECRET_JWT_KEY, { expiresIn: '100d' }) + const authToken = jwt.sign(newUser, SECRET_JWT_KEY, { expiresIn: '100d' }) cookies.set('lazuli-auth', authToken, { path: '/', httpOnly: true, sameSite: 'strict', secure: false, maxAge: 60 * 60 * 24 * 100 })