Compare commits
3 Commits
e288d768bf
...
45b5a36d04
| Author | SHA1 | Date | |
|---|---|---|---|
| 45b5a36d04 | |||
| 4c4be8ba42 | |||
| 45bcce0fb2 |
@@ -50,7 +50,7 @@
|
|||||||
{#each vorgangList as vorgangItem}
|
{#each vorgangList as vorgangItem}
|
||||||
<li data-testid="test-list-item">
|
<li data-testid="test-list-item">
|
||||||
<a
|
<a
|
||||||
href="{ROUTE_NAMES.VORGANG(vorgangItem.vorgangToken, vorgangItem.vorgangPIN)}"
|
href="{ROUTE_NAMES.VORGANG(vorgangItem.vorgangToken)}"
|
||||||
class="flex justify-between gap-x-6 py-5"
|
class="flex justify-between gap-x-6 py-5"
|
||||||
>
|
>
|
||||||
<div class="flex gap-x-4">
|
<div class="flex gap-x-4">
|
||||||
|
|||||||
@@ -1,12 +1,9 @@
|
|||||||
import {
|
import { vorgangPINValidation, vorgangExists } from '$lib/server/vorgangService';
|
||||||
vorgangPINValidation,
|
|
||||||
vorgangExists
|
|
||||||
} from '$lib/server/vorgangService';
|
|
||||||
import { redirect } from '@sveltejs/kit';
|
import { redirect } from '@sveltejs/kit';
|
||||||
import type { PageServerLoad } from './list/[vorgang]/$types';
|
import type { PageServerLoad } from './list/[vorgang]/$types';
|
||||||
import { ROUTE_NAMES } from '..';
|
import { ROUTE_NAMES } from '..';
|
||||||
|
|
||||||
export const load: PageServerLoad = async ({ params, url, locals }) => {
|
export const load: PageServerLoad = async ({ params, cookies, locals }) => {
|
||||||
if (locals.user) {
|
if (locals.user) {
|
||||||
return {
|
return {
|
||||||
user: locals.user
|
user: locals.user
|
||||||
@@ -14,10 +11,12 @@ export const load: PageServerLoad = async ({ params, url, locals }) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const vorgangToken = params.vorgang;
|
const vorgangToken = params.vorgang;
|
||||||
const vorgangPIN = url.searchParams.get('pin');
|
const COOKIE_NAME = `token-${vorgangToken}`;
|
||||||
|
const vorgangPIN = cookies.get(COOKIE_NAME);
|
||||||
|
|
||||||
const isVorgangValid = vorgangExists(vorgangToken);
|
const isVorgangValid = vorgangExists(vorgangToken);
|
||||||
const isVorgangPINValid = vorgangPINValidation(vorgangToken, vorgangPIN);
|
const isVorgangPINValid = vorgangPINValidation(vorgangToken, vorgangPIN);
|
||||||
|
|
||||||
if (!isVorgangValid || !isVorgangPINValid) throw redirect(303, ROUTE_NAMES.ANMELDUNG_VORGANG_PARAM(vorgangToken));
|
if (!isVorgangValid || !isVorgangPINValid)
|
||||||
|
throw redirect(303, ROUTE_NAMES.ANMELDUNG_VORGANG_PARAM(vorgangToken));
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { dev } from '$app/environment';
|
||||||
import { loginUser, logoutUser } from '$lib/server/authService';
|
import { loginUser, logoutUser } from '$lib/server/authService';
|
||||||
import { redirect } from '@sveltejs/kit';
|
import { redirect } from '@sveltejs/kit';
|
||||||
import { ROUTE_NAMES } from '../index.js';
|
import { ROUTE_NAMES } from '../index.js';
|
||||||
@@ -5,13 +6,21 @@ import { ROUTE_NAMES } from '../index.js';
|
|||||||
export const actions = {
|
export const actions = {
|
||||||
login: ({ request, cookies }) => loginUser({ request, cookies }),
|
login: ({ request, cookies }) => loginUser({ request, cookies }),
|
||||||
logout: (event) => logoutUser(event),
|
logout: (event) => logoutUser(event),
|
||||||
getVorgangByToken: async ({ request }) => {
|
getVorgangByToken: async ({ request, cookies }) => {
|
||||||
const data = await request.formData();
|
const data = await request.formData();
|
||||||
const vorgangToken = data.get('vorgang-token');
|
const vorgangToken = data.get('vorgang-token');
|
||||||
const vorgangPIN = data.get('vorgang-pin');
|
const vorgangPIN = data.get('vorgang-pin');
|
||||||
|
|
||||||
if (!vorgangToken || !vorgangPIN) return;
|
if (!vorgangToken || !vorgangPIN) return;
|
||||||
|
|
||||||
throw redirect(303, ROUTE_NAMES.VORGANG(vorgangToken, vorgangPIN));
|
const COOKIE_NAME = `token-${vorgangToken}`
|
||||||
|
cookies.set(COOKIE_NAME, vorgangPIN, {
|
||||||
|
path: '/',
|
||||||
|
httpOnly: true,
|
||||||
|
sameSite: 'strict',
|
||||||
|
secure: !dev
|
||||||
|
});
|
||||||
|
|
||||||
|
throw redirect(303, ROUTE_NAMES.VORGANG(vorgangToken));
|
||||||
}
|
}
|
||||||
} as const;
|
} as const;
|
||||||
|
|||||||
@@ -11,14 +11,8 @@ export const ROUTE_NAMES = {
|
|||||||
USERMGMT: '/user-management',
|
USERMGMT: '/user-management',
|
||||||
|
|
||||||
// (token-based)
|
// (token-based)
|
||||||
// `pin` param is optional
|
VORGANG: (vorgangToken: string) => `/list/${vorgangToken}`,
|
||||||
VORGANG: (vorgangToken: string, vorgangPIN: string) =>
|
CRIME: (vorgangToken: string, tatort: string) => `/view/${vorgangToken}/${tatort}`,
|
||||||
vorgangPIN ? `/list/${vorgangToken}?pin=${vorgangPIN}` : `/list/${vorgangToken}`,
|
|
||||||
|
|
||||||
CRIME: (vorgangToken: string, tatort: string, vorgangPIN: string) =>
|
|
||||||
vorgangPIN
|
|
||||||
? `/view/${vorgangToken}/${tatort}?pin=${vorgangPIN}`
|
|
||||||
: `/view/${vorgangToken}/${tatort}`,
|
|
||||||
|
|
||||||
// Anmeldung: actions
|
// Anmeldung: actions
|
||||||
ANMELDUNG: '/anmeldung',
|
ANMELDUNG: '/anmeldung',
|
||||||
|
|||||||
143
tests/views/Anmeldung.test.ts
Normal file
143
tests/views/Anmeldung.test.ts
Normal file
@@ -0,0 +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 { baseData } from '../fixtures';
|
||||||
|
import { ROUTE_NAMES } from '../../src/routes';
|
||||||
|
import { dev } from '$app/environment';
|
||||||
|
import { vorgangExists, vorgangPINValidation } from '$lib/server/vorgangService';
|
||||||
|
|
||||||
|
vi.mock('$lib/server/vorgangService', () => ({
|
||||||
|
vorgangExists: vi.fn(),
|
||||||
|
vorgangPINValidation: vi.fn(),
|
||||||
|
}));
|
||||||
|
|
||||||
|
describe('Vorgang Anzeige via Token', () => {
|
||||||
|
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 mockRequest = {
|
||||||
|
formData: vi.fn().mockResolvedValue(formData)
|
||||||
|
};
|
||||||
|
|
||||||
|
const cookiesSet = vi.fn();
|
||||||
|
|
||||||
|
const event = {
|
||||||
|
request: mockRequest,
|
||||||
|
cookies: {
|
||||||
|
set: cookiesSet
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let thrownRedirect;
|
||||||
|
try {
|
||||||
|
await actions.getVorgangByToken(event);
|
||||||
|
} catch (e) {
|
||||||
|
thrownRedirect = e;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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: '/',
|
||||||
|
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();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Teste Guard', () => {
|
||||||
|
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;
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
|
||||||
|
expect(cookiesGet).toHaveBeenCalledWith(COOKIE_NAME);
|
||||||
|
});
|
||||||
|
|
||||||
|
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;
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -33,4 +33,13 @@ describe('Teste Links auf Korrektheit', () => {
|
|||||||
expect(linkElement).toBeInTheDocument();
|
expect(linkElement).toBeInTheDocument();
|
||||||
expect(linkElement).toHaveAttribute('href', expectedURL);
|
expect(linkElement).toHaveAttribute('href', expectedURL);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('Links enthalten keinen VorgangsPIN', () => {
|
||||||
|
const vorgListOneItem = baseData.vorgangList.slice(0, 1)
|
||||||
|
|
||||||
|
render(VorgangListPage, { props: { data: { ...baseData, vorgangList: vorgListOneItem } } });
|
||||||
|
const listItem = screen.getByTestId("test-list-item");
|
||||||
|
const linkElement = within(listItem).getByRole('link');
|
||||||
|
expect(linkElement.getAttribute('href')?.toLowerCase()).not.toContain('pin');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user