From 70e640aa9a423394c2f13322cf1d54ffde9f4eaf Mon Sep 17 00:00:00 2001 From: AlexBocken Date: Tue, 18 Jul 2023 12:05:30 +0200 Subject: [PATCH] cleaner login and registration --- src/hooks.server.ts | 28 +++++++++++++ src/lib/js/authenticate.ts | 40 ++++++++++++++++++ src/routes/api/login/+server.ts | 12 ------ src/routes/api/register/+server.ts | 13 ------ src/routes/api/verify/+server.ts | 1 - src/routes/login/+page.server.ts | 32 ++++++++++++++ src/routes/login/+page.svelte | 42 +++++++++++++++++++ src/routes/rezepte/[name]/+page.svelte | 2 +- .../rezepte/[name]/.jukit/.jukit_info.json | 1 + src/routes/rezepte/add/+page.server.ts | 5 +++ .../edit/[name]/{+page.ts => +page.server.ts} | 6 ++- src/routes/rezepte/edit/[name]/+page.svelte | 1 - 12 files changed, 153 insertions(+), 30 deletions(-) create mode 100644 src/hooks.server.ts create mode 100644 src/lib/js/authenticate.ts create mode 100644 src/routes/login/+page.server.ts create mode 100644 src/routes/login/+page.svelte create mode 100644 src/routes/rezepte/[name]/.jukit/.jukit_info.json create mode 100644 src/routes/rezepte/add/+page.server.ts rename src/routes/rezepte/edit/[name]/{+page.ts => +page.server.ts} (63%) diff --git a/src/hooks.server.ts b/src/hooks.server.ts new file mode 100644 index 0000000..74052b4 --- /dev/null +++ b/src/hooks.server.ts @@ -0,0 +1,28 @@ +import { authenticateUser } from "$lib/js/authenticate" +import type { Handle } from "@sveltejs/kit" +import { redirect } from "@sveltejs/kit" +import { error } from "@sveltejs/kit" + +export const handle : Handle = async({event, resolve}) => { + event.locals.user = await authenticateUser(event) + if(event.url.pathname.startsWith('/rezepte/edit') || event.url.pathname.startsWith('/rezepte/add')){ + if(!event.locals.user){ + throw redirect(303, "/login") + } + else if(!event.locals.user.access.includes("rezepte")){ + throw error(401, "Your user does not have access to this page") + } + } + else if(event.url.pathname.startsWith('/abrechnung')){ + console.log(event.locals.user) + if(!event.locals.user){ + throw redirect(303, "/login") + } + else if(!event.locals.user.access.includes("abrechnung")){ + throw error(401, "Your User does not have access to this page") + } + } + + const response = await resolve(event) + return response +} diff --git a/src/lib/js/authenticate.ts b/src/lib/js/authenticate.ts new file mode 100644 index 0000000..fa8f3fb --- /dev/null +++ b/src/lib/js/authenticate.ts @@ -0,0 +1,40 @@ +import type { RequestEvent } from "@sveltejs/kit"; +import { COOKIE_SECRET } from "$env/static/private"; +import { verify } from "jsonwebtoken"; +import { error } from "@sveltejs/kit"; +import { dbConnect, dbDisconnect } from "../../utils/db"; +import { User } from "../../models/User";; + +export async function authenticateUser(event: RequestEvent){ +// Set your master secret key (replace with your own secret) + const { cookies } = event; + const masterSecret = COOKIE_SECRET; + const secretKey = masterSecret + let decoded + try{ + const cookie : string = cookies.get("UserSession") + if(cookie){ + decoded = await verify(cookie, secretKey); + } + + } + catch(e){ + throw error(401, "Cookies have changed, please log in again") + } + + if(decoded){ + await dbConnect() + let res = await User.findOne({username: decoded.username}, 'access').lean(); + await dbDisconnect() + if(!res){ + throw error(404, "User for this Cookie does no longer exist") + } + return { + username: decoded.username, + access: res.access + } + } + else{ + return null + } +} diff --git a/src/routes/api/login/+server.ts b/src/routes/api/login/+server.ts index dc97db7..703f1d8 100644 --- a/src/routes/api/login/+server.ts +++ b/src/routes/api/login/+server.ts @@ -11,7 +11,6 @@ import { User } from '../../../models/User'; // recipe json in body export const POST: RequestHandler = async ({request}) => { const {username, password} = await request.json() - // TODO: get salt from user in DB await dbConnect() let res = await User.findOne({username: username}, 'pass_hash salt').lean() await dbDisconnect() @@ -31,17 +30,6 @@ export const POST: RequestHandler = async ({request}) => { return new Response(JSON.stringify(res)) }; -async function hashPassword(password) { - try { - const salt = await generateSalt(); // Generate a random salt - const hashedPassword = await hash(password, salt); // Hash the password with the salt - return { hashedPassword, salt }; - } catch (error) { - console.error('Error hashing password:', error); - } -} - - async function createJWT(username) { const payload = { username: username, diff --git a/src/routes/api/register/+server.ts b/src/routes/api/register/+server.ts index 61f8cb3..0c25741 100644 --- a/src/routes/api/register/+server.ts +++ b/src/routes/api/register/+server.ts @@ -49,16 +49,3 @@ async function hashPassword(password, salt) { console.error('Error hashing password:', error); } } - - - -async function createJWT(username, userSalt) { - const payload = { - username: username, - }; - - const masterSecret = COOKIE_SECRET; - const secretKey = masterSecret + userSalt; - const jwt = sign(payload, secretKey); - return jwt -} diff --git a/src/routes/api/verify/+server.ts b/src/routes/api/verify/+server.ts index 927b138..50d3aa1 100644 --- a/src/routes/api/verify/+server.ts +++ b/src/routes/api/verify/+server.ts @@ -15,7 +15,6 @@ import { getJWTFromRequest } from '../../../utils/cookie'; // recipe json in body export const GET: RequestHandler = async ({request}) => { const jwt = getJWTFromRequest(request) - console.log(jwt) // Set your master secret key (replace with your own secret) const masterSecret = COOKIE_SECRET; diff --git a/src/routes/login/+page.server.ts b/src/routes/login/+page.server.ts new file mode 100644 index 0000000..21bebb5 --- /dev/null +++ b/src/routes/login/+page.server.ts @@ -0,0 +1,32 @@ +import { redirect } from "@sveltejs/kit" +import type { Actions, PageServerLoad } from "./$types" + +export const load: PageServerLoad = async ({ locals }) => { + return { + user: locals.user, + } +} + +export const actions: Actions = { + login: async (event) => { + const data = await event.request.formData() + const res = await event.fetch('/api/login', + {method: 'POST', + body: JSON.stringify({ + username: data.get('username'), + password: data.get('password'), + }) + } + ) + const jwt = await res.json() + event.cookies.set("UserSession", jwt, { + path: "/", + httpOnly: true, + sameSite: "strict", + secure: process.env.NODE_ENV === "production", + maxAge: 60 * 60 * 24 * 7, // 1 week + }) + + throw redirect(303, "/") + }, +} diff --git a/src/routes/login/+page.svelte b/src/routes/login/+page.svelte new file mode 100644 index 0000000..7ddbed7 --- /dev/null +++ b/src/routes/login/+page.svelte @@ -0,0 +1,42 @@ + + + +
+ + +

Log In

+
+ + + + +
+
diff --git a/src/routes/rezepte/[name]/+page.svelte b/src/routes/rezepte/[name]/+page.svelte index 63f670d..cd3582c 100644 --- a/src/routes/rezepte/[name]/+page.svelte +++ b/src/routes/rezepte/[name]/+page.svelte @@ -9,7 +9,7 @@ import IngredientsPage from '$lib/components/IngredientsPage.svelte'; import TitleImgParallax from '$lib/components/TitleImgParallax.svelte'; import { afterNavigate } from '$app/navigation'; - import {season} from '$lib/js/season_store'; + import {season} from '$lib/js/season_store'; export let data: PageData; diff --git a/src/routes/rezepte/[name]/.jukit/.jukit_info.json b/src/routes/rezepte/[name]/.jukit/.jukit_info.json new file mode 100644 index 0000000..92c7342 --- /dev/null +++ b/src/routes/rezepte/[name]/.jukit/.jukit_info.json @@ -0,0 +1 @@ +{"terminal": "nvimterm"} \ No newline at end of file diff --git a/src/routes/rezepte/add/+page.server.ts b/src/routes/rezepte/add/+page.server.ts new file mode 100644 index 0000000..014387f --- /dev/null +++ b/src/routes/rezepte/add/+page.server.ts @@ -0,0 +1,5 @@ +export async function load({locals}) { + return { + user: locals.user + }; +}; diff --git a/src/routes/rezepte/edit/[name]/+page.ts b/src/routes/rezepte/edit/[name]/+page.server.ts similarity index 63% rename from src/routes/rezepte/edit/[name]/+page.ts rename to src/routes/rezepte/edit/[name]/+page.server.ts index 786ac8f..a28d9ca 100644 --- a/src/routes/rezepte/edit/[name]/+page.ts +++ b/src/routes/rezepte/edit/[name]/+page.server.ts @@ -1,8 +1,10 @@ import type { PageLoad } from "./$types"; -export async function load({ fetch, params}) { +export async function load({ fetch, params, locals}) { let current_month = new Date().getMonth() + 1 const res = await fetch(`/api/items/${params.name}`); const recipe = await res.json(); - return {recipe}; + return {recipe: recipe, + user: locals.user + }; }; diff --git a/src/routes/rezepte/edit/[name]/+page.svelte b/src/routes/rezepte/edit/[name]/+page.svelte index 50f3255..46ba8eb 100644 --- a/src/routes/rezepte/edit/[name]/+page.svelte +++ b/src/routes/rezepte/edit/[name]/+page.svelte @@ -342,7 +342,6 @@ h3{ }

Rezept editieren

-

Kurzname (für URL):