started refactoring (app) layout
This commit is contained in:
10
src/app.d.ts
vendored
10
src/app.d.ts
vendored
@@ -3,11 +3,19 @@
|
|||||||
declare global {
|
declare global {
|
||||||
namespace App {
|
namespace App {
|
||||||
// interface Error {}
|
// interface Error {}
|
||||||
// interface Locals {}
|
interface Locals {
|
||||||
|
user: User
|
||||||
|
}
|
||||||
// interface PageData {}
|
// interface PageData {}
|
||||||
// interface PageState {}
|
// interface PageState {}
|
||||||
// interface Platform {}
|
// interface Platform {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface User {
|
||||||
|
id: string
|
||||||
|
username: string
|
||||||
|
password?: string
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export {}
|
export {}
|
||||||
|
|||||||
27
src/hooks.server.ts
Normal file
27
src/hooks.server.ts
Normal file
@@ -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
|
||||||
|
}
|
||||||
Binary file not shown.
@@ -11,12 +11,6 @@ db.exec(initUsersTable)
|
|||||||
db.exec(initServicesTable)
|
db.exec(initServicesTable)
|
||||||
db.exec(initConnectionsTable)
|
db.exec(initConnectionsTable)
|
||||||
|
|
||||||
interface User {
|
|
||||||
id: string
|
|
||||||
username: string
|
|
||||||
password?: string
|
|
||||||
}
|
|
||||||
|
|
||||||
type UserQueryParams = {
|
type UserQueryParams = {
|
||||||
includePassword?: boolean
|
includePassword?: boolean
|
||||||
}
|
}
|
||||||
|
|||||||
38
src/routes/(app)/+layout.svelte
Normal file
38
src/routes/(app)/+layout.svelte
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import { fly, fade } from "svelte/transition";
|
||||||
|
import { goto } from "$app/navigation";
|
||||||
|
import { pageWidth } from "$lib/stores";
|
||||||
|
import type { LayoutServerData } from "../$types.js";
|
||||||
|
|
||||||
|
export let data: LayoutServerData
|
||||||
|
|
||||||
|
const contentTabs = {
|
||||||
|
'/': {
|
||||||
|
header: 'Home',
|
||||||
|
icon: 'fa-solid fa-house',
|
||||||
|
},
|
||||||
|
'/account': {
|
||||||
|
header: data.user.username,
|
||||||
|
icon: 'fa-solid fa-user',
|
||||||
|
},
|
||||||
|
'/search': {
|
||||||
|
header: 'Search',
|
||||||
|
icon: 'fa-solid fa-search',
|
||||||
|
},
|
||||||
|
'/library': {
|
||||||
|
header: 'Libray',
|
||||||
|
icon: 'fa-solid fa-bars-staggered',
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
const pageTransitionTime: number = 200
|
||||||
|
|
||||||
|
let previousPage = data.urlPathname
|
||||||
|
type PageTransitionDirection = 1 | -1
|
||||||
|
let direction: PageTransitionDirection = 1
|
||||||
|
|
||||||
|
const calculateDirection = (newPage: string): void => {
|
||||||
|
const contentLinks = Object.keys(contentTabs)
|
||||||
|
const newPageIndex = contentLinks.indexOf(newPage)
|
||||||
|
}
|
||||||
|
</script>
|
||||||
5
src/routes/+layout.server.ts
Normal file
5
src/routes/+layout.server.ts
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
import type { LayoutServerLoad } from './$types'
|
||||||
|
|
||||||
|
export const load: LayoutServerLoad = ({ url, locals }) => {
|
||||||
|
return { urlPathname: url.pathname, user: locals.user }
|
||||||
|
}
|
||||||
@@ -3,7 +3,7 @@ import { fail, redirect } from '@sveltejs/kit'
|
|||||||
import { compare, hash } from 'bcrypt-ts'
|
import { compare, hash } from 'bcrypt-ts'
|
||||||
import type { PageServerLoad, Actions } from './$types'
|
import type { PageServerLoad, Actions } from './$types'
|
||||||
import { Users } from '$lib/server/users'
|
import { Users } from '$lib/server/users'
|
||||||
import { sign } from 'jsonwebtoken'
|
import jwt from 'jsonwebtoken'
|
||||||
|
|
||||||
export const load: PageServerLoad = async ({ url }) => {
|
export const load: PageServerLoad = async ({ url }) => {
|
||||||
const redirectLocation = url.searchParams.get('redirect')
|
const redirectLocation = url.searchParams.get('redirect')
|
||||||
@@ -21,7 +21,7 @@ export const actions: Actions = {
|
|||||||
const passwordValid = await compare(password.toString(), user.password!)
|
const passwordValid = await compare(password.toString(), user.password!)
|
||||||
if (!passwordValid) return fail(400, { message: 'Invalid 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 })
|
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 passwordHash = await hash(password.toString(), 10)
|
||||||
const newUser = Users.addUser(username.toString(), passwordHash)
|
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 })
|
cookies.set('lazuli-auth', authToken, { path: '/', httpOnly: true, sameSite: 'strict', secure: false, maxAge: 60 * 60 * 24 * 100 })
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user