diff --git a/web/bun.lockb b/web/bun.lockb index 05028ed..56eee72 100644 Binary files a/web/bun.lockb and b/web/bun.lockb differ diff --git a/web/package.json b/web/package.json index ad5a4ee..2d5de07 100644 --- a/web/package.json +++ b/web/package.json @@ -10,11 +10,13 @@ "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch", "test": "vitest", "lint": "prettier --plugin-search-dir . --check .", - "format": "prettier --plugin-search-dir . --write ." + "format": "prettier --plugin-search-dir . --write .", + "start": "bun ./build/index.js" }, "devDependencies": { "@sveltejs/adapter-auto": "^2.0.0", "@sveltejs/kit": "^1.20.4", + "@types/jsonwebtoken": "^9.0.4", "autoprefixer": "^10.4.14", "postcss": "^8.4.24", "postcss-load-config": "^4.0.1", @@ -32,6 +34,7 @@ "dependencies": { "bits-ui": "^0.9.0", "clsx": "^2.0.0", + "jsonwebtoken": "^9.0.2", "lucide-svelte": "^0.292.0", "tailwind-merge": "^2.0.0", "tailwind-variants": "^0.1.18" diff --git a/web/src/app.postcss b/web/src/app.css similarity index 100% rename from web/src/app.postcss rename to web/src/app.css diff --git a/web/src/hooks.server.ts b/web/src/hooks.server.ts new file mode 100644 index 0000000..2448dcd --- /dev/null +++ b/web/src/hooks.server.ts @@ -0,0 +1,34 @@ +import type { Handle } from '@sveltejs/kit'; +import { verifyToken } from '$lib/auth'; + +export const handle: Handle = async ({ event, resolve }) => { + if (event.url.pathname.startsWith('/custom')) { + const resp = new Response('custom response'); + resp.headers.set('content-type', 'text/plain'); + return resp; + } + + const auth_exception = ['/api/health', '/login']; + + if (!auth_exception.includes(event.url.pathname)) { + const token = event.cookies.get('authorization'); + const redirect = new Response(null, { status: 302, headers: { location: '/login' } }); + + if (!token) { + console.log('handle', event.url.pathname, 'no token'); + return redirect; + } + + const token_valid = await verifyToken(token); + if (!token_valid) { + console.log('handle', event.url.pathname, 'invalid token'); + return redirect; + } + } + + const resp = await resolve(event); + + console.log('handle', event.url.pathname, resp.status); + + return resp; +}; diff --git a/web/src/lib/auth.ts b/web/src/lib/auth.ts new file mode 100644 index 0000000..a3b3f77 --- /dev/null +++ b/web/src/lib/auth.ts @@ -0,0 +1,15 @@ +import jwt from 'jsonwebtoken'; +import { AUTH_SECRET } from '$env/static/private'; + +export async function generateToken(): Promise { + return jwt.sign('OK', AUTH_SECRET, { expiresIn: '1d' }); +} + +export async function verifyToken(token: string): Promise { + try { + const decode = jwt.verify(token, AUTH_SECRET); + return !!(decode && decode === 'OK'); + } catch (e) { + return false; + } +} diff --git a/web/src/routes/+layout.svelte b/web/src/routes/+layout.svelte index 41159bb..6397c15 100644 --- a/web/src/routes/+layout.svelte +++ b/web/src/routes/+layout.svelte @@ -1,5 +1,5 @@ diff --git a/web/src/routes/login/+page.svelte b/web/src/routes/login/+page.svelte new file mode 100644 index 0000000..ba7c290 --- /dev/null +++ b/web/src/routes/login/+page.svelte @@ -0,0 +1 @@ +

Hello World!

\ No newline at end of file