Compare commits
No commits in common. "7dd52d8890a500602afd2df45035b0e8f3341331" and "0816cbe9e5fea246b1b744b08788c45c2af66f5d" have entirely different histories.
7dd52d8890
...
0816cbe9e5
4
src/app.d.ts
vendored
4
src/app.d.ts
vendored
@ -1,5 +1,9 @@
|
|||||||
// See https://kit.svelte.dev/docs/types#app
|
// See https://kit.svelte.dev/docs/types#app
|
||||||
// for information about these interfaces
|
// for information about these interfaces
|
||||||
|
declare module '@fortawesome/pro-solid-svg-icons/index.es' {
|
||||||
|
export * from '@fortawesome/pro-solid-svg-icons';
|
||||||
|
}
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
namespace App {
|
namespace App {
|
||||||
// interface Error {}
|
// interface Error {}
|
||||||
|
@ -1,28 +0,0 @@
|
|||||||
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.cookies)
|
|
||||||
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
|
|
||||||
}
|
|
@ -111,6 +111,9 @@ export function edit_ingredient_and_close_modal(){
|
|||||||
modal_el.close();
|
modal_el.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function show_keys(event){
|
||||||
|
console.log(event.ctrlKey, event.key)
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
@ -122,6 +122,7 @@
|
|||||||
const item = await res.json();
|
const item = await res.json();
|
||||||
}
|
}
|
||||||
async function doAdd () {
|
async function doAdd () {
|
||||||
|
console.log(add_info.total_time)
|
||||||
const res = await fetch('/api/add', {
|
const res = await fetch('/api/add', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
|
@ -14,6 +14,7 @@ const link_els = document.querySelectorAll("nav a")
|
|||||||
link_els.forEach((el) => {
|
link_els.forEach((el) => {
|
||||||
el.addEventListener("click", () => {toggle_sidebar(true)});
|
el.addEventListener("click", () => {toggle_sidebar(true)});
|
||||||
})
|
})
|
||||||
|
console.log(link_els)
|
||||||
})
|
})
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
@ -229,7 +229,7 @@ span
|
|||||||
<button class:selected={multiplier==1.5} on:click={() => {multiplier=1.5; custom_mul="…"}}><sup>3</sup>⁄<sub>2</sub>x</button>
|
<button class:selected={multiplier==1.5} on:click={() => {multiplier=1.5; custom_mul="…"}}><sup>3</sup>⁄<sub>2</sub>x</button>
|
||||||
<button class:selected={multiplier==2} on:click="{() => {multiplier=2; custom_mul="…"}}">2x</button>
|
<button class:selected={multiplier==2} on:click="{() => {multiplier=2; custom_mul="…"}}">2x</button>
|
||||||
<button class:selected={multiplier==3} on:click="{() => {multiplier=3; custom_mul="…"}}">3x</button>
|
<button class:selected={multiplier==3} on:click="{() => {multiplier=3; custom_mul="…"}}">3x</button>
|
||||||
<button class:selected={multiplier==custom_mul} on:click={(e) => { const el = e.composedPath()[0].children[0]; if(el){ el.focus()}}}>
|
<button class:selected={multiplier==custom_mul} on:click={(e) => { console.log(e) ;const el = e.composedPath()[0].children[0]; if(el){ el.focus()}}}>
|
||||||
<span class:selected={multiplier==custom_mul}
|
<span class:selected={multiplier==custom_mul}
|
||||||
on:focus={() => { custom_mul="" }
|
on:focus={() => { custom_mul="" }
|
||||||
}
|
}
|
||||||
|
@ -47,6 +47,7 @@
|
|||||||
|
|
||||||
const json = await res.json()
|
const json = await res.json()
|
||||||
result = JSON.stringify(json)
|
result = JSON.stringify(json)
|
||||||
|
console.log(result)
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
<style>
|
<style>
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
let months = ["Januar", "Februar", "März", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Dezember"]
|
let months = ["Januar", "Februar", "März", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Dezember"]
|
||||||
let month : number;
|
let month : number;
|
||||||
export let active_index;
|
export let active_index;
|
||||||
|
console.log(active_index)
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
<style>
|
<style>
|
||||||
|
@ -1,39 +0,0 @@
|
|||||||
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(cookies){
|
|
||||||
// Set your master secret key (replace with your own secret)
|
|
||||||
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){
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,12 +0,0 @@
|
|||||||
import mongoose from 'mongoose';
|
|
||||||
|
|
||||||
const UserSchema = new mongoose.Schema(
|
|
||||||
{
|
|
||||||
username: {type: String, required: true, unique: true},
|
|
||||||
pass_hash: {type: String, required: true},
|
|
||||||
salt : {type: String, required: true},
|
|
||||||
access: [String], //rezepte, flims, abrechnung, ...
|
|
||||||
}, {timestamps: true}
|
|
||||||
);
|
|
||||||
|
|
||||||
export const User = mongoose.model("User", UserSchema);
|
|
@ -1,14 +0,0 @@
|
|||||||
<script>
|
|
||||||
import Header from '$lib/components/Header.svelte'
|
|
||||||
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<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>
|
|
||||||
<slot></slot>
|
|
||||||
</Header>
|
|
@ -1,18 +0,0 @@
|
|||||||
<style>
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<section>
|
|
||||||
<h2><a href="/rezepte">Rezepte</a></h2>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section>
|
|
||||||
<h2><a href="/bilder">Bilder</a></h2>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section>
|
|
||||||
<h2><a href="/git">Git</a></h2>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section>
|
|
||||||
<h2><a href="/transmission">Transmission Web Viewer</a></h2>
|
|
||||||
</section>
|
|
@ -1,10 +0,0 @@
|
|||||||
<script lang="ts">
|
|
||||||
import Header from "$lib/components/Header.svelte";
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<Header>
|
|
||||||
<ul class=site_header slot=links>
|
|
||||||
<li><a href="/">Home</a></li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
</Header>
|
|
@ -1,16 +0,0 @@
|
|||||||
<script lang="ts">
|
|
||||||
import Header from "$lib/components/Header.svelte";
|
|
||||||
import Calendar from "$lib/components/Calendar.svelte";
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<Header>
|
|
||||||
<ul class=site_header slot=links>
|
|
||||||
<li><a href="/">Home</a></li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<Calendar>
|
|
||||||
|
|
||||||
</Calendar>
|
|
||||||
|
|
||||||
|
|
||||||
</Header>
|
|
@ -1,41 +0,0 @@
|
|||||||
import { redirect } from "@sveltejs/kit"
|
|
||||||
import type { Actions, PageServerLoad } from "./$types"
|
|
||||||
import { error } from "@sveltejs/kit"
|
|
||||||
|
|
||||||
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()
|
|
||||||
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")
|
|
||||||
},
|
|
||||||
}
|
|
@ -1,13 +0,0 @@
|
|||||||
<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>
|
|
@ -1,7 +0,0 @@
|
|||||||
import { redirect } from "@sveltejs/kit"
|
|
||||||
import type { Actions, PageServerLoad } from "./$types"
|
|
||||||
|
|
||||||
export const load: PageServerLoad = async ({ cookies }) => {
|
|
||||||
cookies.delete("UserSession")
|
|
||||||
redirect(303, "/")
|
|
||||||
}
|
|
@ -1,12 +0,0 @@
|
|||||||
<script>
|
|
||||||
import { redirect } from "@sveltejs/kit";
|
|
||||||
import { afterNavigate } from '$app/navigation';
|
|
||||||
import { onMount } from "svelte";
|
|
||||||
afterNavigate(() => {
|
|
||||||
redirect(303, "/")
|
|
||||||
})
|
|
||||||
onMount(() => {
|
|
||||||
redirect(303, "/")
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
<h1>Log Out</h1>
|
|
@ -1,33 +0,0 @@
|
|||||||
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 = {
|
|
||||||
register: async (event) => {
|
|
||||||
const data = await event.request.formData();
|
|
||||||
const acccess_options = ["rezepte", "abrechnung", "flims"]
|
|
||||||
let enabled_access = []
|
|
||||||
acccess_options.forEach((option) => {
|
|
||||||
if(data.get(option) == 'on'){
|
|
||||||
enabled_access.push(option)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
const res = await event.fetch('/api/register',
|
|
||||||
{method: 'POST',
|
|
||||||
body: JSON.stringify({
|
|
||||||
|
|
||||||
username: data.get('username'),
|
|
||||||
password: data.get('password'),
|
|
||||||
access: enabled_access,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
throw redirect(303, "/login")
|
|
||||||
},
|
|
||||||
}
|
|
@ -1,44 +0,0 @@
|
|||||||
<script>
|
|
||||||
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>
|
|
||||||
|
|
||||||
<h1>Register</h1>
|
|
||||||
<form action="?/register" method=POST>
|
|
||||||
<label>
|
|
||||||
Username
|
|
||||||
<input type="text" name="username">
|
|
||||||
</label>
|
|
||||||
<label>
|
|
||||||
Passwort
|
|
||||||
<input name="password" type="password">
|
|
||||||
</label>
|
|
||||||
<label>
|
|
||||||
Rezepte
|
|
||||||
<input type="checkbox" name="rezepte">
|
|
||||||
</label>
|
|
||||||
<label>
|
|
||||||
Abrechnungen
|
|
||||||
<input type="checkbox" name="abrechnung">
|
|
||||||
</label>
|
|
||||||
<label>
|
|
||||||
Flims
|
|
||||||
<input type="checkbox" name="flims">
|
|
||||||
</label>
|
|
||||||
|
|
||||||
<button type="submit">Register</button>
|
|
||||||
</form>
|
|
@ -1,78 +0,0 @@
|
|||||||
<script>
|
|
||||||
import Header from '$lib/components/Header.svelte'
|
|
||||||
import { onMount } from 'svelte';
|
|
||||||
import { goto } from '$app/navigation';
|
|
||||||
import { get } from 'svelte/store';
|
|
||||||
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})
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function registerUserTest(){
|
|
||||||
const res = await fetch('/api/register',
|
|
||||||
{method: 'POST',
|
|
||||||
body: JSON.stringify({
|
|
||||||
username: "testuser2",
|
|
||||||
password: "password",
|
|
||||||
access: ["rezepte", "abrechnung", "flims" ]
|
|
||||||
})
|
|
||||||
}
|
|
||||||
)
|
|
||||||
console.log("res:", res);
|
|
||||||
const j = await res.json()
|
|
||||||
console.log("response:", j)
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function readJWTSS(){
|
|
||||||
const res = await fetch('/api/verify',
|
|
||||||
{method: 'GET',
|
|
||||||
credentials: 'include',
|
|
||||||
}
|
|
||||||
)
|
|
||||||
const item = await res.json()
|
|
||||||
console.log(res)
|
|
||||||
console.log(item)
|
|
||||||
}
|
|
||||||
|
|
||||||
</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>
|
|
||||||
|
|
||||||
<section>
|
|
||||||
<h2><a href="/rezepte">Rezepte</a></h2>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section>
|
|
||||||
<h2><a href="/bilder">Bilder</a></h2>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section>
|
|
||||||
<h2><a href="/git">Git</a></h2>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section>
|
|
||||||
<h2><a href="/transmission">Transmission Web Viewer</a></h2>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<button on:click={registerUserTest}>Test User Registration</button>
|
|
||||||
<button on:click={createJWT}>Log In</button>
|
|
||||||
<button on:click={readJWTSS}>Test reading cookie</button>
|
|
||||||
</Header>
|
|
@ -1,5 +0,0 @@
|
|||||||
export async function load({locals}) {
|
|
||||||
return {
|
|
||||||
user: locals.user
|
|
||||||
};
|
|
||||||
};
|
|
32
src/routes/+page.svelte
Normal file
32
src/routes/+page.svelte
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
<script>
|
||||||
|
import Header from '$lib/components/Header.svelte'
|
||||||
|
</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>
|
||||||
|
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<h2><a href="/rezepte">Rezepte</a></h2>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<h2><a href="/bilder">Bilder</a></h2>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<h2><a href="/git">Git</a></h2>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<h2><a href="/transmission">Transmission Web Viewer</a></h2>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
</Header>
|
@ -1,30 +1,28 @@
|
|||||||
import type { RequestHandler } from '@sveltejs/kit';
|
import type { RequestHandler } from '@sveltejs/kit';
|
||||||
import { Recipe } from '../../../models/Recipe';
|
import { Recipe } from '../../../models/Recipe';
|
||||||
import { dbConnect, dbDisconnect } from '../../../utils/db';
|
import { dbConnect, dbDisconnect } from '../../../utils/db';
|
||||||
|
import type {RecipeModelType} from '../../../types/types';
|
||||||
|
import { BEARER_TOKEN } from '$env/static/private'
|
||||||
import { error } from '@sveltejs/kit';
|
import { error } from '@sveltejs/kit';
|
||||||
import { authenticateUser } from '$lib/js/authenticate';;
|
|
||||||
// header: use for bearer token for now
|
// header: use for bearer token for now
|
||||||
// recipe json in body
|
// recipe json in body
|
||||||
export const POST: RequestHandler = async ({request, cookies}) => {
|
export const POST: RequestHandler = async ({request}) => {
|
||||||
let message = await request.json()
|
let message = await request.json()
|
||||||
const recipe_json = message.recipe
|
const recipe_json = message.recipe
|
||||||
const user = await authenticateUser(cookies)
|
const bearer_token = message.headers.bearer
|
||||||
if(!user){
|
if(bearer_token === BEARER_TOKEN){
|
||||||
throw error(401, "Not logged in")
|
await dbConnect();
|
||||||
}
|
try{
|
||||||
if(!user.access.includes("rezepte")){
|
await Recipe.create(recipe_json);
|
||||||
throw error(401, "This user does not have permissions to add recipes")
|
} catch(e){
|
||||||
}
|
throw error(400, e)
|
||||||
else{
|
}
|
||||||
await dbConnect();
|
await dbDisconnect();
|
||||||
try{
|
return new Response(JSON.stringify({msg: "Added recipe successfully"}),{
|
||||||
await Recipe.create(recipe_json);
|
status: 200,
|
||||||
} catch(e){
|
});
|
||||||
throw error(400, e)
|
}
|
||||||
}
|
else{
|
||||||
await dbDisconnect();
|
throw error(403, "Password incorrect")
|
||||||
return new Response(JSON.stringify({msg: "Added recipe successfully"}),{
|
}
|
||||||
status: 200,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
@ -2,22 +2,23 @@ import type { RequestHandler } from '@sveltejs/kit';
|
|||||||
import { Recipe } from '../../../models/Recipe';
|
import { Recipe } from '../../../models/Recipe';
|
||||||
import { dbConnect, dbDisconnect } from '../../../utils/db';
|
import { dbConnect, dbDisconnect } from '../../../utils/db';
|
||||||
import type {RecipeModelType} from '../../../types/types';
|
import type {RecipeModelType} from '../../../types/types';
|
||||||
|
import { BEARER_TOKEN } from '$env/static/private'
|
||||||
import { error } from '@sveltejs/kit';
|
import { error } from '@sveltejs/kit';
|
||||||
import { authenticateUser } from '$lib/js/authenticate';
|
|
||||||
// header: use for bearer token for now
|
// header: use for bearer token for now
|
||||||
// recipe json in body
|
// recipe json in body
|
||||||
export const POST: RequestHandler = async ({request, cookies}) => {
|
export const POST: RequestHandler = async ({request}) => {
|
||||||
let message = await request.json()
|
let message = await request.json()
|
||||||
|
const short_name = message.old_short_name
|
||||||
const user = await authenticateUser(cookies)
|
const bearer_token = message.headers.bearer
|
||||||
if(!user) throw error(401, "Need to be logged in")
|
if(bearer_token === BEARER_TOKEN){
|
||||||
if(!user.access.includes("rezepte")) throw error(401, "Insufficient permissions")
|
await dbConnect();
|
||||||
|
|
||||||
const short_name = message.old_short_name
|
|
||||||
await dbConnect();
|
|
||||||
await Recipe.findOneAndDelete({short_name: short_name});
|
await Recipe.findOneAndDelete({short_name: short_name});
|
||||||
await dbDisconnect();
|
await dbDisconnect();
|
||||||
return new Response(JSON.stringify({msg: "Deleted recipe successfully"}),{
|
return new Response(JSON.stringify({msg: "Deleted recipe successfully"}),{
|
||||||
status: 200,
|
status: 200,
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
throw error(403, "Password incorrect")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,23 +2,16 @@ import type { RequestHandler } from '@sveltejs/kit';
|
|||||||
import { Recipe } from '../../../models/Recipe';
|
import { Recipe } from '../../../models/Recipe';
|
||||||
import { dbConnect, dbDisconnect } from '../../../utils/db';
|
import { dbConnect, dbDisconnect } from '../../../utils/db';
|
||||||
import type {RecipeModelType} from '../../../types/types';
|
import type {RecipeModelType} from '../../../types/types';
|
||||||
|
import { BEARER_TOKEN } from '$env/static/private'
|
||||||
import { error } from '@sveltejs/kit';
|
import { error } from '@sveltejs/kit';
|
||||||
import { authenticateUser } from '$lib/js/authenticate';
|
|
||||||
// header: use for bearer token for now
|
// header: use for bearer token for now
|
||||||
// recipe json in body
|
// recipe json in body
|
||||||
export const POST: RequestHandler = async ({request, cookies}) => {
|
export const POST: RequestHandler = async ({request}) => {
|
||||||
let message = await request.json()
|
let message = await request.json()
|
||||||
const recipe_json = message.recipe
|
const recipe_json = message.recipe
|
||||||
const user = await authenticateUser(cookies)
|
const bearer_token = message.headers.bearer
|
||||||
console.log(user)
|
if(bearer_token === BEARER_TOKEN){
|
||||||
if(!user){
|
await dbConnect();
|
||||||
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);
|
await Recipe.findOneAndUpdate({short_name: message.old_short_name }, recipe_json);
|
||||||
await dbDisconnect();
|
await dbDisconnect();
|
||||||
return new Response(JSON.stringify({msg: "Edited recipe successfully"}),{
|
return new Response(JSON.stringify({msg: "Edited recipe successfully"}),{
|
||||||
@ -26,4 +19,7 @@ export const POST: RequestHandler = async ({request, cookies}) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
else{
|
||||||
|
throw error(403, "Password incorrect")
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
@ -1,15 +1,13 @@
|
|||||||
import path from 'path'
|
import path from 'path'
|
||||||
import type { RequestHandler } from '@sveltejs/kit';
|
import type { RequestHandler } from '@sveltejs/kit';
|
||||||
|
import { BEARER_TOKEN } from '$env/static/private'
|
||||||
import { error } from '@sveltejs/kit';
|
import { error } from '@sveltejs/kit';
|
||||||
import { IMAGE_DIR } from '$env/static/private'
|
import { IMAGE_DIR } from '$env/static/private'
|
||||||
import sharp from 'sharp';
|
import sharp from 'sharp';
|
||||||
import { authenticateUser } from '$lib/js/authenticate';
|
|
||||||
|
|
||||||
export const POST = (async ({ request, cookies }) => {
|
export const POST = (async ({ request }) => {
|
||||||
const data = await request.json();
|
const data = await request.json();
|
||||||
const user = await authenticateUser(cookies)
|
if(data.bearer === BEARER_TOKEN){
|
||||||
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")
|
|
||||||
let full_res = new Buffer.from(data.image, 'base64')
|
let full_res = new Buffer.from(data.image, 'base64')
|
||||||
// reduce image size if over 500KB
|
// reduce image size if over 500KB
|
||||||
const MAX_SIZE_KB = 500
|
const MAX_SIZE_KB = 500
|
||||||
@ -43,4 +41,9 @@ export const POST = (async ({ request, cookies }) => {
|
|||||||
return new Response(JSON.stringify({msg: "Added image successfully"}),{
|
return new Response(JSON.stringify({msg: "Added image successfully"}),{
|
||||||
status: 200,
|
status: 200,
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
throw error(403, "Password incorrect")
|
||||||
|
}
|
||||||
|
|
||||||
}) satisfies RequestHandler;
|
}) satisfies RequestHandler;
|
||||||
|
@ -1,15 +1,13 @@
|
|||||||
import path from 'path'
|
import path from 'path'
|
||||||
import type { RequestHandler } from '@sveltejs/kit';
|
import type { RequestHandler } from '@sveltejs/kit';
|
||||||
|
import { BEARER_TOKEN } from '$env/static/private'
|
||||||
import { IMAGE_DIR } from '$env/static/private'
|
import { IMAGE_DIR } from '$env/static/private'
|
||||||
import { unlink } from 'node:fs';
|
import { unlink } from 'node:fs';
|
||||||
import { error } from '@sveltejs/kit';
|
import { error } from '@sveltejs/kit';
|
||||||
import { authenticateUser } from '$lib/js/authenticate';;
|
|
||||||
|
|
||||||
export const POST = (async ({ request, cookies }) => {
|
export const POST = (async ({ request }) => {
|
||||||
const data = await request.json();
|
const data = await request.json();
|
||||||
const user = await authenticateUser(cookies)
|
if(data.bearer === BEARER_TOKEN){
|
||||||
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")
|
|
||||||
[ "full", "thumb", "placeholder"].forEach((folder) => {
|
[ "full", "thumb", "placeholder"].forEach((folder) => {
|
||||||
unlink(path.join(IMAGE_DIR, "rezepte", folder, data.name + ".webp"), (e) => {
|
unlink(path.join(IMAGE_DIR, "rezepte", folder, data.name + ".webp"), (e) => {
|
||||||
if(e) error(404, "could not delete: " + folder + "/" + data.name + ".webp" + e)
|
if(e) error(404, "could not delete: " + folder + "/" + data.name + ".webp" + e)
|
||||||
@ -18,4 +16,9 @@ export const POST = (async ({ request, cookies }) => {
|
|||||||
return new Response(JSON.stringify({msg: "Deleted image successfully"}),{
|
return new Response(JSON.stringify({msg: "Deleted image successfully"}),{
|
||||||
status: 200,
|
status: 200,
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
throw error(403, "Password incorrect")
|
||||||
|
}
|
||||||
|
|
||||||
}) satisfies RequestHandler;
|
}) satisfies RequestHandler;
|
||||||
|
@ -1,16 +1,13 @@
|
|||||||
import path from 'path'
|
import path from 'path'
|
||||||
import type { RequestHandler } from '@sveltejs/kit';
|
import type { RequestHandler } from '@sveltejs/kit';
|
||||||
|
import { BEARER_TOKEN } from '$env/static/private'
|
||||||
import { IMAGE_DIR } from '$env/static/private'
|
import { IMAGE_DIR } from '$env/static/private'
|
||||||
import { rename } from 'node:fs';
|
import { rename } from 'node:fs';
|
||||||
import { error } from '@sveltejs/kit';
|
import { error } from '@sveltejs/kit';
|
||||||
import { authenticateUser } from '$lib/js/authenticate';
|
|
||||||
|
|
||||||
export const POST = (async ({ request, cookies }) => {
|
|
||||||
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")
|
|
||||||
|
|
||||||
|
export const POST = (async ({ request }) => {
|
||||||
|
const data = await request.json();
|
||||||
|
if(data.bearer === BEARER_TOKEN){
|
||||||
[ "full", "thumb", "placeholder"].forEach((folder) => {
|
[ "full", "thumb", "placeholder"].forEach((folder) => {
|
||||||
const old_path = path.join(IMAGE_DIR, "rezepte", folder, data.old_name + ".webp")
|
const old_path = path.join(IMAGE_DIR, "rezepte", folder, data.old_name + ".webp")
|
||||||
rename(old_path, path.join(IMAGE_DIR, "rezepte", folder, data.new_name + ".webp"), (e) => {
|
rename(old_path, path.join(IMAGE_DIR, "rezepte", folder, data.new_name + ".webp"), (e) => {
|
||||||
@ -18,8 +15,12 @@ export const POST = (async ({ request, cookies }) => {
|
|||||||
if(e) throw error(500, "could not mv: " + old_path)
|
if(e) throw error(500, "could not mv: " + old_path)
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
return new Response(JSON.stringify({msg: "Deleted image successfully"}),{
|
return new Response(JSON.stringify({msg: "Deleted image successfully"}),{
|
||||||
status: 200,
|
status: 200,
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
throw error(403, "Password incorrect")
|
||||||
|
}
|
||||||
|
|
||||||
}) satisfies RequestHandler;
|
}) satisfies RequestHandler;
|
||||||
|
@ -1,45 +0,0 @@
|
|||||||
import type { RequestHandler } from '@sveltejs/kit';
|
|
||||||
import { error } from '@sveltejs/kit';
|
|
||||||
import { sign } from 'jsonwebtoken';
|
|
||||||
import { verify} from 'argon2';
|
|
||||||
import { COOKIE_SECRET } from '$env/static/private'
|
|
||||||
import { PEPPER } from '$env/static/private'
|
|
||||||
|
|
||||||
import { dbConnect, dbDisconnect } from '../../../utils/db';
|
|
||||||
import { User } from '../../../models/User';
|
|
||||||
|
|
||||||
// header: use for bearer token for now
|
|
||||||
// recipe json in body
|
|
||||||
export const POST: RequestHandler = async ({request}) => {
|
|
||||||
const {username, password} = await request.json()
|
|
||||||
await dbConnect()
|
|
||||||
let res = await User.findOne({username: username}, 'pass_hash salt').lean()
|
|
||||||
await dbDisconnect()
|
|
||||||
if(!res){
|
|
||||||
console.log("NOT FOUND")
|
|
||||||
throw error(401, {message: "wrong password or user does not exist"})
|
|
||||||
}
|
|
||||||
|
|
||||||
const stored_pw = res.pass_hash
|
|
||||||
const salt = res.salt
|
|
||||||
|
|
||||||
const isMatch = await verify(stored_pw, password + PEPPER, {salt})
|
|
||||||
if(!isMatch){
|
|
||||||
throw error(401, {message: "wrong password or user does not exist"})
|
|
||||||
}
|
|
||||||
|
|
||||||
res = await createJWT(username)
|
|
||||||
return new Response(JSON.stringify(res))
|
|
||||||
};
|
|
||||||
|
|
||||||
async function createJWT(username) {
|
|
||||||
const payload = {
|
|
||||||
username: username,
|
|
||||||
};
|
|
||||||
|
|
||||||
const masterSecret = COOKIE_SECRET;
|
|
||||||
const secretKey = masterSecret;
|
|
||||||
const jwt = sign(payload, secretKey);
|
|
||||||
console.log(jwt)
|
|
||||||
return jwt
|
|
||||||
}
|
|
@ -1,50 +0,0 @@
|
|||||||
import type { RequestHandler } from '@sveltejs/kit';
|
|
||||||
import { error } from '@sveltejs/kit';
|
|
||||||
import { hash } from 'argon2';
|
|
||||||
import { randomBytes } from 'crypto';
|
|
||||||
import { ALLOW_REGISTRATION } from '$env/static/private';
|
|
||||||
import { PEPPER } from '$env/static/private';
|
|
||||||
|
|
||||||
import { User } from '../../../models/User';
|
|
||||||
import { dbConnect, dbDisconnect } from '../../../utils/db';
|
|
||||||
|
|
||||||
// header: use for bearer token for now
|
|
||||||
// recipe json in body
|
|
||||||
export const POST: RequestHandler = async ({request}) => {
|
|
||||||
if(ALLOW_REGISTRATION){
|
|
||||||
const {username, password, access} = await request.json()
|
|
||||||
const salt = randomBytes(32).toString('hex'); // Generate a random salt
|
|
||||||
|
|
||||||
const pass_hash = await hashPassword(password + PEPPER, salt)
|
|
||||||
await dbConnect();
|
|
||||||
try{
|
|
||||||
await User.create({
|
|
||||||
username: username,
|
|
||||||
pass_hash: pass_hash,
|
|
||||||
salt: salt,
|
|
||||||
access: access,
|
|
||||||
})
|
|
||||||
}catch(e){
|
|
||||||
await dbDisconnect();
|
|
||||||
throw error(400, e);
|
|
||||||
}
|
|
||||||
await dbDisconnect();
|
|
||||||
return new Response(JSON.stringify({message: "User added successfully"}),
|
|
||||||
{status: 200}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
throw error(401, "user registration currently closed")
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
async function hashPassword(password, salt) {
|
|
||||||
try {
|
|
||||||
const hashedPassword = await hash(password, salt); // Hash the password with the salt and pepper
|
|
||||||
return hashedPassword;
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Error hashing password:', error);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,62 +0,0 @@
|
|||||||
import type { RequestHandler } from '@sveltejs/kit';
|
|
||||||
import { error } from '@sveltejs/kit';
|
|
||||||
import { verify } from 'jsonwebtoken';
|
|
||||||
import { hash} from 'argon2';
|
|
||||||
import { randomBytes } from 'crypto';
|
|
||||||
import { COOKIE_SECRET } from '$env/static/private'
|
|
||||||
import { ALLOW_REGISTRATION } from '$env/static/private'
|
|
||||||
|
|
||||||
import { User } from '../../../models/User';
|
|
||||||
import { dbConnect, dbDisconnect } from '../../../utils/db';
|
|
||||||
|
|
||||||
|
|
||||||
import { getJWTFromRequest } from '../../../utils/cookie';
|
|
||||||
// header: use for bearer token for now
|
|
||||||
// recipe json in body
|
|
||||||
export const GET: RequestHandler = async ({request}) => {
|
|
||||||
const jwt = getJWTFromRequest(request)
|
|
||||||
|
|
||||||
// Set your master secret key (replace with your own secret)
|
|
||||||
const masterSecret = COOKIE_SECRET;
|
|
||||||
const secretKey = masterSecret
|
|
||||||
let decoded
|
|
||||||
try{
|
|
||||||
decoded = await verify(jwt, secretKey);
|
|
||||||
}
|
|
||||||
catch(e){
|
|
||||||
throw error(401, "Cookies have changed, please log in again")
|
|
||||||
}
|
|
||||||
|
|
||||||
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 new Response(JSON.stringify({
|
|
||||||
username: decoded.username,
|
|
||||||
access: res.access
|
|
||||||
}), {status: 200})
|
|
||||||
};
|
|
||||||
|
|
||||||
async function hashPassword(password, salt) {
|
|
||||||
try {
|
|
||||||
const hashedPassword = await hash(password, salt); // Hash the password with the salt
|
|
||||||
return hashedPassword;
|
|
||||||
} catch (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
|
|
||||||
}
|
|
@ -35,6 +35,4 @@ h1{
|
|||||||
</MediaScroller>
|
</MediaScroller>
|
||||||
{/each}
|
{/each}
|
||||||
<p>{data.all_brief.length}</p>
|
<p>{data.all_brief.length}</p>
|
||||||
{#if data.user && data.user.access.includes("rezepte")}
|
<AddButton></AddButton>
|
||||||
<AddButton></AddButton>
|
|
||||||
{/if}
|
|
@ -1,6 +1,6 @@
|
|||||||
import type { PageServerLoad } from "./$types";
|
import type { PageLoad } from "./$types";
|
||||||
|
|
||||||
export async function load({ fetch, locals }) {
|
export async function load({ fetch }) {
|
||||||
let current_month = new Date().getMonth() + 1
|
let current_month = new Date().getMonth() + 1
|
||||||
const res_season = await fetch(`/api/items/in_season/` + current_month);
|
const res_season = await fetch(`/api/items/in_season/` + current_month);
|
||||||
const res_all_brief = await fetch(`/api/items/all_brief`);
|
const res_all_brief = await fetch(`/api/items/all_brief`);
|
||||||
@ -9,6 +9,5 @@ export async function load({ fetch, locals }) {
|
|||||||
return {
|
return {
|
||||||
season: item_season,
|
season: item_season,
|
||||||
all_brief: item_all_brief,
|
all_brief: item_all_brief,
|
||||||
user: locals.user,
|
|
||||||
};
|
};
|
||||||
};
|
};
|
@ -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;
|
||||||
|
|
||||||
@ -242,6 +242,4 @@ h4{
|
|||||||
</div>
|
</div>
|
||||||
</TitleImgParallax>
|
</TitleImgParallax>
|
||||||
|
|
||||||
{#if data.user && data.user.access.includes("rezepte")}
|
|
||||||
<EditButton href="/rezepte/edit/{data.short_name}"></EditButton>
|
<EditButton href="/rezepte/edit/{data.short_name}"></EditButton>
|
||||||
{/if}
|
|
@ -4,10 +4,9 @@ import type { PageLoad } from "./$types";
|
|||||||
//import { dbConnect, dbDisconnect } from '../../../utils/db';
|
//import { dbConnect, dbDisconnect } from '../../../utils/db';
|
||||||
import { error } from "@sveltejs/kit";
|
import { error } from "@sveltejs/kit";
|
||||||
|
|
||||||
export async function load({ fetch, params, locals }) {
|
export async function load({ fetch, params }) {
|
||||||
const res = await fetch(`/api/items/${params.name}`);
|
const res = await fetch(`/api/items/${params.name}`);
|
||||||
let item = await res.json();
|
const item = await res.json();
|
||||||
item.user = locals.user
|
|
||||||
if(res.status != 200){
|
if(res.status != 200){
|
||||||
throw error(res.status, item.message)
|
throw error(res.status, item.message)
|
||||||
}
|
}
|
@ -47,6 +47,7 @@
|
|||||||
cooking: "",
|
cooking: "",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let password = ""
|
||||||
let images = []
|
let images = []
|
||||||
let short_name = ""
|
let short_name = ""
|
||||||
let datecreated = new Date()
|
let datecreated = new Date()
|
||||||
@ -85,13 +86,14 @@
|
|||||||
const data = {
|
const data = {
|
||||||
image: img_local,
|
image: img_local,
|
||||||
name: short_name,
|
name: short_name,
|
||||||
|
bearer: password,
|
||||||
}
|
}
|
||||||
await fetch(`/api/img/add`, {
|
await fetch(`/api/img/add`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
Accept: 'application/json',
|
Accept: 'application/json',
|
||||||
credentials: 'include',
|
bearer: password,
|
||||||
},
|
},
|
||||||
body: JSON.stringify(data)
|
body: JSON.stringify(data)
|
||||||
});
|
});
|
||||||
@ -239,25 +241,6 @@ h1{
|
|||||||
h3{
|
h3{
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
button.action_button{
|
|
||||||
animation: unset !important;
|
|
||||||
font-size: 1.3rem;
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
.submit_buttons{
|
|
||||||
display: flex;
|
|
||||||
margin-inline: auto;
|
|
||||||
max-width: 1000px;
|
|
||||||
margin-block: 1rem;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
gap: 2rem;
|
|
||||||
}
|
|
||||||
.submit_buttons p{
|
|
||||||
padding: 0;
|
|
||||||
padding-right: 0.5em;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
<h1>Rezept erstellen</h1>
|
<h1>Rezept erstellen</h1>
|
||||||
|
|
||||||
@ -292,6 +275,8 @@ button.action_button{
|
|||||||
<div class=addendum bind:innerText={addendum} contenteditable></div>
|
<div class=addendum bind:innerText={addendum} contenteditable></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class=submit_buttons>
|
<div class=submit_wrapper>
|
||||||
<button class=action_button on:click={doPost}><p>Hinzufügen</p><Check fill=white width=2rem height=2rem></Check></button>
|
<h2>Neues Rezept hinzufügen:</h2>
|
||||||
|
<input type="password" placeholder=Passwort bind:value={password}>
|
||||||
|
<button class=action_button on:click={doPost}><Check fill=white width=2rem height=2rem></Check></button>
|
||||||
</div>
|
</div>
|
@ -59,6 +59,7 @@
|
|||||||
let images = data.recipe.images
|
let images = data.recipe.images
|
||||||
|
|
||||||
let short_name = data.recipe.short_name
|
let short_name = data.recipe.short_name
|
||||||
|
let password
|
||||||
let datecreated = data.recipe.datecreated
|
let datecreated = data.recipe.datecreated
|
||||||
let datemodified = new Date()
|
let datemodified = new Date()
|
||||||
|
|
||||||
@ -98,10 +99,10 @@
|
|||||||
method: 'POST',
|
method: 'POST',
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
name: old_short_name,
|
name: old_short_name,
|
||||||
}),
|
bearer: password,}),
|
||||||
headers : {
|
headers : {
|
||||||
'content-type': 'application/json',
|
'content-type': 'application/json',
|
||||||
credentials: 'include',
|
bearer: password
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
if(!res_img.ok){
|
if(!res_img.ok){
|
||||||
@ -116,6 +117,7 @@
|
|||||||
old_short_name,
|
old_short_name,
|
||||||
headers: {
|
headers: {
|
||||||
'content-type': 'application/json',
|
'content-type': 'application/json',
|
||||||
|
bearer: password,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -143,10 +145,11 @@
|
|||||||
method: 'POST',
|
method: 'POST',
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
name: old_short_name,
|
name: old_short_name,
|
||||||
|
bearer: password,
|
||||||
}),
|
}),
|
||||||
headers : {
|
headers : {
|
||||||
'content-type': 'application/json',
|
'content-type': 'application/json',
|
||||||
credentials: 'include',
|
bearer: password
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
if(!res.ok){
|
if(!res.ok){
|
||||||
@ -158,13 +161,14 @@
|
|||||||
const data = {
|
const data = {
|
||||||
image: img_local,
|
image: img_local,
|
||||||
name: short_name,
|
name: short_name,
|
||||||
|
bearer: password,
|
||||||
}
|
}
|
||||||
const res = await fetch(`/api/img/add`, {
|
const res = await fetch(`/api/img/add`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
Accept: 'application/json',
|
Accept: 'application/json',
|
||||||
credentials: 'include',
|
bearer: password,
|
||||||
},
|
},
|
||||||
body: JSON.stringify(data)
|
body: JSON.stringify(data)
|
||||||
});
|
});
|
||||||
@ -179,16 +183,18 @@
|
|||||||
// case new short_name:
|
// case new short_name:
|
||||||
else if(short_name != old_short_name){
|
else if(short_name != old_short_name){
|
||||||
console.log("MOVING")
|
console.log("MOVING")
|
||||||
|
console.log("PASSWORD:", password)
|
||||||
const res_img = await fetch('/api/img/mv', {
|
const res_img = await fetch('/api/img/mv', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
Accept: 'application/json',
|
Accept: 'application/json',
|
||||||
credentials: 'include',
|
bearer: password,
|
||||||
},
|
},
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
old_name: old_short_name,
|
old_name: old_short_name,
|
||||||
new_name: short_name,
|
new_name: short_name,
|
||||||
|
bearer: password,
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
if(!res_img.ok){
|
if(!res_img.ok){
|
||||||
@ -217,7 +223,7 @@
|
|||||||
old_short_name,
|
old_short_name,
|
||||||
headers: {
|
headers: {
|
||||||
'content-type': 'application/json',
|
'content-type': 'application/json',
|
||||||
credentials: 'include',
|
bearer: password,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@ -264,6 +270,26 @@ input:focus-visible
|
|||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
input[type=password]{
|
||||||
|
box-sizing: border-box;
|
||||||
|
font-size: 1.5rem;
|
||||||
|
padding-block: 0.5em;
|
||||||
|
display: inline;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.submit_wrapper{
|
||||||
|
position: relative;
|
||||||
|
margin-inline: auto;
|
||||||
|
width: max(300px, 50vw)
|
||||||
|
}
|
||||||
|
.submit_wrapper button{
|
||||||
|
position: absolute;
|
||||||
|
right:-1em;
|
||||||
|
bottom: -0.5em;
|
||||||
|
}
|
||||||
|
.submit_wrapper h2{
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
h1{
|
h1{
|
||||||
text-align: center;
|
text-align: center;
|
||||||
margin-bottom: 2rem;
|
margin-bottom: 2rem;
|
||||||
@ -314,27 +340,9 @@ h1{
|
|||||||
h3{
|
h3{
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
button.action_button{
|
|
||||||
animation: unset !important;
|
|
||||||
font-size: 1.3rem;
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
.submit_buttons{
|
|
||||||
display: flex;
|
|
||||||
margin-inline: auto;
|
|
||||||
max-width: 1000px;
|
|
||||||
margin-block: 1rem;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
gap: 2rem;
|
|
||||||
}
|
|
||||||
.submit_buttons p{
|
|
||||||
padding: 0;
|
|
||||||
padding-right: 0.5em;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
</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>
|
||||||
@ -366,7 +374,14 @@ button.action_button{
|
|||||||
<div class=addendum bind:innerText={addendum} contenteditable></div>
|
<div class=addendum bind:innerText={addendum} contenteditable></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class=submit_buttons>
|
<div class=submit_wrapper>
|
||||||
<button class=action_button on:click={doDelete}><p>Löschen</p><Cross fill=white width=2rem height=2rem></Cross></button>
|
<h2>Editiertes Rezept abspeichern:</h2>
|
||||||
<button class=action_button on:click={doEdit}><p>Speichern</p><Check fill=white width=2rem height=2rem></Check></button>
|
<input type="password" placeholder=Passwort bind:value={password}>
|
||||||
|
<button class=action_button on:click={doEdit}><Check fill=white width=2rem height=2rem></Check></button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class=submit_wrapper>
|
||||||
|
<h2>Rezept löschen:</h2>
|
||||||
|
<input type="password" placeholder=Passwort bind:value={password}>
|
||||||
|
<button class=action_button on:click={doDelete}><Cross fill=white width=2rem height=2rem></Cross></button>
|
||||||
</div>
|
</div>
|
@ -1,10 +1,8 @@
|
|||||||
import type { PageLoad } from "./$types";
|
import type { PageLoad } from "./$types";
|
||||||
|
|
||||||
export async function load({ fetch, params, locals}) {
|
export async function load({ fetch, params}) {
|
||||||
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: recipe,
|
return {recipe};
|
||||||
user: locals.user
|
|
||||||
};
|
|
||||||
};
|
};
|
Loading…
x
Reference in New Issue
Block a user