First fully working user management, move to layout groups
This commit is contained in:
parent
70e640aa9a
commit
7dd52d8890
4
src/app.d.ts
vendored
4
src/app.d.ts
vendored
@ -1,9 +1,5 @@
|
||||
// See https://kit.svelte.dev/docs/types#app
|
||||
// for information about these interfaces
|
||||
declare module '@fortawesome/pro-solid-svg-icons/index.es' {
|
||||
export * from '@fortawesome/pro-solid-svg-icons';
|
||||
}
|
||||
|
||||
declare global {
|
||||
namespace App {
|
||||
// interface Error {}
|
||||
|
@ -4,7 +4,7 @@ import { redirect } from "@sveltejs/kit"
|
||||
import { error } from "@sveltejs/kit"
|
||||
|
||||
export const handle : Handle = async({event, resolve}) => {
|
||||
event.locals.user = await authenticateUser(event)
|
||||
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")
|
||||
|
@ -111,9 +111,6 @@ export function edit_ingredient_and_close_modal(){
|
||||
modal_el.close();
|
||||
}
|
||||
|
||||
export function show_keys(event){
|
||||
console.log(event.ctrlKey, event.key)
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
@ -122,7 +122,6 @@
|
||||
const item = await res.json();
|
||||
}
|
||||
async function doAdd () {
|
||||
console.log(add_info.total_time)
|
||||
const res = await fetch('/api/add', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({
|
||||
|
@ -14,7 +14,6 @@ const link_els = document.querySelectorAll("nav a")
|
||||
link_els.forEach((el) => {
|
||||
el.addEventListener("click", () => {toggle_sidebar(true)});
|
||||
})
|
||||
console.log(link_els)
|
||||
})
|
||||
|
||||
</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==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==custom_mul} on:click={(e) => { console.log(e) ;const el = e.composedPath()[0].children[0]; if(el){ el.focus()}}}>
|
||||
<button class:selected={multiplier==custom_mul} on:click={(e) => { const el = e.composedPath()[0].children[0]; if(el){ el.focus()}}}>
|
||||
<span class:selected={multiplier==custom_mul}
|
||||
on:focus={() => { custom_mul="" }
|
||||
}
|
||||
|
@ -47,7 +47,6 @@
|
||||
|
||||
const json = await res.json()
|
||||
result = JSON.stringify(json)
|
||||
console.log(result)
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
|
@ -5,7 +5,6 @@
|
||||
let months = ["Januar", "Februar", "März", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Dezember"]
|
||||
let month : number;
|
||||
export let active_index;
|
||||
console.log(active_index)
|
||||
|
||||
</script>
|
||||
<style>
|
||||
|
@ -5,9 +5,8 @@ import { error } from "@sveltejs/kit";
|
||||
import { dbConnect, dbDisconnect } from "../../utils/db";
|
||||
import { User } from "../../models/User";;
|
||||
|
||||
export async function authenticateUser(event: RequestEvent){
|
||||
export async function authenticateUser(cookies){
|
||||
// Set your master secret key (replace with your own secret)
|
||||
const { cookies } = event;
|
||||
const masterSecret = COOKIE_SECRET;
|
||||
const secretKey = masterSecret
|
||||
let decoded
|
||||
@ -19,7 +18,7 @@ export async function authenticateUser(event: RequestEvent){
|
||||
|
||||
}
|
||||
catch(e){
|
||||
throw error(401, "Cookies have changed, please log in again")
|
||||
return null
|
||||
}
|
||||
|
||||
if(decoded){
|
||||
|
14
src/routes/(main)/+layout.svelte
Normal file
14
src/routes/(main)/+layout.svelte
Normal file
@ -0,0 +1,14 @@
|
||||
<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>
|
18
src/routes/(main)/+page.svelte
Normal file
18
src/routes/(main)/+page.svelte
Normal file
@ -0,0 +1,18 @@
|
||||
<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>
|
10
src/routes/(main)/abrechnung/+page.svelte
Normal file
10
src/routes/(main)/abrechnung/+page.svelte
Normal file
@ -0,0 +1,10 @@
|
||||
<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>
|
16
src/routes/(main)/flims/+page.svelte
Normal file
16
src/routes/(main)/flims/+page.svelte
Normal file
@ -0,0 +1,16 @@
|
||||
<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,5 +1,6 @@
|
||||
import { redirect } from "@sveltejs/kit"
|
||||
import type { Actions, PageServerLoad } from "./$types"
|
||||
import { error } from "@sveltejs/kit"
|
||||
|
||||
export const load: PageServerLoad = async ({ locals }) => {
|
||||
return {
|
||||
@ -18,7 +19,8 @@ export const actions: Actions = {
|
||||
})
|
||||
}
|
||||
)
|
||||
const jwt = await res.json()
|
||||
const jwt = await res.json()
|
||||
if(res.ok){
|
||||
event.cookies.set("UserSession", jwt, {
|
||||
path: "/",
|
||||
httpOnly: true,
|
||||
@ -28,5 +30,12 @@ export const actions: Actions = {
|
||||
})
|
||||
|
||||
throw redirect(303, "/")
|
||||
}
|
||||
else{
|
||||
throw error(401, jwt.message)
|
||||
}
|
||||
},
|
||||
logout: async () => {
|
||||
throw redirect(303, "/logout")
|
||||
},
|
||||
}
|
13
src/routes/(main)/login/+page.svelte
Normal file
13
src/routes/(main)/login/+page.svelte
Normal file
@ -0,0 +1,13 @@
|
||||
<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>
|
7
src/routes/(main)/logout/+page.server.ts
Normal file
7
src/routes/(main)/logout/+page.server.ts
Normal file
@ -0,0 +1,7 @@
|
||||
import { redirect } from "@sveltejs/kit"
|
||||
import type { Actions, PageServerLoad } from "./$types"
|
||||
|
||||
export const load: PageServerLoad = async ({ cookies }) => {
|
||||
cookies.delete("UserSession")
|
||||
redirect(303, "/")
|
||||
}
|
12
src/routes/(main)/logout/+page.svelte
Normal file
12
src/routes/(main)/logout/+page.svelte
Normal file
@ -0,0 +1,12 @@
|
||||
<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>
|
33
src/routes/(main)/register/+page.server.ts
Normal file
33
src/routes/(main)/register/+page.server.ts
Normal file
@ -0,0 +1,33 @@
|
||||
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,5 +1,4 @@
|
||||
<script>
|
||||
import Header from '$lib/components/Header.svelte'
|
||||
import { setCookie } from 'svelte-cookie';
|
||||
|
||||
export async function createJWT() {
|
||||
@ -18,16 +17,8 @@
|
||||
<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>
|
||||
<h1>Register</h1>
|
||||
<form action="?/register" method=POST>
|
||||
<label>
|
||||
Username
|
||||
<input type="text" name="username">
|
||||
@ -36,7 +27,18 @@
|
||||
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">Log In</button>
|
||||
<button type="submit">Register</button>
|
||||
</form>
|
||||
</Header>
|
78
src/routes/(main)/test/+page.svelte
Normal file
78
src/routes/(main)/test/+page.svelte
Normal file
@ -0,0 +1,78 @@
|
||||
<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,6 +1,6 @@
|
||||
import type { PageLoad } from "./$types";
|
||||
import type { PageServerLoad } from "./$types";
|
||||
|
||||
export async function load({ fetch }) {
|
||||
export async function load({ fetch, locals }) {
|
||||
let current_month = new Date().getMonth() + 1
|
||||
const res_season = await fetch(`/api/items/in_season/` + current_month);
|
||||
const res_all_brief = await fetch(`/api/items/all_brief`);
|
||||
@ -9,5 +9,6 @@ export async function load({ fetch }) {
|
||||
return {
|
||||
season: item_season,
|
||||
all_brief: item_all_brief,
|
||||
user: locals.user,
|
||||
};
|
||||
};
|
@ -35,4 +35,6 @@ h1{
|
||||
</MediaScroller>
|
||||
{/each}
|
||||
<p>{data.all_brief.length}</p>
|
||||
<AddButton></AddButton>
|
||||
{#if data.user && data.user.access.includes("rezepte")}
|
||||
<AddButton></AddButton>
|
||||
{/if}
|
@ -4,9 +4,10 @@ import type { PageLoad } from "./$types";
|
||||
//import { dbConnect, dbDisconnect } from '../../../utils/db';
|
||||
import { error } from "@sveltejs/kit";
|
||||
|
||||
export async function load({ fetch, params }) {
|
||||
export async function load({ fetch, params, locals }) {
|
||||
const res = await fetch(`/api/items/${params.name}`);
|
||||
const item = await res.json();
|
||||
let item = await res.json();
|
||||
item.user = locals.user
|
||||
if(res.status != 200){
|
||||
throw error(res.status, item.message)
|
||||
}
|
@ -242,4 +242,6 @@ h4{
|
||||
</div>
|
||||
</TitleImgParallax>
|
||||
|
||||
{#if data.user && data.user.access.includes("rezepte")}
|
||||
<EditButton href="/rezepte/edit/{data.short_name}"></EditButton>
|
||||
{/if}
|
@ -47,7 +47,6 @@
|
||||
cooking: "",
|
||||
}
|
||||
|
||||
let password = ""
|
||||
let images = []
|
||||
let short_name = ""
|
||||
let datecreated = new Date()
|
||||
@ -86,14 +85,13 @@
|
||||
const data = {
|
||||
image: img_local,
|
||||
name: short_name,
|
||||
bearer: password,
|
||||
}
|
||||
await fetch(`/api/img/add`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
Accept: 'application/json',
|
||||
bearer: password,
|
||||
credentials: 'include',
|
||||
},
|
||||
body: JSON.stringify(data)
|
||||
});
|
||||
@ -241,6 +239,25 @@ h1{
|
||||
h3{
|
||||
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>
|
||||
<h1>Rezept erstellen</h1>
|
||||
|
||||
@ -275,8 +292,6 @@ h3{
|
||||
<div class=addendum bind:innerText={addendum} contenteditable></div>
|
||||
</div>
|
||||
|
||||
<div class=submit_wrapper>
|
||||
<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 class=submit_buttons>
|
||||
<button class=action_button on:click={doPost}><p>Hinzufügen</p><Check fill=white width=2rem height=2rem></Check></button>
|
||||
</div>
|
@ -59,7 +59,6 @@
|
||||
let images = data.recipe.images
|
||||
|
||||
let short_name = data.recipe.short_name
|
||||
let password
|
||||
let datecreated = data.recipe.datecreated
|
||||
let datemodified = new Date()
|
||||
|
||||
@ -99,10 +98,10 @@
|
||||
method: 'POST',
|
||||
body: JSON.stringify({
|
||||
name: old_short_name,
|
||||
bearer: password,}),
|
||||
}),
|
||||
headers : {
|
||||
'content-type': 'application/json',
|
||||
bearer: password
|
||||
credentials: 'include',
|
||||
}
|
||||
})
|
||||
if(!res_img.ok){
|
||||
@ -117,7 +116,6 @@
|
||||
old_short_name,
|
||||
headers: {
|
||||
'content-type': 'application/json',
|
||||
bearer: password,
|
||||
}
|
||||
})
|
||||
|
||||
@ -145,11 +143,10 @@
|
||||
method: 'POST',
|
||||
body: JSON.stringify({
|
||||
name: old_short_name,
|
||||
bearer: password,
|
||||
}),
|
||||
headers : {
|
||||
'content-type': 'application/json',
|
||||
bearer: password
|
||||
credentials: 'include',
|
||||
}
|
||||
})
|
||||
if(!res.ok){
|
||||
@ -161,14 +158,13 @@
|
||||
const data = {
|
||||
image: img_local,
|
||||
name: short_name,
|
||||
bearer: password,
|
||||
}
|
||||
const res = await fetch(`/api/img/add`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
Accept: 'application/json',
|
||||
bearer: password,
|
||||
credentials: 'include',
|
||||
},
|
||||
body: JSON.stringify(data)
|
||||
});
|
||||
@ -183,18 +179,16 @@
|
||||
// case new short_name:
|
||||
else if(short_name != old_short_name){
|
||||
console.log("MOVING")
|
||||
console.log("PASSWORD:", password)
|
||||
const res_img = await fetch('/api/img/mv', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
Accept: 'application/json',
|
||||
bearer: password,
|
||||
credentials: 'include',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
old_name: old_short_name,
|
||||
new_name: short_name,
|
||||
bearer: password,
|
||||
})
|
||||
})
|
||||
if(!res_img.ok){
|
||||
@ -223,7 +217,7 @@
|
||||
old_short_name,
|
||||
headers: {
|
||||
'content-type': 'application/json',
|
||||
bearer: password,
|
||||
credentials: 'include',
|
||||
}
|
||||
})
|
||||
})
|
||||
@ -270,26 +264,6 @@ input:focus-visible
|
||||
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{
|
||||
text-align: center;
|
||||
margin-bottom: 2rem;
|
||||
@ -340,6 +314,25 @@ h1{
|
||||
h3{
|
||||
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>
|
||||
<h1>Rezept editieren</h1>
|
||||
<CardAdd {card_data} {image_preview_url} ></CardAdd>
|
||||
@ -373,14 +366,7 @@ h3{
|
||||
<div class=addendum bind:innerText={addendum} contenteditable></div>
|
||||
</div>
|
||||
|
||||
<div class=submit_wrapper>
|
||||
<h2>Editiertes Rezept abspeichern:</h2>
|
||||
<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 class=submit_buttons>
|
||||
<button class=action_button on:click={doDelete}><p>Löschen</p><Cross fill=white width=2rem height=2rem></Cross></button>
|
||||
<button class=action_button on:click={doEdit}><p>Speichern</p><Check fill=white width=2rem height=2rem></Check></button>
|
||||
</div>
|
@ -1,32 +0,0 @@
|
||||
<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,28 +1,30 @@
|
||||
import type { RequestHandler } from '@sveltejs/kit';
|
||||
import { Recipe } from '../../../models/Recipe';
|
||||
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 { authenticateUser } from '$lib/js/authenticate';;
|
||||
// header: use for bearer token for now
|
||||
// recipe json in body
|
||||
export const POST: RequestHandler = async ({request}) => {
|
||||
let message = await request.json()
|
||||
const recipe_json = message.recipe
|
||||
const bearer_token = message.headers.bearer
|
||||
if(bearer_token === BEARER_TOKEN){
|
||||
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,
|
||||
});
|
||||
}
|
||||
else{
|
||||
throw error(403, "Password incorrect")
|
||||
}
|
||||
export const POST: RequestHandler = async ({request, cookies}) => {
|
||||
let message = await request.json()
|
||||
const recipe_json = message.recipe
|
||||
const user = await authenticateUser(cookies)
|
||||
if(!user){
|
||||
throw error(401, "Not logged in")
|
||||
}
|
||||
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,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
@ -2,23 +2,22 @@ import type { RequestHandler } from '@sveltejs/kit';
|
||||
import { Recipe } from '../../../models/Recipe';
|
||||
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 { authenticateUser } from '$lib/js/authenticate';
|
||||
// header: use for bearer token for now
|
||||
// recipe json in body
|
||||
export const POST: RequestHandler = async ({request}) => {
|
||||
let message = await request.json()
|
||||
const short_name = message.old_short_name
|
||||
const bearer_token = message.headers.bearer
|
||||
if(bearer_token === BEARER_TOKEN){
|
||||
await dbConnect();
|
||||
export const POST: RequestHandler = async ({request, cookies}) => {
|
||||
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 short_name = message.old_short_name
|
||||
await dbConnect();
|
||||
await Recipe.findOneAndDelete({short_name: short_name});
|
||||
await dbDisconnect();
|
||||
return new Response(JSON.stringify({msg: "Deleted recipe successfully"}),{
|
||||
status: 200,
|
||||
});
|
||||
}
|
||||
else{
|
||||
throw error(403, "Password incorrect")
|
||||
}
|
||||
}
|
||||
|
@ -2,16 +2,23 @@ import type { RequestHandler } from '@sveltejs/kit';
|
||||
import { Recipe } from '../../../models/Recipe';
|
||||
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 { authenticateUser } from '$lib/js/authenticate';
|
||||
// header: use for bearer token for now
|
||||
// recipe json in body
|
||||
export const POST: RequestHandler = async ({request}) => {
|
||||
export const POST: RequestHandler = async ({request, cookies}) => {
|
||||
let message = await request.json()
|
||||
const recipe_json = message.recipe
|
||||
const bearer_token = message.headers.bearer
|
||||
if(bearer_token === BEARER_TOKEN){
|
||||
await dbConnect();
|
||||
const user = await authenticateUser(cookies)
|
||||
console.log(user)
|
||||
if(!user){
|
||||
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 dbDisconnect();
|
||||
return new Response(JSON.stringify({msg: "Edited recipe successfully"}),{
|
||||
@ -19,7 +26,4 @@ export const POST: RequestHandler = async ({request}) => {
|
||||
});
|
||||
|
||||
}
|
||||
else{
|
||||
throw error(403, "Password incorrect")
|
||||
}
|
||||
};
|
||||
|
@ -1,13 +1,15 @@
|
||||
import path from 'path'
|
||||
import type { RequestHandler } from '@sveltejs/kit';
|
||||
import { BEARER_TOKEN } from '$env/static/private'
|
||||
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 }) => {
|
||||
const data = await request.json();
|
||||
if(data.bearer === BEARER_TOKEN){
|
||||
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 sufficient permissions for this")
|
||||
let full_res = new Buffer.from(data.image, 'base64')
|
||||
// reduce image size if over 500KB
|
||||
const MAX_SIZE_KB = 500
|
||||
@ -41,9 +43,4 @@ export const POST = (async ({ request }) => {
|
||||
return new Response(JSON.stringify({msg: "Added image successfully"}),{
|
||||
status: 200,
|
||||
});
|
||||
}
|
||||
else{
|
||||
throw error(403, "Password incorrect")
|
||||
}
|
||||
|
||||
}) satisfies RequestHandler;
|
||||
|
@ -1,13 +1,15 @@
|
||||
import path from 'path'
|
||||
import type { RequestHandler } from '@sveltejs/kit';
|
||||
import { BEARER_TOKEN } from '$env/static/private'
|
||||
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 }) => {
|
||||
const data = await request.json();
|
||||
if(data.bearer === BEARER_TOKEN){
|
||||
export const POST = (async ({ request, cookies }) => {
|
||||
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")
|
||||
[ "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)
|
||||
@ -16,9 +18,4 @@ export const POST = (async ({ request }) => {
|
||||
return new Response(JSON.stringify({msg: "Deleted image successfully"}),{
|
||||
status: 200,
|
||||
});
|
||||
}
|
||||
else{
|
||||
throw error(403, "Password incorrect")
|
||||
}
|
||||
|
||||
}) satisfies RequestHandler;
|
||||
|
@ -1,13 +1,16 @@
|
||||
import path from 'path'
|
||||
import type { RequestHandler } from '@sveltejs/kit';
|
||||
import { BEARER_TOKEN } from '$env/static/private'
|
||||
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 }) => {
|
||||
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) => {
|
||||
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) => {
|
||||
@ -15,12 +18,8 @@ export const POST = (async ({ request }) => {
|
||||
if(e) throw error(500, "could not mv: " + old_path)
|
||||
})
|
||||
});
|
||||
|
||||
return new Response(JSON.stringify({msg: "Deleted image successfully"}),{
|
||||
status: 200,
|
||||
});
|
||||
}
|
||||
else{
|
||||
throw error(403, "Password incorrect")
|
||||
}
|
||||
|
||||
}) satisfies RequestHandler;
|
||||
|
@ -1,8 +1,9 @@
|
||||
import type { RequestHandler } from '@sveltejs/kit';
|
||||
import { error } from '@sveltejs/kit';
|
||||
import { sign } from 'jsonwebtoken';
|
||||
import { hash, verify} from 'argon2';
|
||||
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';
|
||||
@ -15,13 +16,14 @@ export const POST: RequestHandler = async ({request}) => {
|
||||
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, {salt})
|
||||
const isMatch = await verify(stored_pw, password + PEPPER, {salt})
|
||||
if(!isMatch){
|
||||
throw error(401, {message: "wrong password or user does not exist"})
|
||||
}
|
||||
@ -38,5 +40,6 @@ async function createJWT(username) {
|
||||
const masterSecret = COOKIE_SECRET;
|
||||
const secretKey = masterSecret;
|
||||
const jwt = sign(payload, secretKey);
|
||||
console.log(jwt)
|
||||
return jwt
|
||||
}
|
||||
|
@ -1,10 +1,9 @@
|
||||
import type { RequestHandler } from '@sveltejs/kit';
|
||||
import { error } from '@sveltejs/kit';
|
||||
import { sign } from 'jsonwebtoken';
|
||||
import { hash, verify } from 'argon2';
|
||||
import { hash } from 'argon2';
|
||||
import { randomBytes } from 'crypto';
|
||||
import { COOKIE_SECRET } from '$env/static/private'
|
||||
import { ALLOW_REGISTRATION } from '$env/static/private'
|
||||
import { ALLOW_REGISTRATION } from '$env/static/private';
|
||||
import { PEPPER } from '$env/static/private';
|
||||
|
||||
import { User } from '../../../models/User';
|
||||
import { dbConnect, dbDisconnect } from '../../../utils/db';
|
||||
@ -16,7 +15,7 @@ export const POST: RequestHandler = async ({request}) => {
|
||||
const {username, password, access} = await request.json()
|
||||
const salt = randomBytes(32).toString('hex'); // Generate a random salt
|
||||
|
||||
const pass_hash = await hashPassword(password, salt)
|
||||
const pass_hash = await hashPassword(password + PEPPER, salt)
|
||||
await dbConnect();
|
||||
try{
|
||||
await User.create({
|
||||
@ -43,7 +42,7 @@ export const POST: RequestHandler = async ({request}) => {
|
||||
|
||||
async function hashPassword(password, salt) {
|
||||
try {
|
||||
const hashedPassword = await hash(password, salt); // Hash the password with the salt
|
||||
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 +0,0 @@
|
||||
{"terminal": "nvimterm"}
|
Loading…
Reference in New Issue
Block a user