initial OIDC setup

This commit is contained in:
Alexander Bocken 2024-02-14 16:07:55 +01:00
parent 1929189187
commit a781be8d00
Signed by: Alexander
GPG Key ID: 1D237BE83F9B05E8
28 changed files with 226 additions and 373 deletions

141
package-lock.json generated
View File

@ -8,6 +8,7 @@
"name": "sk-recipes-test",
"version": "0.0.1",
"dependencies": {
"@auth/sveltekit": "^0.12.3",
"@sveltejs/adapter-node": "^1.3.1",
"argon2": "^0.30.3",
"cheerio": "1.0.0-rc.12",
@ -28,6 +29,62 @@
"vite": "^4.4.4"
}
},
"node_modules/@auth/core": {
"version": "0.26.3",
"resolved": "https://registry.npmjs.org/@auth/core/-/core-0.26.3.tgz",
"integrity": "sha512-Ka6rMjWMdiQCvLW/CnYZxj4Rq2bhQ/ZtU32NLxmtyAaixGb0mRXQ9MxJUBZA7GHovbghdzu55p2Cb54qNlVFzw==",
"dependencies": {
"@panva/hkdf": "^1.1.1",
"@types/cookie": "0.6.0",
"cookie": "0.6.0",
"jose": "^5.1.3",
"oauth4webapi": "^2.4.0",
"preact": "10.11.3",
"preact-render-to-string": "5.2.3"
},
"peerDependencies": {
"@simplewebauthn/browser": "^9.0.1",
"@simplewebauthn/server": "^9.0.1",
"nodemailer": "^6.8.0"
},
"peerDependenciesMeta": {
"@simplewebauthn/browser": {
"optional": true
},
"@simplewebauthn/server": {
"optional": true
},
"nodemailer": {
"optional": true
}
}
},
"node_modules/@auth/core/node_modules/@types/cookie": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.6.0.tgz",
"integrity": "sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA=="
},
"node_modules/@auth/core/node_modules/cookie": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz",
"integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/@auth/sveltekit": {
"version": "0.12.3",
"resolved": "https://registry.npmjs.org/@auth/sveltekit/-/sveltekit-0.12.3.tgz",
"integrity": "sha512-ZZhLPTkLBccJbBPom6n1ARqMNGpSO55ZJUiWhAqY8jPW+K3DtVOd4e/Je+e7g2NJ7vaDoQI4uI0V+jLDBp4B9g==",
"dependencies": {
"@auth/core": "0.26.3",
"set-cookie-parser": "^2.6.0"
},
"peerDependencies": {
"@sveltejs/kit": "^1.0.0 || ^2.0.0",
"svelte": "^3.54.0 || ^4.0.0 || ^5"
}
},
"node_modules/@esbuild/android-arm": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz",
@ -453,6 +510,14 @@
"node": ">= 8"
}
},
"node_modules/@panva/hkdf": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/@panva/hkdf/-/hkdf-1.1.1.tgz",
"integrity": "sha512-dhPeilub1NuIG0X5Kvhh9lH4iW3ZsHlnzwgwbOlgwQ2wG1IqFzsgHqmKPk3WzsdWAeaxKJxgM0+W433RmN45GA==",
"funding": {
"url": "https://github.com/sponsors/panva"
}
},
"node_modules/@phc/format": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@phc/format/-/format-1.0.0.tgz",
@ -1553,10 +1618,17 @@
"resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz",
"integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew=="
},
"node_modules/ip": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ip/-/ip-2.0.0.tgz",
"integrity": "sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ=="
"node_modules/ip-address": {
"version": "9.0.5",
"resolved": "https://registry.npmjs.org/ip-address/-/ip-address-9.0.5.tgz",
"integrity": "sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==",
"dependencies": {
"jsbn": "1.1.0",
"sprintf-js": "^1.1.3"
},
"engines": {
"node": ">= 12"
}
},
"node_modules/is-arrayish": {
"version": "0.3.2",
@ -1651,6 +1723,19 @@
"@types/estree": "*"
}
},
"node_modules/jose": {
"version": "5.2.2",
"resolved": "https://registry.npmjs.org/jose/-/jose-5.2.2.tgz",
"integrity": "sha512-/WByRr4jDcsKlvMd1dRJnPfS1GVO3WuKyaurJ/vvXcOaUQO8rnNObCQMlv/5uCceVQIq5Q4WLF44ohsdiTohdg==",
"funding": {
"url": "https://github.com/sponsors/panva"
}
},
"node_modules/jsbn": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz",
"integrity": "sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A=="
},
"node_modules/jsonwebtoken": {
"version": "9.0.2",
"resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz",
@ -2137,6 +2222,14 @@
"url": "https://github.com/fb55/nth-check?sponsor=1"
}
},
"node_modules/oauth4webapi": {
"version": "2.10.3",
"resolved": "https://registry.npmjs.org/oauth4webapi/-/oauth4webapi-2.10.3.tgz",
"integrity": "sha512-9FkXEXfzVKzH63GUOZz1zMr3wBaICSzk6DLXx+CGdrQ10ItNk2ePWzYYc1fdmKq1ayGFb2aX97sRCoZ2s0mkDw==",
"funding": {
"url": "https://github.com/sponsors/panva"
}
},
"node_modules/object-assign": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
@ -2244,6 +2337,26 @@
"node": "^10 || ^12 || >=14"
}
},
"node_modules/preact": {
"version": "10.11.3",
"resolved": "https://registry.npmjs.org/preact/-/preact-10.11.3.tgz",
"integrity": "sha512-eY93IVpod/zG3uMF22Unl8h9KkrcKIRs2EGar8hwLZZDU1lkjph303V9HZBwufh2s736U6VXuhD109LYqPoffg==",
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/preact"
}
},
"node_modules/preact-render-to-string": {
"version": "5.2.3",
"resolved": "https://registry.npmjs.org/preact-render-to-string/-/preact-render-to-string-5.2.3.tgz",
"integrity": "sha512-aPDxUn5o3GhWdtJtW0svRC2SS/l8D9MAgo2+AWml+BhDImb27ALf04Q2d+AHqUUOc6RdSXFIBVa2gxzgMKgtZA==",
"dependencies": {
"pretty-format": "^3.8.0"
},
"peerDependencies": {
"preact": ">=10"
}
},
"node_modules/prebuild-install": {
"version": "7.1.1",
"resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.1.tgz",
@ -2300,6 +2413,11 @@
"node": ">=6"
}
},
"node_modules/pretty-format": {
"version": "3.8.0",
"resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-3.8.0.tgz",
"integrity": "sha512-WuxUnVtlWL1OfZFQFuqvnvs6MiAGk9UNsBostyBOB0Is9wb5uRESevA6rnl/rkksXaGX3GzZhPup5d6Vp1nFew=="
},
"node_modules/pump": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
@ -2746,15 +2864,15 @@
}
},
"node_modules/socks": {
"version": "2.7.1",
"resolved": "https://registry.npmjs.org/socks/-/socks-2.7.1.tgz",
"integrity": "sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ==",
"version": "2.7.3",
"resolved": "https://registry.npmjs.org/socks/-/socks-2.7.3.tgz",
"integrity": "sha512-vfuYK48HXCTFD03G/1/zkIls3Ebr2YNa4qU9gHDZdblHLiqhJrJGkY3+0Nx0JpN9qBhJbVObc1CNciT1bIZJxw==",
"dependencies": {
"ip": "^2.0.0",
"ip-address": "^9.0.5",
"smart-buffer": "^4.2.0"
},
"engines": {
"node": ">= 10.13.0",
"node": ">= 10.0.0",
"npm": ">= 3.0.0"
}
},
@ -2790,6 +2908,11 @@
"memory-pager": "^1.0.2"
}
},
"node_modules/sprintf-js": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz",
"integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA=="
},
"node_modules/streamx": {
"version": "2.15.6",
"resolved": "https://registry.npmjs.org/streamx/-/streamx-2.15.6.tgz",

View File

@ -21,6 +21,7 @@
"vite": "^4.4.4"
},
"dependencies": {
"@auth/sveltekit": "^0.12.3",
"@sveltejs/adapter-node": "^1.3.1",
"argon2": "^0.30.3",
"cheerio": "1.0.0-rc.12",

12
src/auth.ts Normal file
View File

@ -0,0 +1,12 @@
import { SvelteKitAuth } from "@auth/sveltekit"
import Authentik from "@auth/core/providers/authentik"
import { AUTHENTIK_ID, AUTHENTIK_SECRET, AUTHENTIK_ISSUER } from "$env/static/private";
export const { handle, signIn, signOut } = SvelteKitAuth({
providers: [
Authentik({
clientId: AUTHENTIK_ID,
clientSecret: AUTHENTIK_SECRET,
issuer: AUTHENTIK_ISSUER,
})],
})

View File

@ -2,27 +2,28 @@ import { authenticateUser } from "$lib/js/authenticate"
import type { Handle } from "@sveltejs/kit"
import { redirect } from "@sveltejs/kit"
import { error } from "@sveltejs/kit"
export { handle } from "./auth"
export const handle : Handle = async({event, resolve}) => {
if(event.url.pathname.startsWith('/rezepte/edit') || event.url.pathname.startsWith('/rezepte/add')){
event.locals.user = await authenticateUser(event.cookies)
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')){
event.locals.user = await authenticateUser(event.cookies)
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
}
//export const handle : Handle = async({event, resolve}) => {
// if(event.url.pathname.startsWith('/rezepte/edit') || event.url.pathname.startsWith('/rezepte/add')){
// event.locals.user = await authenticateUser(event.cookies)
// 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')){
// event.locals.user = await authenticateUser(event.cookies)
// 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
//}

View File

@ -130,11 +130,11 @@ h2{
<div id=options class="speech top" hidden>
<h2>{username}</h2>
<ul>
<li><a href="/settings" >Einstellungen</a></li>
<li><a href="/logout" >Log Out</a></li>
<li><a href="https://sso.bocken.org/if/user/#/settings" >Einstellungen</a></li>
<li><a href="/auth/signout" >Log Out</a></li>
</ul>
</div>
</button>
{:else}
<a class=entry href=/login>Log In</a>
<a class=entry href=/auth/signin>Log In</a>
{/if}

View File

@ -1,15 +0,0 @@
import mongoose from 'mongoose';
const PaymentSchema= new mongoose.Schema(
{
payee: {type: String, required: true},
amount: {type: Number, required: true},
for_self: {type: Number},
for_other: {type: Number},
description: {type: String},
added_by: {type: String},
date: {type: Date, required: true, default: Date.now},
}, {timestamps: true}
);
export const Payment = mongoose.model("Payment", PaymentSchema);

View File

@ -2,6 +2,8 @@ import { get_username } from '$lib/js/get_username';;
import type { Actions, PageServerLoad } from "./$types"
import { error } from "@sveltejs/kit"
export const load = (async ({cookies}) => {
return { user: await get_username(cookies) }
export const load = (async ({cookies, locals}) => {
return {
session: await locals.auth(),
}
});

View File

@ -3,9 +3,10 @@ import Header from '$lib/components/Header.svelte'
import UserHeader from '$lib/components/UserHeader.svelte';
export let data
let username = ""
if(data.user){
username = data.user.username
if(data.session){
username = data.session.user.name
}
console.log(data)
</script>
<Header>

View File

@ -2,6 +2,10 @@
import "$lib/css/nordtheme.css";
import LinksGrid from "$lib/components/LinksGrid.svelte";
export let data;
import { SignIn, SignOut } from "@auth/sveltekit/components"
import { page } from "$app/stores"
/*console.log($page)*/
/*console.log($page.daja.session.user)*/
</script>
<style>
.hero{
@ -49,7 +53,8 @@ section h2{
}
</style>
{#if ! data.user}
{#if ! data.session}
<section class=hero>
<img src="https://bocken.org/static/user/full/Alexander.webp" alt="Smiling Alexander Bocken">
<div>

View File

@ -1,35 +0,0 @@
import { redirect } from "@sveltejs/kit"
import type { Actions, PageServerLoad } from "./$types"
import { error } from "@sveltejs/kit"
export const actions: Actions = {
login: async (event) => {
const data = await event.request.formData()
const res = await event.fetch('/api/user/login',
{method: 'POST',
body: JSON.stringify({
username: data.get('username'),
password: data.get('password'),
})
}
)
const jwt = await res.json()
if(res.ok){
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, "/")
}
else{
throw error(401, jwt.message)
}
},
logout: async () => {
throw redirect(303, "/logout")
},
}

View File

@ -1,23 +0,0 @@
<script>
import "$lib/css/form.css"
import "$lib/css/nordtheme.css"
</script>
<form action="?/login" method=POST>
<h1>Log In</h1>
<p>
Note: This is a separate account to all the services running on this server.
Please only use this login if you want to edit recipes.
In the future, this login will be merged with the other services.
</p>
<label>
Benutzername
<input type="text" name="username" required>
</label>
<label>
Passwort
<input name="password" type="password" required>
</label>
<button type="submit">Log In</button>
<p>Noch keinen Account? <a href=/register>Hier registrieren</a>.</p>
</form>

View File

@ -1 +0,0 @@
{"terminal": "nvimterm"}

View File

@ -1,8 +0,0 @@
import redirect from "@sveltejs/kit"
import type { Actions } from './$types';
export const actions: Actions = {
default: async ({cookies}) => {
cookies.delete("UserSession")
}
} satisfies Actions;

View File

@ -1,7 +0,0 @@
<script>
import "$lib/css/form.css"
</script>
<form method='POST'>
<h1>Log out</h1>
<button type='submit'>Log Out</button>
</form>

View File

@ -1,61 +0,0 @@
import type { RequestHandler } from '@sveltejs/kit';
import { Payment } from '../../../../models/Payment';
import { dbConnect, dbDisconnect } from '../../../../utils/db';
import { error } from '@sveltejs/kit';
import { authenticateUser } from '$lib/js/authenticate';;
import sharp from 'sharp';
import path from 'path';
import {IMAGE_DIR} from '$env/static/private';
export const POST: RequestHandler = async ({request, cookies}) => {
const user = await authenticateUser(cookies)
if(!user){
throw error(401, "Not logged in")
}
if(!user.access.includes("abrechnung")){
throw error(401, "This user does not have permissions to add payments")
}
else{
const formData = await request.formData();
const json = {
amount: formData.get("amount"),
for_self: formData.get("for_self"),
for_other: formData.get("for_other"),
payee: formData.get("payee"),
added_by: user._id
}
await dbConnect();
let id;
try{
id = (await Payment.create(json))._id.toString();
} catch(e){
await dbDisconnect();
throw error(400, e)
}
await dbDisconnect();
const img = formData.get("file")
if(img){
//this feels stupid, is there a smarter way directly to Buffer?
const full_res = Buffer.from(await img.arrayBuffer())
await sharp(full_res)
.toFormat('webp')
.toFile(path.join(IMAGE_DIR,
"abrechnung",
"full",
id + '.webp'))
await sharp(full_res)
.resize({width: 20})
.toFormat('webp')
.toFile(path.join(IMAGE_DIR,
"abrechnung",
"placeholder",
id + '.webp'))
}
return new Response(JSON.stringify({message: "Added payment successfully"}),{
status: 200,
});
}
};

View File

@ -1,24 +0,0 @@
import type { RequestHandler } from '@sveltejs/kit';
import { Payment } from '../../../../models/Payment';
import { dbConnect, dbDisconnect } from '../../../../utils/db';
import { error } from '@sveltejs/kit';
import { authenticateUser } from '$lib/js/authenticate';
// header: use for bearer token for now
// recipe json in body
export const POST: RequestHandler = async ({request, cookies}) => {
let json = await request.json()
const user = await authenticateUser(cookies)
if(!user) throw error(401, "Need to be logged in")
if(!user.access.includes("abrechnung")){
throw error(401, "Insufficient permissions")
}
else{
await dbConnect();
await Payment.findOneAndDelete({_id: json.id});
await dbDisconnect();
return new Response(JSON.stringify({msg: "Deleted payment successfully"}),{
status: 200,
});
}
}

View File

@ -1,27 +0,0 @@
import type { RequestHandler } from '@sveltejs/kit';
import { Payment } from '../../../../models/Payment';
import { dbConnect, dbDisconnect } from '../../../../utils/db';
import { error } from '@sveltejs/kit';
import { authenticateUser } from '$lib/js/authenticate';
// header: use for bearer token for now
// recipe json in body
export const POST: RequestHandler = async ({request, cookies}) => {
let message = await request.json()
const json = message.payment
const user = await authenticateUser(cookies)
if(!user){
throw error(403, "Not logged in")
}
else if(!user.access.includes("abrechnung")){
throw error(403, "This user does not have edit permissions for payments")
}
else{
await dbConnect();
await Payment.findOneAndUpdate({_id: json.id}, json);
await dbDisconnect();
return new Response(JSON.stringify({msg: "Edited payment successfully"}),{
status: 200,
});
}
};

View File

@ -1,27 +0,0 @@
import type { RequestHandler } from '@sveltejs/kit';
import { Payment } from '../../../../../models/Payment';
import { dbConnect, dbDisconnect } from '../../../../../utils/db';
import { error } from '@sveltejs/kit';
import { authenticateUser } from '$lib/js/authenticate';
// header: use for bearer token for now
// recipe json in body
export const POST: RequestHandler = async ({request, cookies}) => {
let message = await request.json()
const json = message.payment
const user = await authenticateUser(cookies)
if(!user){
throw error(403, "Not logged in")
}
else if(!user.access.includes("abrechnung")){
throw error(403, "This user does not have edit permissions for payments")
}
else{
await dbConnect();
const payment = await Payment.findOne({_id: json.id}).lean();
await dbDisconnect();
return new Response(JSON.stringify({payment}),{
status: 200,
});
}
};

View File

@ -1,28 +0,0 @@
import type { RequestHandler } from '@sveltejs/kit';
import { Payment } from '../../../../../models/Payment';
import { dbConnect, dbDisconnect } from '../../../../../utils/db';
import { error } from '@sveltejs/kit';
import { authenticateUser } from '$lib/js/authenticate';
// header: use for bearer token for now
// recipe json in body
export const POST: RequestHandler = async ({request, cookies, params}) => {
let message = await request.json()
const n = params.range
const start = message?.start ?? 0;
const user = await authenticateUser(cookies)
if(!user){
throw error(403, "Not logged in")
}
else if(!user.access.includes("abrechnung")){
throw error(403, "This user does not have viewing permissions for payments")
}
else{
await dbConnect();
const payments = await Payment.find({}).sort({ date: -1 }).skip(start).limit(n).lean()
await dbDisconnect();
return new Response(JSON.stringify({payments}),{
status: 200,
});
}
};

View File

@ -1,26 +0,0 @@
import type { RequestHandler } from '@sveltejs/kit';
import { Payment } from '../../../../models/Payment';
import { dbConnect, dbDisconnect } from '../../../../utils/db';
import { error } from '@sveltejs/kit';
import { authenticateUser } from '$lib/js/authenticate';
import { User } from '../../../../models/User';
// header: use for bearer token for now
// recipe json in body
export const GET: RequestHandler = async ({request, cookies}) => {
const user = await authenticateUser(cookies)
if(!user){
throw error(403, "Not logged in")
}
else if(!user.access.includes("abrechnung")){
throw error(403, "This user does not have edit permissions for payments")
}
else{
await dbConnect();
const users = await User.find({access: "abrechnung"}, 'username').lean()
await dbDisconnect();
return new Response(JSON.stringify({users}),{
status: 200,
});
}
};

View File

@ -2,29 +2,28 @@ import type { RequestHandler } from '@sveltejs/kit';
import { Recipe } from '../../../../models/Recipe';
import { dbConnect, dbDisconnect } from '../../../../utils/db';
import { error } from '@sveltejs/kit';
import { authenticateUser } from '$lib/js/authenticate';;
// header: use for bearer token for now
// recipe json in body
export const POST: RequestHandler = async ({request, cookies}) => {
export const POST: RequestHandler = async ({request, cookies, locals}) => {
let message = await request.json()
const recipe_json = message.recipe
const user = await authenticateUser(cookies)
if(!user){
let auth = await locals.auth();
/*const user = session.user;*/
console.log(auth)
if(!auth){
throw error(401, "Not logged in")
}
if(!user.access.includes("rezepte")){
/*if(!user.access.includes("rezepte")){
throw error(401, "This user does not have permissions to add recipes")
}
else{
await dbConnect();
try{
await Recipe.create(recipe_json);
} catch(e){
throw error(400, e)
}
await dbDisconnect();
return new Response(JSON.stringify({msg: "Added recipe successfully"}),{
status: 200,
});
}
}*/
await dbConnect();
try{
await Recipe.create(recipe_json);
} catch(e){
throw error(400, e)
}
await dbDisconnect();
return new Response(JSON.stringify({msg: "Added recipe successfully"}),{
status: 200,
});
};

View File

@ -3,15 +3,13 @@ import { Recipe } from '../../../../models/Recipe';
import { dbConnect, dbDisconnect } from '../../../../utils/db';
import type {RecipeModelType} from '../../../../types/types';
import { error } from '@sveltejs/kit';
import { authenticateUser } from '$lib/js/authenticate';
// header: use for bearer token for now
// recipe json in body
export const POST: RequestHandler = async ({request, cookies}) => {
export const POST: RequestHandler = async ({request, locals}) => {
let message = await request.json()
const user = await authenticateUser(cookies)
if(!user) throw error(401, "Need to be logged in")
if(!user.access.includes("rezepte")) throw error(401, "Insufficient permissions")
const auth = await locals.auth();
if(!auth) throw error(401, "Need to be logged in")
const short_name = message.old_short_name
await dbConnect();

View File

@ -3,20 +3,15 @@ import { Recipe } from '../../../../models/Recipe';
import { dbConnect, dbDisconnect } from '../../../../utils/db';
import type {RecipeModelType} from '../../../../types/types';
import { error } from '@sveltejs/kit';
import { authenticateUser } from '$lib/js/authenticate';
// header: use for bearer token for now
// recipe json in body
export const POST: RequestHandler = async ({request, cookies}) => {
export const POST: RequestHandler = async ({request, locals}) => {
let message = await request.json()
const recipe_json = message.recipe
const user = await authenticateUser(cookies)
console.log(user)
if(!user){
const auth = await locals.auth();
if(!auth){
throw error(403, "Not logged in")
}
else if(!user.access.includes("rezepte")){
throw error(403, "This user does not have edit permissions for recipes")
}
else{
await dbConnect();
await Recipe.findOneAndUpdate({short_name: message.old_short_name }, recipe_json);

View File

@ -3,13 +3,11 @@ import type { RequestHandler } from '@sveltejs/kit';
import { error } from '@sveltejs/kit';
import { IMAGE_DIR } from '$env/static/private'
import sharp from 'sharp';
import { authenticateUser } from '$lib/js/authenticate';
export const POST = (async ({ request, cookies }) => {
export const POST = (async ({ request, locals}) => {
const data = await request.json();
const user = await authenticateUser(cookies)
if (!user) throw error(401, "Need to be logged in")
if (!user.access.includes("rezepte")) throw error(401, "You don't have sufficient permissions for this")
const auth = await locals.auth();
if (!auth) throw error(401, "Need to be logged in")
let full_res = new Buffer.from(data.image, 'base64')
// reduce image size if over 500KB
const MAX_SIZE_KB = 500

View File

@ -3,13 +3,12 @@ import type { RequestHandler } from '@sveltejs/kit';
import { IMAGE_DIR } from '$env/static/private'
import { unlink } from 'node:fs';
import { error } from '@sveltejs/kit';
import { authenticateUser } from '$lib/js/authenticate';;
export const POST = (async ({ request, cookies }) => {
export const POST = (async ({ request, locals}) => {
const data = await request.json();
const user = await authenticateUser(cookies)
if(!user) throw error(401, "You need to be logged in")
if(!user.access.includes("rezepte")) throw error(401, "Your don't have the required permission for this")
const auth = await locals.auth()
if(!auth) throw error(401, "You need to be logged in")
[ "full", "thumb", "placeholder"].forEach((folder) => {
unlink(path.join(IMAGE_DIR, "rezepte", folder, data.name + ".webp"), (e) => {
if(e) error(404, "could not delete: " + folder + "/" + data.name + ".webp" + e)

View File

@ -3,13 +3,11 @@ import type { RequestHandler } from '@sveltejs/kit';
import { IMAGE_DIR } from '$env/static/private'
import { rename } from 'node:fs';
import { error } from '@sveltejs/kit';
import { authenticateUser } from '$lib/js/authenticate';
export const POST = (async ({ request, cookies }) => {
export const POST = (async ({ request, locals}) => {
const data = await request.json();
const user = await authenticateUser(cookies)
if(!user) throw error(401, "need to be logged in")
if(!user.access.includes("rezepte")) throw error(401, "You don't have the required permission to do this")
const auth = await locals.auth();
if(!auth ) throw error(401, "need to be logged in")
[ "full", "thumb", "placeholder"].forEach((folder) => {
const old_path = path.join(IMAGE_DIR, "rezepte", folder, data.old_name + ".webp")

View File

@ -1,5 +1,8 @@
import { get_username } from '$lib/js/get_username';;
import type { Actions, PageServerLoad } from "./$types"
import { error } from "@sveltejs/kit"
export const load = (async ({cookies}) => {
return { user: await get_username(cookies) }
export const load = (async ({cookies, locals}) => {
return {
session: await locals.getSession()
}
});

View File

@ -3,8 +3,8 @@ import Header from '$lib/components/Header.svelte'
import UserHeader from '$lib/components/UserHeader.svelte';
export let data
let username = ""
if(data.user){
username = data.user.username
if(data.session){
username = data.session.user.name
}
</script>