cleaner login and registration
This commit is contained in:
		
							
								
								
									
										28
									
								
								src/hooks.server.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								src/hooks.server.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -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 | ||||||
|  | } | ||||||
							
								
								
									
										40
									
								
								src/lib/js/authenticate.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								src/lib/js/authenticate.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -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 | ||||||
|  | 	} | ||||||
|  | } | ||||||
| @@ -11,7 +11,6 @@ import { User } from '../../../models/User'; | |||||||
| // recipe json in body | // recipe json in body | ||||||
| export const POST: RequestHandler = async ({request}) => { | export const POST: RequestHandler = async ({request}) => { | ||||||
| 	const {username, password} = await request.json() | 	const {username, password} = await request.json() | ||||||
| 	// TODO: get salt from user in DB |  | ||||||
| 	await dbConnect() | 	await dbConnect() | ||||||
| 	let res = await User.findOne({username: username}, 'pass_hash salt').lean() | 	let res = await User.findOne({username: username}, 'pass_hash salt').lean() | ||||||
| 	await dbDisconnect() | 	await dbDisconnect() | ||||||
| @@ -31,17 +30,6 @@ export const POST: RequestHandler = async ({request}) => { | |||||||
| 	return new Response(JSON.stringify(res)) | 	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) { | async function createJWT(username) { | ||||||
| 	const payload = { | 	const payload = { | ||||||
|   	  username: username, |   	  username: username, | ||||||
|   | |||||||
| @@ -49,16 +49,3 @@ async function hashPassword(password, salt) { | |||||||
|     console.error('Error hashing password:', error); |     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 |  | ||||||
| } |  | ||||||
|   | |||||||
| @@ -15,7 +15,6 @@ import { getJWTFromRequest } from '../../../utils/cookie'; | |||||||
| // recipe json in body | // recipe json in body | ||||||
| export const GET: RequestHandler = async ({request}) => { | export const GET: RequestHandler = async ({request}) => { | ||||||
| 	const jwt = getJWTFromRequest(request) | 	const jwt = getJWTFromRequest(request) | ||||||
| 	console.log(jwt) |  | ||||||
|  |  | ||||||
|   	// Set your master secret key (replace with your own secret) |   	// Set your master secret key (replace with your own secret) | ||||||
|   	const masterSecret = COOKIE_SECRET; |   	const masterSecret = COOKIE_SECRET; | ||||||
|   | |||||||
							
								
								
									
										32
									
								
								src/routes/login/+page.server.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								src/routes/login/+page.server.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -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, "/") | ||||||
|  | 	}, | ||||||
|  | } | ||||||
							
								
								
									
										42
									
								
								src/routes/login/+page.svelte
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								src/routes/login/+page.svelte
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,42 @@ | |||||||
|  | <script> | ||||||
|  | 	import Header from '$lib/components/Header.svelte' | ||||||
|  |   	import { setCookie } from 'svelte-cookie'; | ||||||
|  |  | ||||||
|  | 	export async function createJWT() { | ||||||
|  | 	    const res = await fetch('/api/login', | ||||||
|  | 	    		{method: 'POST', | ||||||
|  | 			body: JSON.stringify({ | ||||||
|  | 				username: "testuser2", | ||||||
|  | 				password: "password", | ||||||
|  | 			}) | ||||||
|  | 			} | ||||||
|  | 			) | ||||||
|  | 	    const jwt = await res.json() | ||||||
|  | 	    setCookie('UserSession', jwt, {expires: 7}) | ||||||
|  | 	} | ||||||
|  | </script> | ||||||
|  | <style> | ||||||
|  | </style> | ||||||
|  |  | ||||||
|  | <Header> | ||||||
|  | <ul class=site_header slot=links> | ||||||
|  | 	<li><a href="/rezepte">Rezepte</a></li> | ||||||
|  | 	<li><a href="/bilder">Bilder</a></li> | ||||||
|  | 	<li><a href="/git">Git</a></li> | ||||||
|  | 	<li><a href="/transmission">Transmission</a></li> | ||||||
|  | </ul> | ||||||
|  |  | ||||||
|  | <h1>Log In</h1> | ||||||
|  | <form action="?/login" method=POST> | ||||||
|  | 	<label> | ||||||
|  | 		Username | ||||||
|  | 		<input type="text" name="username"> | ||||||
|  | 	</label> | ||||||
|  | 	<label> | ||||||
|  | 		Passwort | ||||||
|  | 		<input  name="password" type="password"> | ||||||
|  | 	</label> | ||||||
|  |  | ||||||
|  | 	<button type="submit">Log In</button> | ||||||
|  | </form> | ||||||
|  | </Header> | ||||||
| @@ -9,7 +9,7 @@ | |||||||
| 	import IngredientsPage from '$lib/components/IngredientsPage.svelte'; | 	import IngredientsPage from '$lib/components/IngredientsPage.svelte'; | ||||||
| 	import TitleImgParallax from '$lib/components/TitleImgParallax.svelte'; | 	import TitleImgParallax from '$lib/components/TitleImgParallax.svelte'; | ||||||
| 	import { afterNavigate } from '$app/navigation'; | 	import { afterNavigate } from '$app/navigation'; | ||||||
|     import {season} from '$lib/js/season_store'; |     	import {season} from '$lib/js/season_store'; | ||||||
|  |  | ||||||
|     	export let data: PageData; |     	export let data: PageData; | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										1
									
								
								src/routes/rezepte/[name]/.jukit/.jukit_info.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								src/routes/rezepte/[name]/.jukit/.jukit_info.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | |||||||
|  | {"terminal": "nvimterm"} | ||||||
							
								
								
									
										5
									
								
								src/routes/rezepte/add/+page.server.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								src/routes/rezepte/add/+page.server.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,5 @@ | |||||||
|  | export async function load({locals}) { | ||||||
|  |     return { | ||||||
|  | 	user: locals.user | ||||||
|  |     }; | ||||||
|  | }; | ||||||
| @@ -1,8 +1,10 @@ | |||||||
| import type { PageLoad } from "./$types"; | 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 |     let current_month = new Date().getMonth() + 1 | ||||||
|     const res = await fetch(`/api/items/${params.name}`); |     const res = await fetch(`/api/items/${params.name}`); | ||||||
|     const recipe = await res.json(); |     const recipe = await res.json(); | ||||||
|     return {recipe}; |     return {recipe: recipe, | ||||||
|  | 	user: locals.user | ||||||
|  |     }; | ||||||
| }; | }; | ||||||
| @@ -342,7 +342,6 @@ h3{ | |||||||
| } | } | ||||||
| </style> | </style> | ||||||
| <h1>Rezept editieren</h1> | <h1>Rezept editieren</h1> | ||||||
|  |  | ||||||
| <CardAdd {card_data} {image_preview_url} ></CardAdd> | <CardAdd {card_data} {image_preview_url} ></CardAdd> | ||||||
|  |  | ||||||
| <h3>Kurzname (für URL):</h3> | <h3>Kurzname (für URL):</h3> | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user