diff --git a/src/lib/components/Header.svelte b/src/lib/components/Header.svelte index eb3d1d9..f6e49e0 100644 --- a/src/lib/components/Header.svelte +++ b/src/lib/components/Header.svelte @@ -21,7 +21,7 @@

Tatort

{#if data.user} -
+ +
+ + + + + + +{/if} + + diff --git a/src/routes/(angemeldet)/list/+page.server.ts b/src/routes/(angemeldet)/list/+page.server.ts index 2053a67..ab89231 100644 --- a/src/routes/(angemeldet)/list/+page.server.ts +++ b/src/routes/(angemeldet)/list/+page.server.ts @@ -1,7 +1,12 @@ import { getVorgaenge } from '$lib/server/vorgangService'; import type { PageServerLoad } from '../../(token-based)/view/$types'; +import { error } from '@sveltejs/kit'; + +export const load: PageServerLoad = async (event) => { + if (!event.locals.user) { + error(404, 'Not Found') + } -export const load: PageServerLoad = async () => { const vorgangList = getVorgaenge(); return { diff --git a/src/routes/(angemeldet)/upload/+page.server.ts b/src/routes/(angemeldet)/upload/+page.server.ts index dfa143c..8155608 100644 --- a/src/routes/(angemeldet)/upload/+page.server.ts +++ b/src/routes/(angemeldet)/upload/+page.server.ts @@ -1,6 +1,6 @@ import { Readable } from 'stream'; import { BUCKET, client } from '$lib/minio'; -import { fail } from '@sveltejs/kit'; +import { fail, error } from '@sveltejs/kit'; import { v4 as uuidv4 } from 'uuid'; import { db } from '$lib/server/dbService'; @@ -123,3 +123,10 @@ export const actions = { return { etag, error }; } }; + + +export const load: PageServerLoad = async (event) => { + if (!event.locals.user) { + error(404, 'Not found') + } +}; \ No newline at end of file diff --git a/src/routes/(angemeldet)/user-management/+page.server.ts b/src/routes/(angemeldet)/user-management/+page.server.ts new file mode 100644 index 0000000..0b4a194 --- /dev/null +++ b/src/routes/(angemeldet)/user-management/+page.server.ts @@ -0,0 +1,8 @@ +import type { PageServerLoad } from '../../(token-based)/view/$types'; +import { error } from '@sveltejs/kit'; + +export const load: PageServerLoad = async (event) => { + if (!event.locals.user) { + error(404, 'Not Found') + } +}; diff --git a/src/routes/anmeldung/+page.server.ts b/src/routes/anmeldung/+page.server.ts index a4d6007..e5bc90c 100644 --- a/src/routes/anmeldung/+page.server.ts +++ b/src/routes/anmeldung/+page.server.ts @@ -1,19 +1,23 @@ import { dev } from '$app/environment'; -import { loginUser, logoutUser } from '$lib/server/authService'; -import { redirect } from '@sveltejs/kit'; +import { error, fail, redirect } from '@sveltejs/kit'; import { ROUTE_NAMES } from '../index.js'; +import { vorgangPINValidation } from '$lib/server/vorgangService.js'; export const actions = { - login: ({ request, cookies }) => loginUser({ request, cookies }), - logout: (event) => logoutUser(event), - getVorgangByToken: async ({ request, cookies }) => { + default: async ({ request, cookies }) => { const data = await request.formData(); const vorgangToken = data.get('vorgang-token'); - const vorgangPIN = data.get('vorgang-pin'); + const vorgangPIN = data.get('vorgang-pin') as string; - if (!vorgangToken || !vorgangPIN) return; + if (!vorgangPIN) { + return fail(400, { message: 'Bitte einen PIN eingeben.'}); + } - const COOKIE_NAME = `token-${vorgangToken}` + if (!vorgangPINValidation(vorgangToken, vorgangPIN)) { + return fail(400, { message: 'Falsche Zugangsdaten.'}); + } + + const COOKIE_NAME = `token-${vorgangToken}`; cookies.set(COOKIE_NAME, vorgangPIN, { path: '/', httpOnly: true, @@ -24,3 +28,8 @@ export const actions = { throw redirect(303, ROUTE_NAMES.VORGANG(vorgangToken)); } } as const; + +export const load: PageServerLoad = async ({ url }) => { + const vorgang = url.searchParams.get('vorgang'); + if (!vorgang) error(404, "Not Found"); +}; \ No newline at end of file diff --git a/src/routes/anmeldung/+page.svelte b/src/routes/anmeldung/+page.svelte index b2a1d24..5d774ee 100644 --- a/src/routes/anmeldung/+page.svelte +++ b/src/routes/anmeldung/+page.svelte @@ -1,22 +1,15 @@ +{#if vorgangToken}
Landeswappen Niedersachsen @@ -28,73 +21,30 @@
-
- -
- -
-
- -
- + +
+ +
+ +
+ {#if form?.message} +

{form.message}

+ {/if} + +
+ +
+
+
-
- -
- - Anmelden - -
-
- -
- -
-
- -
- -
- -
-
- -
- -
-
-
- -
+{/if} \ No newline at end of file diff --git a/src/routes/index.ts b/src/routes/index.ts index a8c3603..f7b5f00 100644 --- a/src/routes/index.ts +++ b/src/routes/index.ts @@ -16,8 +16,8 @@ export const ROUTE_NAMES = { // Anmeldung: actions ANMELDUNG: '/anmeldung', - ANMELDUNG_LOGIN: '/anmeldung?/login', - ANMELDUNG_LOGOUT: '/anmeldung?/logout', + LOGIN: '/?/login', + LOGOUT: '/?/logout', ANMELDUNG_GET_VORGANG_BY_TOKEN: '/anmeldung?/getVorgangByToken', ANMELDUNG_VORGANG_PARAM: (vorgangToken: string) => `/anmeldung?vorgang=${vorgangToken}` }; diff --git a/tests/views/Anmeldung.test.ts b/tests/views/Anmeldung.test.ts index 96cf9b3..48fb893 100644 --- a/tests/views/Anmeldung.test.ts +++ b/tests/views/Anmeldung.test.ts @@ -1,144 +1,143 @@ import { describe, it, expect, vi } from 'vitest'; -import { actions } from '$root/routes/anmeldung/+page.server'; -import { load } from '$root/routes/(token-based)/+layout.server' +// import { actions } from '$root/routes/anmeldung/+page.server'; +// import { load } from '$root/routes/(token-based)/+layout.server' +import { actions } from '../../src/routes/anmeldung/+page.server'; +import { load } from '../../src/routes/(token-based)/+layout.server'; import { baseData } from '../fixtures'; import { ROUTE_NAMES } from '../../src/routes'; import { dev } from '$app/environment'; import { vorgangExists, vorgangPINValidation } from '$lib/server/vorgangService'; -import { Redirect } from '@sveltejs/kit'; +import type { Redirect } from '@sveltejs/kit'; vi.mock('$lib/server/vorgangService', () => ({ vorgangExists: vi.fn(), - vorgangPINValidation: vi.fn(), + vorgangPINValidation: vi.fn() })); describe('Vorgang Anzeige via Token', () => { - it('Setze Cookie nach erfolgreicher Eingabe', async () => { - // Mock formData - const vorgObj = baseData.vorgang; + it('Setze Cookie nach erfolgreicher Eingabe', async () => { + // Mock formData + const vorgObj = baseData.vorgang; - const formData = new FormData(); - formData.set('vorgang-token', vorgObj.vorgangToken); - formData.set('vorgang-pin', vorgObj.vorgangPIN); + const formData = new FormData(); + formData.set('vorgang-token', vorgObj.vorgangToken); + formData.set('vorgang-pin', vorgObj.vorgangPIN); - const mockRequest = { - formData: vi.fn().mockResolvedValue(formData) - }; + const mockRequest = { + formData: vi.fn().mockResolvedValue(formData) + }; + vi.mocked(vorgangPINValidation).mockReturnValueOnce(true); - const cookiesSet = vi.fn(); + const cookiesSet = vi.fn(); - const event = { - request: mockRequest, - cookies: { - set: cookiesSet - } - }; + const event = { + request: mockRequest, + cookies: { + set: cookiesSet + } + }; - let thrownRedirect: Redirect | undefined; - try { - await actions.getVorgangByToken(event); - } catch (e) { - thrownRedirect = e as Redirect; - } + let thrownRedirect: Redirect | undefined; + try { + await actions.default(event); + } catch (e) { + thrownRedirect = e as Redirect; + } - // Redirect bei erfolgreicher Eingabe - expect(thrownRedirect?.status).toBe(303); - expect(thrownRedirect?.location).toBe(ROUTE_NAMES.VORGANG(vorgObj.vorgangToken)); + // Redirect bei erfolgreicher Eingabe + expect(thrownRedirect?.status).toBe(303); + expect(thrownRedirect?.location).toBe(ROUTE_NAMES.VORGANG(vorgObj.vorgangToken)); - // Cookie wurde gesetzt - const COOKIE_NAME = `token-${vorgObj.vorgangToken}` - expect(cookiesSet).toHaveBeenCalledWith(COOKIE_NAME, vorgObj.vorgangPIN, { - path: '/', + // Cookie wurde gesetzt + const COOKIE_NAME = `token-${vorgObj.vorgangToken}`; + expect(cookiesSet).toHaveBeenCalledWith(COOKIE_NAME, vorgObj.vorgangPIN, { + path: '/', httpOnly: true, sameSite: 'strict', secure: !dev - }); - }); + }); + }); - it('Schlägt fehl wenn keine Daten übergeben werden', async () => { - const formData = new FormData(); // no data - - const mockRequest = { - formData: vi.fn().mockResolvedValue(formData) - }; - - const cookiesSet = vi.fn(); - - const event = { - request: mockRequest, - cookies: { - set: cookiesSet - } - }; - - const result = await actions.getVorgangByToken(event); - - expect(result).toBeUndefined(); - - // Cookie wird nicht gesetzt - expect(cookiesSet).not.toHaveBeenCalled(); - }); + it('Schlägt fehl wenn keine Daten übergeben werden', async () => { + const formData = new FormData(); // no data + const mockRequest = { + formData: vi.fn().mockResolvedValue(formData) + }; + const cookiesSet = vi.fn(); + const event = { + request: mockRequest, + cookies: { + set: cookiesSet + } + }; + const result = await actions.default(event); + expect(result.status).toBe(400); + expect(result.data.message).toMatch(/PIN eingeben/i); + // Cookie wird nicht gesetzt + expect(cookiesSet).not.toHaveBeenCalled(); + }); + it.todo('Überprüfe was passiert, wenn Eingabe falsch, bzw. nicht im System passend gefunden'); }); describe('Teste Guard', () => { - it('Lese Cookie aus', async () => { - const vorgObj = baseData.vorgang; + it('Lese Cookie aus', async () => { + const vorgObj = baseData.vorgang; - const COOKIE_NAME = `token-${vorgObj.vorgangToken}` - const cookiesGet = vi.fn().mockImplementation((key: string) => { - if (key === COOKIE_NAME) return vorgObj.vorgangPIN; - return undefined; - }); + const COOKIE_NAME = `token-${vorgObj.vorgangToken}`; + const cookiesGet = vi.fn().mockImplementation((key: string) => { + if (key === COOKIE_NAME) return vorgObj.vorgangPIN; + return undefined; + }); + // mocked objects + const event = { + cookies: { + get: cookiesGet + }, + locals: {}, + params: { vorgang: vorgObj.vorgangToken } + }; + vi.mocked(vorgangExists).mockReturnValueOnce(true); + vi.mocked(vorgangPINValidation).mockReturnValueOnce(true); - // mocked objects - const event = { - cookies: { - get: cookiesGet - }, - locals: {}, - params: {vorgang: vorgObj.vorgangToken} - }; - vi.mocked(vorgangExists).mockReturnValueOnce(true); - vi.mocked(vorgangPINValidation).mockReturnValueOnce(true); + await load(event); - await load(event); + expect(cookiesGet).toHaveBeenCalledWith(COOKIE_NAME); + }); - expect(cookiesGet).toHaveBeenCalledWith(COOKIE_NAME); - }); + it('Kein Cookie gesetzt', async () => { + const vorgObj = baseData.vorgang; - it('Kein Cookie gesetzt', async () => { - const vorgObj = baseData.vorgang; + const COOKIE_NAME = `token-${vorgObj.vorgangToken}`; + const cookiesGet = vi.fn().mockImplementation((key: string) => { + if (key === COOKIE_NAME) return vorgObj.vorgangPIN; + return undefined; + }); - const COOKIE_NAME = `token-${vorgObj.vorgangToken}` - const cookiesGet = vi.fn().mockImplementation((key: string) => { - if (key === COOKIE_NAME) return vorgObj.vorgangPIN; - return undefined; - }); + // mocked objects + const event = { + cookies: { + get: cookiesGet + }, + locals: {}, + params: { vorgang: vorgObj.vorgangToken } + }; + vi.mocked(vorgangExists).mockReturnValueOnce(true); + vi.mocked(vorgangPINValidation).mockReturnValueOnce(false); + let thrownRedirect; + try { + await load(event); + throw new Error('Function did not throw'); + } catch (e) { + thrownRedirect = e; + } + expect(thrownRedirect?.status).toBe(303); + expect(thrownRedirect?.location).toBe( + ROUTE_NAMES.ANMELDUNG_VORGANG_PARAM(vorgObj.vorgangToken) + ); - // mocked objects - const event = { - cookies: { - get: cookiesGet - }, - locals: {}, - params: {vorgang: vorgObj.vorgangToken} - }; - vi.mocked(vorgangExists).mockReturnValueOnce(true); - vi.mocked(vorgangPINValidation).mockReturnValueOnce(false); - - let thrownRedirect; - try { - await load(event); - throw new Error('Function did not throw') - } catch (e) { - thrownRedirect = e; - } - expect(thrownRedirect?.status).toBe(303); - expect(thrownRedirect?.location).toBe(ROUTE_NAMES.ANMELDUNG_VORGANG_PARAM(vorgObj.vorgangToken)); - - expect(cookiesGet).toHaveBeenCalledWith(COOKIE_NAME); - }); + expect(cookiesGet).toHaveBeenCalledWith(COOKIE_NAME); + }); }); diff --git a/tests/views/Layout.test.ts b/tests/views/Layout.test.ts index 0f329ef..9b79b3a 100644 --- a/tests/views/Layout.test.ts +++ b/tests/views/Layout.test.ts @@ -4,20 +4,15 @@ import { ROUTE_NAMES } from '../../src/routes'; import { baseData, mockEvent } from '../fixtures'; describe('+layout.server load(): Teste korrekte URL', () => { - test('Werfe redirect zu /anmeldung wenn User nicht eingeloggt', async () => { + test('Werfe keinen Redirect und gebe nichts zurück', async () => { const mockEvent = { locals: { user: null }, url: new URL(`https://example.com/not-anmeldung`) }; - try { - load(mockEvent); - throw new Error('Expected load() to throw'); - } catch (err) { - expect(err.status).toBe(303); - expect(err.location).toBe(ROUTE_NAMES.ANMELDUNG); - } + const res = load(mockEvent); + expect(res).toBe(undefined); }); });