From 8e2cbe9aa1fb38731a0115cadbfd5648e8655766 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aleksa=20Siri=C5=A1ki?= <31509435+aleksasiriski@users.noreply.github.com> Date: Tue, 17 Dec 2024 07:29:48 +0100 Subject: [PATCH 1/3] fix(errors): show a message when fail() is returned --- src/routes/(dashboard)/+page.server.ts | 36 +++++++------------ src/routes/(dashboard)/+page.svelte | 3 +- .../create/employee/+page.server.ts | 20 ++++++----- .../(dashboard)/create/employee/+page.svelte | 3 +- .../create/student/+page.server.ts | 18 ++++++---- .../(dashboard)/create/student/+page.svelte | 3 +- .../admin/create/building/+page.server.ts | 13 ++++--- src/routes/admin/create/building/+page.svelte | 3 +- .../admin/create/department/+page.server.ts | 13 ++++--- .../admin/create/department/+page.svelte | 3 +- src/routes/admin/register/+page.server.ts | 12 ++++--- src/routes/admin/register/+page.svelte | 3 +- src/routes/login/+page.server.ts | 15 ++++---- src/routes/login/+page.svelte | 3 +- 14 files changed, 80 insertions(+), 68 deletions(-) diff --git a/src/routes/(dashboard)/+page.server.ts b/src/routes/(dashboard)/+page.server.ts index 4f3d446..4b65a74 100644 --- a/src/routes/(dashboard)/+page.server.ts +++ b/src/routes/(dashboard)/+page.server.ts @@ -8,18 +8,9 @@ import { deleteSessionTokenCookie } from '$lib/server/session'; export const load: PageServerLoad = async ({ url }) => { try { - const limit = 1000; - const offset = 0; - - const studentLimit = Math.round(limit / 2); - const employeeLimit = limit - studentLimit; - const studentOffset = Math.round(offset / 2); - const employeeOffset = offset - studentOffset; - const searchQuery = url.searchParams.get('q') ?? undefined; - - const studentsP = getStudents(studentLimit, studentOffset, searchQuery); - const employeesP = getEmployees(employeeLimit, employeeOffset, searchQuery); + const studentsP = getStudents(1000, 0, searchQuery); + const employeesP = getEmployees(1000, 0, searchQuery); const students = await studentsP; const employees = await employeesP; @@ -49,8 +40,9 @@ export const load: PageServerLoad = async ({ url }) => { persons }; } catch (err: unknown) { - return fail(400, { - message: `Failed to get students or employees: ${(err as Error).message}` + console.debug(`Failed to get students and employees: ${(err as Error).message}`); + return fail(500, { + message: 'Failed to get students and employees' }); } }; @@ -63,8 +55,8 @@ export const actions: Actions = { const type = formData.get('type'); if (locals.session === null || locals.user === null) { - return fail(400, { - message: 'Null building or username' + return fail(401, { + message: 'Invalid session' }); } const building = locals.session.building; @@ -93,14 +85,13 @@ export const actions: Actions = { await toggleEmployeeState(id, building, creator); } else { return fail(400, { - message: 'Invalid type' + message: 'Invalid type (neither student nor employee)' }); } } catch (err: unknown) { - const msg = `Failed to toggle state: ${(err as Error).message}`; - console.debug(msg); + console.debug(`Failed to toggle state: ${(err as Error).message}`); return fail(400, { - message: msg + message: 'Failed to toggle state' }); } }, @@ -108,19 +99,18 @@ export const actions: Actions = { try { const formData = await event.request.formData(); const idS = formData.get('id_session'); - if (idS === null || idS === undefined || typeof idS !== 'string' || idS === '') { return fail(400, { message: 'Invalid or missing fields' }); } + await invalidateSession(idS); deleteSessionTokenCookie(event); } catch (err: unknown) { - const msg = `Failed to toggle state: ${(err as Error).message}`; - console.debug(msg); + console.debug(`Failed to logout: ${(err as Error).message}`); return fail(400, { - message: msg + message: 'Failed to logout' }); } diff --git a/src/routes/(dashboard)/+page.svelte b/src/routes/(dashboard)/+page.svelte index a67f96f..729056c 100644 --- a/src/routes/(dashboard)/+page.svelte +++ b/src/routes/(dashboard)/+page.svelte @@ -7,7 +7,7 @@ import DataTable from './data-table.svelte'; import { columns } from './columns'; - let { data } = $props(); + let { data, form: actionData } = $props(); const searchQuery = data.searchQuery; let searchBox: HTMLFormElement | null; @@ -28,6 +28,7 @@ +

{actionData?.message}

diff --git a/src/routes/(dashboard)/create/employee/+page.server.ts b/src/routes/(dashboard)/create/employee/+page.server.ts index 5e59a60..b88178c 100644 --- a/src/routes/(dashboard)/create/employee/+page.server.ts +++ b/src/routes/(dashboard)/create/employee/+page.server.ts @@ -1,5 +1,5 @@ import { fail, type Actions } from '@sveltejs/kit'; -import { superValidate, message } from 'sveltekit-superforms'; +import { superValidate } from 'sveltekit-superforms'; import { zod } from 'sveltekit-superforms/adapters'; import { createEmployee } from '$lib/server/db/employee'; @@ -23,13 +23,15 @@ export const actions: Actions = { const form = await superValidate(request, zod(formSchema)); if (!form.valid) { return fail(400, { - form + form, + message: 'Invalid form inputs' }); } if (locals.session === null || locals.user === null) { - return fail(400, { - form + return fail(401, { + form, + message: 'Invalid session' }); } @@ -39,14 +41,16 @@ export const actions: Actions = { const creator = locals.user.username; await createEmployee(email, fname, lname, department, building, creator); } catch (err: unknown) { - const message = `Failed to create employee: ${(err as Error).message}}`; - console.debug(message); + console.debug(`Failed to create employee: ${(err as Error).message}`); return fail(400, { form, - message + message: 'Employee already exists' }); } - return message(form, 'Employee created successfully!'); + return { + form, + message: 'Employee created successfully!' + }; } }; diff --git a/src/routes/(dashboard)/create/employee/+page.svelte b/src/routes/(dashboard)/create/employee/+page.svelte index 7b9b3fb..ef620fa 100644 --- a/src/routes/(dashboard)/create/employee/+page.svelte +++ b/src/routes/(dashboard)/create/employee/+page.svelte @@ -8,7 +8,7 @@ import { toast } from 'svelte-sonner'; import { formSchema } from './schema'; - let { data } = $props(); + let { data, form: actionData } = $props(); const form = superForm(data.form, { validators: zodClient(formSchema), @@ -31,6 +31,7 @@ Create an employee who wants to enter the building for the first time. +

{actionData?.message}

diff --git a/src/routes/(dashboard)/create/student/+page.server.ts b/src/routes/(dashboard)/create/student/+page.server.ts index ad51025..6e30d28 100644 --- a/src/routes/(dashboard)/create/student/+page.server.ts +++ b/src/routes/(dashboard)/create/student/+page.server.ts @@ -23,13 +23,15 @@ export const actions: Actions = { const form = await superValidate(request, zod(formSchema)); if (!form.valid) { return fail(400, { - form + form, + message: 'Invalid form inputs' }); } if (locals.session === null || locals.user === null) { - return fail(400, { - form + return fail(401, { + form, + message: 'Invalid session' }); } @@ -39,14 +41,16 @@ export const actions: Actions = { const creator = locals.user.username; await createStudent(index, fname, lname, department, building, creator); } catch (err: unknown) { - const message = `Failed to create student: ${(err as Error).message}`; - console.debug(message); + console.debug(`Failed to create student: ${(err as Error).message}`); return fail(400, { form, - message + message: 'Student already exists' }); } - return message(form, 'Student created successfully!'); + return { + form, + message: 'Student created successfully!' + }; } }; diff --git a/src/routes/(dashboard)/create/student/+page.svelte b/src/routes/(dashboard)/create/student/+page.svelte index 352fa1e..45fe1e8 100644 --- a/src/routes/(dashboard)/create/student/+page.svelte +++ b/src/routes/(dashboard)/create/student/+page.svelte @@ -8,7 +8,7 @@ import { toast } from 'svelte-sonner'; import { formSchema } from './schema'; - let { data } = $props(); + let { data, form: actionData } = $props(); const form = superForm(data.form, { validators: zodClient(formSchema), @@ -31,6 +31,7 @@ Create an student who wants to enter the building for the first time. +

{actionData?.message}

diff --git a/src/routes/admin/create/building/+page.server.ts b/src/routes/admin/create/building/+page.server.ts index 1296588..45469cb 100644 --- a/src/routes/admin/create/building/+page.server.ts +++ b/src/routes/admin/create/building/+page.server.ts @@ -19,7 +19,8 @@ export const actions: Actions = { const form = await superValidate(event.request, zod(formSchema)); if (!form.valid) { return fail(400, { - form + form, + message: 'Invalid form inputs' }); } @@ -36,14 +37,16 @@ export const actions: Actions = { const { building } = form.data; await createBuilding(building); } catch (err: unknown) { - const message = `Failed to create building: ${(err as Error).message}}`; - console.debug(message); + console.debug(`Failed to create building: ${(err as Error).message}`); return fail(400, { form, - message + message: 'Building already exists' }); } - return message(form, 'Building created successfully!'); + return { + form, + message: 'Building created successfully!' + }; } }; diff --git a/src/routes/admin/create/building/+page.svelte b/src/routes/admin/create/building/+page.svelte index 7ff7cb0..93d0f77 100644 --- a/src/routes/admin/create/building/+page.svelte +++ b/src/routes/admin/create/building/+page.svelte @@ -7,7 +7,7 @@ import { toast } from 'svelte-sonner'; import { formSchema } from './schema'; - let { data } = $props(); + let { data, form: actionData } = $props(); const form = superForm(data.form, { validators: zodClient(formSchema), @@ -28,6 +28,7 @@ Create building Enter the name of the new building to create. +

{actionData?.message}

diff --git a/src/routes/admin/create/department/+page.server.ts b/src/routes/admin/create/department/+page.server.ts index 49f0884..1e13c41 100644 --- a/src/routes/admin/create/department/+page.server.ts +++ b/src/routes/admin/create/department/+page.server.ts @@ -19,7 +19,8 @@ export const actions: Actions = { const form = await superValidate(event.request, zod(formSchema)); if (!form.valid) { return fail(400, { - form + form, + message: 'Invalid form inputs' }); } @@ -36,14 +37,16 @@ export const actions: Actions = { const { department } = form.data; await createDepartment(department); } catch (err: unknown) { - const message = `Failed to create department: ${(err as Error).message}}`; - console.debug(message); + console.debug(`Failed to create department: ${(err as Error).message}`); return fail(400, { form, - message + message: 'Department already exists' }); } - return message(form, 'Department created successfully!'); + return { + form, + message: 'Department created successfully!' + }; } }; diff --git a/src/routes/admin/create/department/+page.svelte b/src/routes/admin/create/department/+page.svelte index 2d35f20..f5aeb22 100644 --- a/src/routes/admin/create/department/+page.svelte +++ b/src/routes/admin/create/department/+page.svelte @@ -7,7 +7,7 @@ import { toast } from 'svelte-sonner'; import { formSchema } from './schema'; - let { data } = $props(); + let { data, form: actionData } = $props(); const form = superForm(data.form, { validators: zodClient(formSchema), @@ -28,6 +28,7 @@ Create department Enter the name of the new department to create. +

{actionData?.message}

diff --git a/src/routes/admin/register/+page.server.ts b/src/routes/admin/register/+page.server.ts index d1d70ad..b7d2d87 100644 --- a/src/routes/admin/register/+page.server.ts +++ b/src/routes/admin/register/+page.server.ts @@ -9,7 +9,9 @@ import { formSchema } from './schema'; export const load: PageServerLoad = async () => { const form = await superValidate(zod(formSchema)); - return { form }; + return { + form + }; }; export const actions: Actions = { @@ -17,7 +19,8 @@ export const actions: Actions = { const form = await superValidate(event.request, zod(formSchema)); if (!form.valid) { return fail(400, { - form + form, + message: 'Invalid form inputs' }); } @@ -35,11 +38,10 @@ export const actions: Actions = { // Create the new user await createUser(username, password); } catch (err: unknown) { - const message = `Failed to register: ${(err as Error).message}}`; - console.debug(message); + console.debug(`Failed to register: ${(err as Error).message}`); return fail(400, { form, - message + message: 'Username already exists or password is too weak' }); } } diff --git a/src/routes/admin/register/+page.svelte b/src/routes/admin/register/+page.svelte index 097ac9e..55ae282 100644 --- a/src/routes/admin/register/+page.svelte +++ b/src/routes/admin/register/+page.svelte @@ -7,7 +7,7 @@ import { zodClient } from 'sveltekit-superforms/adapters'; import { formSchema } from './schema'; - let { data } = $props(); + let { data, form: actionData } = $props(); const form = superForm(data.form, { validators: zodClient(formSchema), @@ -28,6 +28,7 @@ Register Enter credentials for user registration. +

{actionData?.message}

diff --git a/src/routes/login/+page.server.ts b/src/routes/login/+page.server.ts index 8fb8dca..d3348b0 100644 --- a/src/routes/login/+page.server.ts +++ b/src/routes/login/+page.server.ts @@ -24,18 +24,18 @@ export const actions: Actions = { const form = await superValidate(event.request, zod(formSchema)); if (!form.valid) { return fail(400, { - form + form, + message: 'Invalid form inputs' }); } + try { const { username, password, building } = form.data; // Check if the username and password are valid const { id, passwordHash } = await getUserIdAndPasswordHash(username); const validPassword = await verifyPasswordHash(passwordHash, password); if (!validPassword) { - return fail(401, { - message: 'Invalid username or password' - }); + throw new Error('Invalid username or password'); } // Create a new session token @@ -43,11 +43,10 @@ export const actions: Actions = { const session = await createSession(sessionToken, id, building); setSessionTokenCookie(event, sessionToken, session.expiresAt); } catch (err: unknown) { - const message = `Failed to login: ${(err as Error).message}}`; - console.debug(message); - return fail(400, { + console.debug(`Failed to login: ${(err as Error).message}`); + return fail(401, { form, - message + message: 'Invalid username or password' }); } diff --git a/src/routes/login/+page.svelte b/src/routes/login/+page.svelte index 6876a14..d2d498b 100644 --- a/src/routes/login/+page.svelte +++ b/src/routes/login/+page.svelte @@ -8,7 +8,7 @@ import { toast } from 'svelte-sonner'; import { formSchema } from './schema'; - let { data } = $props(); + let { data, form: actionData } = $props(); const form = superForm(data.form, { validators: zodClient(formSchema), @@ -30,6 +30,7 @@ Login Enter your credentials to login to the dashboard +

{actionData?.message}

From fa9d834b630ab834ab7fe4c6ef2a1bc4fa772e3a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aleksa=20Siri=C5=A1ki?= <31509435+aleksasiriski@users.noreply.github.com> Date: Tue, 17 Dec 2024 07:30:10 +0100 Subject: [PATCH 2/3] chore(Makefile): install --- Makefile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Makefile b/Makefile index 676587c..47b61e0 100644 --- a/Makefile +++ b/Makefile @@ -1,3 +1,5 @@ +install: + pnpm i --frozen-lockfile prod-start: docker compose -f docker-compose.prod.yml up -d prod-stop: From ad452c4a351cd8cad5042761d9bc57402ace5a26 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aleksa=20Siri=C5=A1ki?= <31509435+aleksasiriski@users.noreply.github.com> Date: Tue, 17 Dec 2024 07:55:18 +0100 Subject: [PATCH 3/3] fix: lint errors and regexp comment --- src/lib/utils/regexp.ts | 6 +++--- src/routes/(dashboard)/create/student/+page.server.ts | 2 +- src/routes/admin/create/building/+page.server.ts | 2 +- src/routes/admin/create/department/+page.server.ts | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/lib/utils/regexp.ts b/src/lib/utils/regexp.ts index 8caae30..39c5d9b 100644 --- a/src/lib/utils/regexp.ts +++ b/src/lib/utils/regexp.ts @@ -4,12 +4,12 @@ export const nameRegExpMsg = export const indexRegExp = /^\d{1,4}[a-zA-Z]?\/(?:\d{2}|\d{4})(?:[A-Z]{1,3})?$/; export const indexRegExpMsg = - 'String must be in format: 1-4 numbers, optional single character and 2 or 4 numbers (year)'; + 'String must be in format: 1-4 numbers, optional single character and 2 or 4 numbers (year) and optional 1-3 uppercase letters'; -export const uppercaseRegExp = /^[A-Z0-9_\-+\/\\|]*$/; +export const uppercaseRegExp = /^[A-Z0-9_\-+/\\|]*$/; export const uppercaseRegExpMsg = 'String must only consist of uppercase letters, numbers and special signs (_, -, +, /, \\, |)'; -export const lowercaseRegExp = /^[a-z0-9_\-+\/\\|]*$/; +export const lowercaseRegExp = /^[a-z0-9_\-+/\\|]*$/; export const lowercaseRegExpMsg = 'String must only consist of lowercase letters, numbers and special signs (_, -, +, /, \\, |)'; diff --git a/src/routes/(dashboard)/create/student/+page.server.ts b/src/routes/(dashboard)/create/student/+page.server.ts index 6e30d28..523931a 100644 --- a/src/routes/(dashboard)/create/student/+page.server.ts +++ b/src/routes/(dashboard)/create/student/+page.server.ts @@ -1,5 +1,5 @@ import { fail, type Actions } from '@sveltejs/kit'; -import { superValidate, message } from 'sveltekit-superforms'; +import { superValidate } from 'sveltekit-superforms'; import { zod } from 'sveltekit-superforms/adapters'; import { createStudent } from '$lib/server/db/student'; diff --git a/src/routes/admin/create/building/+page.server.ts b/src/routes/admin/create/building/+page.server.ts index 45469cb..d569701 100644 --- a/src/routes/admin/create/building/+page.server.ts +++ b/src/routes/admin/create/building/+page.server.ts @@ -1,5 +1,5 @@ import { fail, type Actions } from '@sveltejs/kit'; -import { message, superValidate } from 'sveltekit-superforms'; +import { superValidate } from 'sveltekit-superforms'; import { zod } from 'sveltekit-superforms/adapters'; import { formSchema } from './schema'; import type { PageServerLoad } from './$types'; diff --git a/src/routes/admin/create/department/+page.server.ts b/src/routes/admin/create/department/+page.server.ts index 1e13c41..623b0cf 100644 --- a/src/routes/admin/create/department/+page.server.ts +++ b/src/routes/admin/create/department/+page.server.ts @@ -1,5 +1,5 @@ import { fail, type Actions } from '@sveltejs/kit'; -import { message, superValidate } from 'sveltekit-superforms'; +import { superValidate } from 'sveltekit-superforms'; import { zod } from 'sveltekit-superforms/adapters'; import { formSchema } from './schema'; import type { PageServerLoad } from './$types';