diff --git a/src/error.html b/src/error.html index 73d0c64..e2222c7 100644 --- a/src/error.html +++ b/src/error.html @@ -1,4 +1,15 @@ + + + + + + + + +

Du wurdest automatisch ausgeloggt

Lösche deine Cookies aus dem Browser und logge dich neu ein

Code %sveltekit.status%

%sveltekit.error.message%

+ + diff --git a/src/lib/components/EditableItem.svelte b/src/lib/components/EditableItem.svelte new file mode 100644 index 0000000..c03acca --- /dev/null +++ b/src/lib/components/EditableItem.svelte @@ -0,0 +1,93 @@ + + +
+ + + + {#if manualError || error} +

{manualError || error}

+ {/if} +
diff --git a/src/lib/config.ts b/src/lib/config.ts index 0775514..2e2bf34 100644 --- a/src/lib/config.ts +++ b/src/lib/config.ts @@ -1,3 +1,3 @@ import { readFileSync } from 'fs'; -export default JSON.parse(readFileSync('./config.json').toString()); +export default JSON.parse(readFileSync('./config_prod.json').toString()); diff --git a/src/lib/helper/error-utils.ts b/src/lib/helper/error-utils.ts new file mode 100644 index 0000000..66cf1f2 --- /dev/null +++ b/src/lib/helper/error-utils.ts @@ -0,0 +1,27 @@ +/** + * + * @param oldValue + * @param inputValue + * @param options + * @returns + */ +export function validateNameInput(oldValue:string, inputValue: string, options: { minLength?: number; existingNames?: string[] }) { + const errors: string[] = []; + + if (!inputValue.trim()) errors.push('Feld darf nicht leer sein'); + if (options.existingNames?.includes(inputValue) && oldValue !== inputValue) + errors.push('Name existiert bereits'); + + return errors; +} + + +// siehe suche: fail + +// Button +// BaseInputField + +// fetch siehe b038 + +// api/list/vorgang/tatort/server.ts +// api/list/vorgang/server.ts diff --git a/src/lib/icons/Cube.svelte b/src/lib/icons/Cube.svelte index 4992960..ff56e24 100644 --- a/src/lib/icons/Cube.svelte +++ b/src/lib/icons/Cube.svelte @@ -1,10 +1,15 @@ + + => { }); }; -export const getContentOfTextObject = async (bucket: string, objPath: string) => { +export const getContentOfTextObject = async (bucket: string, objPath: string) => { //Was kriege ich da raus? const res = await client.getObject(bucket, objPath); const text = await new Response(res).text(); diff --git a/src/routes/(angemeldet)/list/+page.server.ts b/src/routes/(angemeldet)/list/+page.server.ts index 4d78120..0bc3bd8 100644 --- a/src/routes/(angemeldet)/list/+page.server.ts +++ b/src/routes/(angemeldet)/list/+page.server.ts @@ -2,9 +2,9 @@ import { getListOfVorgänge } from '$lib/server/vorgangService'; import type { PageServerLoad } from '../../(token-based)/view/$types'; export const load: PageServerLoad = async () => { - const caseList = await getListOfVorgänge(); + const vorgangList = getListOfVorgänge(); - return { - caseList - }; + return { + vorgangList + }; }; diff --git a/src/routes/(angemeldet)/list/+page.svelte b/src/routes/(angemeldet)/list/+page.svelte index b730a95..ff37cfa 100644 --- a/src/routes/(angemeldet)/list/+page.svelte +++ b/src/routes/(angemeldet)/list/+page.svelte @@ -1,11 +1,21 @@
@@ -44,29 +99,32 @@
diff --git a/src/routes/(angemeldet)/list/+page.ts b/src/routes/(angemeldet)/list/+page.ts new file mode 100644 index 0000000..2387d7c --- /dev/null +++ b/src/routes/(angemeldet)/list/+page.ts @@ -0,0 +1,23 @@ + +export async function load({ fetch }) { + +//const caseToken = url.searchParams.get('token'); + const adminRes = await fetch(`/api/user`) +const user = await adminRes.json() + +const res = await fetch(`/api/list`, { +/* headers: { + Authorization: `Bearer ${caseToken}` + } */ +}); + + const data = await res.json(); + // console.log("Kay", data.caseList); + + const caseList = data.caseList + + return { + caseList, //{name, token} + user //für Abfrage ob eingeloggt + }; +}; diff --git a/src/routes/(angemeldet)/tatorte/+page.svelte b/src/routes/(angemeldet)/tatorte/+page.svelte index 44acb50..a61e0f0 100644 --- a/src/routes/(angemeldet)/tatorte/+page.svelte +++ b/src/routes/(angemeldet)/tatorte/+page.svelte @@ -1,4 +1,5 @@
-

Vorgang {$page.params.vorgang}

+

Vorgang {vorgang}

diff --git a/src/routes/(token-based)/list/[vorgang]/+page.ts b/src/routes/(token-based)/list/[vorgang]/+page.ts new file mode 100644 index 0000000..7165b9d --- /dev/null +++ b/src/routes/(token-based)/list/[vorgang]/+page.ts @@ -0,0 +1,34 @@ +// load für die Tatort-Liste +export async function load({ fetch, params, url }) { + + const caseId = params.vorgang; + const caseToken = url.searchParams.get('token'); + + const adminRes = await fetch(`/api/user`) +const user = await adminRes.json() + +const res = await fetch(`/api/list/${caseId}`, { + headers: { + Authorization: `Bearer ${caseToken}` + } +}); + +const data = await res.json(); + + +const crimesList = data.crimesList + + + + return { + caseId, + crimesList, + caseToken, + user + }; + + + + +}; + diff --git a/src/routes/(token-based)/list/[vorgang]/+server.ts b/src/routes/(token-based)/list/[vorgang]/+server.ts index 98611df..03b79b3 100644 --- a/src/routes/(token-based)/list/[vorgang]/+server.ts +++ b/src/routes/(token-based)/list/[vorgang]/+server.ts @@ -1,4 +1,4 @@ -import { client } from '$lib/minio'; +/* import { client } from '$lib/minio'; import { json } from '@sveltejs/kit'; @@ -33,3 +33,4 @@ export async function PUT({ request }: {request: Request}) { return json({ success: 'success' }, { status: 200 }); }; + */ diff --git a/src/routes/api/list/+server.ts b/src/routes/api/list/+server.ts new file mode 100644 index 0000000..6147da5 --- /dev/null +++ b/src/routes/api/list/+server.ts @@ -0,0 +1,27 @@ +import { getListOfVorgänge } from "$lib/server/vorgangService"; +import { json } from "@sveltejs/kit"; + + +//Get für die Vorgangsliste mit token, daher authorized Abfrage +export async function GET({locals, url, request}) { +/* if(!locals.user?.admin){ + return new Response('Unauthorized',{status: 401}) +} + + const urlToken = url.searchParams.get('token'); + const caseToken = request.headers.get('Authorization')?.replace('Bearer ', ''); + +if(!(urlToken || caseToken)) return new Response('Unauthorized', { status: 401 }); + */ + let caseList; + +try { + + caseList = await getListOfVorgänge(); +} catch (err) { + console.error('Fehler beim Laden der Liste:', err); +} + if(!caseList) return new Response(`Keine Liste vorhanden ${caseList}`, {status: 404}) + const data = {caseList} + return json(data) +} diff --git a/src/routes/api/list/[vorgang]/+server.ts b/src/routes/api/list/[vorgang]/+server.ts index 5a76090..ddd7e09 100644 --- a/src/routes/api/list/[vorgang]/+server.ts +++ b/src/routes/api/list/[vorgang]/+server.ts @@ -1,24 +1,120 @@ -import { client } from '$lib/minio'; +import { BUCKET, client } from '$lib/minio'; +import { getVorgangByCaseId } from '$lib/server/vorgangService'; +import type { RequestHandler } from '@sveltejs/kit'; +import { json } from '@sveltejs/kit'; -export async function DELETE({ params }) { - const vorgang = params.vorgang; +// Seite für die Vorgangs-Liste - const object_list = await new Promise((resolve, reject) => { - const res = []; - const items_str = client.listObjects('tatort', vorgang, true); +//Get für die Tatortliste mit token, daher authorized Abfrage +export async function GET({locals,request, params, url}) { +if(!locals.user?.admin){ + return new Response('Unauthorized',{status: 401}) +} + + const caseId = params.vorgang; + const urlToken = url.searchParams.get('token'); + const caseToken = request.headers.get('Authorization')?.replace('Bearer ', ''); + + +if(!(urlToken || caseToken)) return new Response('Unauthorized', { status: 401 }); + + + + + const crimesList = await getVorgangByCaseId(caseId); + const data = { + caseId, + crimesList, + caseToken + } + return json(data) +} + + + + +// rename operation +export const PUT: RequestHandler= async ({request, locals}) => { + if(!locals.user?.admin){ + return new Response('Forbidden', { status: 403 }); + } + +const { oldName, newName} = await request.json(); + + if (!newName || !newName.trim()) { + return new Response('Ungültiger Name', { status: 400 }); + } + + + + try { + const stat = await client.statObject(BUCKET, newName).catch(()=> null) + if(stat){ + return json({ error: 'Datei mit dem neuen Namen existiert bereits.' }, { status: 409 }); + } + // 2. Kopieren + const Object_list:string[] = await new Promise((resolve, reject) => { + const res: string[] = []; + const items_str = client.listObjects(BUCKET, oldName, true); + + + +items_str.on('data', (obj) => { + if (obj.name) res.push(obj.name); +}); + +items_str.on('error', reject); + +items_str.on('end', async () => { + try { + for (const oldKey of res) { + +const oldPath = `${oldName}/`; +const newPath = `${newName}/`; +const newKey = oldKey.replace(oldPath, newPath); + await client.copyObject(BUCKET, newKey, `/${BUCKET}/${oldKey}`); + } + resolve(res); + } catch (err) { + reject(err); + } +}); + }); + + + + //3. Löschen + await client.removeObjects(BUCKET, Object_list) + const data = { success: true, message: 'Datei erfolgreich umbenannt.' } + + return json(data, { status: 200 }); + } catch (err) { + console.error('Fehler beim Umbenennen', err) + return json({error: `Fehler beim Umbenennen der Datei ${oldName} zu ${newName}`}, {status: 500}) + } + +}; + +export const DELETE: RequestHandler = async ({ request })=> { //body: {request}, keine params // params= de?param1=value¶ms2 + // const vorgang = params.vorgang; + const { vorgang } = await request.json(); + + const object_list:string[] = await new Promise((resolve, reject) => { + const res: string[] = []; + const items_str = client.listObjects(BUCKET, vorgang, true); items_str.on('data', (obj) => { - res.push(obj.name); - }); + if(obj.name) res.push(obj.name); + }); - items_str.on('error', reject); + items_str.on('error', reject); - items_str.on('end', async () => { + items_str.on('end', async () => { resolve(res); }); - }); + }); await client.removeObjects('tatort', object_list); - return new Response(null, { status: 204 }); -} + return new Response(null, { status: 204 }); + } diff --git a/src/routes/api/list/[vorgang]/[tatort]/+server.ts b/src/routes/api/list/[vorgang]/[tatort]/+server.ts index 73f9033..933848f 100644 --- a/src/routes/api/list/[vorgang]/[tatort]/+server.ts +++ b/src/routes/api/list/[vorgang]/[tatort]/+server.ts @@ -1,5 +1,9 @@ import { BUCKET, client } from '$lib/minio'; +import type { RequestHandler } from '@sveltejs/kit'; +import { json } from '@sveltejs/kit'; + +// Seite für die Tatorte-Liste export async function GET() { const stream = client.listObjectsV2(BUCKET, '', true); const result = new ReadableStream({ @@ -21,15 +25,51 @@ export async function GET() { 'content-type': 'text/event-stream' } }); + } +export const PUT: RequestHandler= async ({request, locals}) => { -export async function DELETE({ request }: { request: Request }) { - const url_fragments = request.url.split('/'); - const item = url_fragments.at(-1); - const vorgang = url_fragments.at(-2); + if(!locals.user?.admin){ + return new Response('Forbidden', { status: 403 }); + } + const {vorgang, oldName, newName} = await request.json(); + + if (!newName || !newName.trim()) { + return new Response('Ungültiger Name', { status: 400 }); + } + + + const oldKey = `${vorgang}/${oldName}`; + const newKey = `${vorgang}/${newName}`; + console.log("PUT Tatorte-Liste: ", vorgang, oldKey, newKey); + try { + const stat = await client.statObject(BUCKET, newKey).catch(()=> null) + if(stat){ + return json({ error: 'Datei mit dem neuen Namen existiert bereits.' }, { status: 409 }); + } + + // 2. Kopieren + await client.copyObject(BUCKET, newKey, `/${BUCKET}/${oldKey}`); + //3. Löschen + await client.removeObject(BUCKET, oldKey) + const data = { success: true, message: 'Datei erfolgreich umbenannt.' } + return json(data); + } catch (err) { + console.error('Fehler beim Umbenennen', err) + return json({error: 'Fehler beim Umbenennen der Datei'}, {status: 500}) + } - await client.removeObject(BUCKET, `${vorgang}/${item}`); - return new Response(null, { status: 204 }); } + +export const DELETE: RequestHandler = async ({ request })=> { //body: {request}, keine params // params= de?param1=value¶ms2 + const url_fragments = request.url.split('/'); + const item = url_fragments.at(-1); + const vorgang = url_fragments.at(-2); + + await client.removeObject(BUCKET, `${vorgang}/${item}`); + return new Response(null, { status: 204 }); + +} + diff --git a/src/routes/api/user/+server.ts b/src/routes/api/user/+server.ts new file mode 100644 index 0000000..36ebdc5 --- /dev/null +++ b/src/routes/api/user/+server.ts @@ -0,0 +1,10 @@ +//Rollenabfrage ob Benutzer admin ist + +import { json } from "@sveltejs/kit"; + +export async function GET({locals}) { + const isAdmin = locals.user?.admin === true; + const data = {admin: isAdmin} + return json(data) + +}