From 09c39eeb38014994d2c72513ec33bcdac5fadb7f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sopronyi=20Zolt=C3=A1n?= <70892729+Sopa02@users.noreply.github.com> Date: Sun, 26 Nov 2023 20:55:47 +0100 Subject: [PATCH 1/3] IMG-49 feat: login form submission --- package.json | 3 +- pnpm-lock.yaml | 48 +++++++++++++++++++++++-- src/lib/LoginForm.svelte | 5 +-- src/routes/dash/login/+page.server.ts | 52 +++++++++++++++++++++++++++ src/routes/dash/login/+page.svelte | 8 +++-- 5 files changed, 108 insertions(+), 8 deletions(-) create mode 100644 src/routes/dash/login/+page.server.ts diff --git a/package.json b/package.json index 6f7d5d3..b1334ff 100644 --- a/package.json +++ b/package.json @@ -24,13 +24,14 @@ "eslint-plugin-svelte": "^2.30.0", "formsnap": "^0.4.1", "lucide-svelte": "^0.291.0", + "node-fetch": "^3.3.2", "postcss": "^8.4.31", "prettier": "^2.8.0", "prettier-plugin-svelte": "^2.10.1", "svelte": "^4.0.5", "svelte-check": "^3.4.3", - "sveltekit-superforms": "^1.10.1", "svelte-meta-tags": "^3.1.0", + "sveltekit-superforms": "^1.10.1", "tailwind-merge": "^2.0.0", "tailwind-variants": "^0.1.18", "tailwindcss": "^3.3.5", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 5634044..a5ad05e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -41,6 +41,9 @@ devDependencies: lucide-svelte: specifier: ^0.291.0 version: 0.291.0(svelte@4.2.2) + node-fetch: + specifier: ^3.3.2 + version: 3.3.2 postcss: specifier: ^8.4.31 version: 8.4.31 @@ -56,12 +59,12 @@ devDependencies: svelte-check: specifier: ^3.4.3 version: 3.5.2(postcss@8.4.31)(svelte@4.2.2) - sveltekit-superforms: - specifier: ^1.10.1 - version: 1.10.1(@sveltejs/kit@1.27.2)(svelte@4.2.2)(zod@3.22.4) svelte-meta-tags: specifier: ^3.1.0 version: 3.1.0(svelte@4.2.2)(typescript@5.2.2) + sveltekit-superforms: + specifier: ^1.10.1 + version: 1.10.1(@sveltejs/kit@1.27.2)(svelte@4.2.2)(zod@3.22.4) tailwind-merge: specifier: ^2.0.0 version: 2.0.0 @@ -1006,6 +1009,11 @@ packages: hasBin: true dev: true + /data-uri-to-buffer@4.0.1: + resolution: {integrity: sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==} + engines: {node: '>= 12'} + dev: true + /debug@4.3.4: resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} engines: {node: '>=6.0'} @@ -1284,6 +1292,14 @@ packages: reusify: 1.0.4 dev: true + /fetch-blob@3.2.0: + resolution: {integrity: sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==} + engines: {node: ^12.20 || >= 14.13} + dependencies: + node-domexception: 1.0.0 + web-streams-polyfill: 3.2.1 + dev: true + /file-entry-cache@6.0.1: resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} engines: {node: ^10.12.0 || >=12.0.0} @@ -1325,6 +1341,13 @@ packages: tabbable: 6.2.0 dev: true + /formdata-polyfill@4.0.10: + resolution: {integrity: sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==} + engines: {node: '>=12.20.0'} + dependencies: + fetch-blob: 3.2.0 + dev: true + /formsnap@0.4.1(svelte@4.2.2)(sveltekit-superforms@1.10.1)(zod@3.22.4): resolution: {integrity: sha512-hUOaDKb+KoBi4PamJRnxRqIQW3msp2BKPqohoqjHUuBb+vgBrhoaz0WYEFkXG4bzVQS3JngG55m/zX5ciZTyeA==} peerDependencies: @@ -1732,6 +1755,20 @@ packages: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} dev: true + /node-domexception@1.0.0: + resolution: {integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==} + engines: {node: '>=10.5.0'} + dev: true + + /node-fetch@3.3.2: + resolution: {integrity: sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dependencies: + data-uri-to-buffer: 4.0.1 + fetch-blob: 3.2.0 + formdata-polyfill: 4.0.10 + dev: true + /node-releases@2.0.13: resolution: {integrity: sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==} dev: true @@ -2510,6 +2547,11 @@ packages: vite: 4.5.0 dev: true + /web-streams-polyfill@3.2.1: + resolution: {integrity: sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q==} + engines: {node: '>= 8'} + dev: true + /which@2.0.2: resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} engines: {node: '>= 8'} diff --git a/src/lib/LoginForm.svelte b/src/lib/LoginForm.svelte index f8ed7b4..c919c50 100644 --- a/src/lib/LoginForm.svelte +++ b/src/lib/LoginForm.svelte @@ -3,9 +3,10 @@ import { loginSchema, type LoginSchema } from '$lib/schema' import type { SuperValidated } from 'sveltekit-superforms' export let form: SuperValidated + - + Username @@ -17,7 +18,7 @@ Password - + diff --git a/src/routes/dash/login/+page.server.ts b/src/routes/dash/login/+page.server.ts new file mode 100644 index 0000000..b9168bd --- /dev/null +++ b/src/routes/dash/login/+page.server.ts @@ -0,0 +1,52 @@ +import type { PageServerLoad, Actions } from './$types' +import { fail } from '@sveltejs/kit' +import { superValidate } from 'sveltekit-superforms/server' +import { loginSchema } from '$lib/schema' +import fetch from 'node-fetch' + +export const load: PageServerLoad = () => { + return { + form: superValidate(loginSchema) + } +} + +export const actions: Actions = { + default: async (event) => { + const form = await superValidate(event, loginSchema) + if (!form.valid) { + return fail(400, { + form + }) + } + try { + // TODO: Adjust to backend endpoint + const response = await fetch('BACKEND', { + method: 'POST', + headers: { + 'Content-Type': 'application/json' // Adjust content type based on what your backend expects + // Add any necessary headers (e.g., authorization headers) + }, + body: JSON.stringify({ + // or body: form.data, remains to be tested + username: form.data.username, + password: form.data.password + }) + }) + if (!response.ok) { + throw new Error('Network response was NOT ok.') + } + + // You might choose to process the response from the backend here if needed + // For example, getting data back from the backend + const responseData = await response.json() + + return { + form: responseData // Optionally, return the response from the backend to the client + } + } catch (error) { + return fail(500, { + error: error + }) + } + } +} diff --git a/src/routes/dash/login/+page.svelte b/src/routes/dash/login/+page.svelte index 52200f7..63f2d2b 100644 --- a/src/routes/dash/login/+page.svelte +++ b/src/routes/dash/login/+page.svelte @@ -9,7 +9,11 @@ import LoginForm from '$lib/LoginForm.svelte' import Centered from '$lib/Centered.svelte' - import logo from '$lib/assets/icons/logo_slate-700.png' + import logo from '$lib/assets/icons/Border/logo_slate-700.png' + + import type { PageData } from './$types'; + export let data: PageData; + @@ -20,7 +24,7 @@ - + From f515e9fa4a711c4f4bf183c5296648db8c77934f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sopronyi=20Zolt=C3=A1n?= <70892729+Sopa02@users.noreply.github.com> Date: Tue, 28 Nov 2023 14:29:21 +0100 Subject: [PATCH 2/3] IMG-49 feat: login server side handling --- package.json | 1 - pnpm-lock.yaml | 42 ---------------- src/routes/dash/login/+page.server.ts | 70 ++++++++++++++------------- src/routes/dash/login/+page.svelte | 3 +- 4 files changed, 39 insertions(+), 77 deletions(-) diff --git a/package.json b/package.json index b1334ff..bda360a 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,6 @@ "eslint-plugin-svelte": "^2.30.0", "formsnap": "^0.4.1", "lucide-svelte": "^0.291.0", - "node-fetch": "^3.3.2", "postcss": "^8.4.31", "prettier": "^2.8.0", "prettier-plugin-svelte": "^2.10.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a5ad05e..4f5dbb3 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -41,9 +41,6 @@ devDependencies: lucide-svelte: specifier: ^0.291.0 version: 0.291.0(svelte@4.2.2) - node-fetch: - specifier: ^3.3.2 - version: 3.3.2 postcss: specifier: ^8.4.31 version: 8.4.31 @@ -1009,11 +1006,6 @@ packages: hasBin: true dev: true - /data-uri-to-buffer@4.0.1: - resolution: {integrity: sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==} - engines: {node: '>= 12'} - dev: true - /debug@4.3.4: resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} engines: {node: '>=6.0'} @@ -1292,14 +1284,6 @@ packages: reusify: 1.0.4 dev: true - /fetch-blob@3.2.0: - resolution: {integrity: sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==} - engines: {node: ^12.20 || >= 14.13} - dependencies: - node-domexception: 1.0.0 - web-streams-polyfill: 3.2.1 - dev: true - /file-entry-cache@6.0.1: resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} engines: {node: ^10.12.0 || >=12.0.0} @@ -1341,13 +1325,6 @@ packages: tabbable: 6.2.0 dev: true - /formdata-polyfill@4.0.10: - resolution: {integrity: sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==} - engines: {node: '>=12.20.0'} - dependencies: - fetch-blob: 3.2.0 - dev: true - /formsnap@0.4.1(svelte@4.2.2)(sveltekit-superforms@1.10.1)(zod@3.22.4): resolution: {integrity: sha512-hUOaDKb+KoBi4PamJRnxRqIQW3msp2BKPqohoqjHUuBb+vgBrhoaz0WYEFkXG4bzVQS3JngG55m/zX5ciZTyeA==} peerDependencies: @@ -1755,20 +1732,6 @@ packages: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} dev: true - /node-domexception@1.0.0: - resolution: {integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==} - engines: {node: '>=10.5.0'} - dev: true - - /node-fetch@3.3.2: - resolution: {integrity: sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - dependencies: - data-uri-to-buffer: 4.0.1 - fetch-blob: 3.2.0 - formdata-polyfill: 4.0.10 - dev: true - /node-releases@2.0.13: resolution: {integrity: sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==} dev: true @@ -2547,11 +2510,6 @@ packages: vite: 4.5.0 dev: true - /web-streams-polyfill@3.2.1: - resolution: {integrity: sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q==} - engines: {node: '>= 8'} - dev: true - /which@2.0.2: resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} engines: {node: '>= 8'} diff --git a/src/routes/dash/login/+page.server.ts b/src/routes/dash/login/+page.server.ts index b9168bd..48d9a79 100644 --- a/src/routes/dash/login/+page.server.ts +++ b/src/routes/dash/login/+page.server.ts @@ -2,7 +2,21 @@ import type { PageServerLoad, Actions } from './$types' import { fail } from '@sveltejs/kit' import { superValidate } from 'sveltekit-superforms/server' import { loginSchema } from '$lib/schema' -import fetch from 'node-fetch' +import { redirect } from '@sveltejs/kit' +import { actionResult } from 'sveltekit-superforms/server' +import { error } from '@sveltejs/kit' + +interface LoginResponse { + token: string +} +interface ResponseType { + message: string + details: any + error: { + statusCode: number + statusPhrase: string + } +} export const load: PageServerLoad = () => { return { @@ -11,42 +25,32 @@ export const load: PageServerLoad = () => { } export const actions: Actions = { - default: async (event) => { - const form = await superValidate(event, loginSchema) + default: async ({ request, cookies }) => { + const form = await superValidate(request, loginSchema) if (!form.valid) { - return fail(400, { - form - }) + return actionResult('failure', { form }, 400) } - try { - // TODO: Adjust to backend endpoint - const response = await fetch('BACKEND', { - method: 'POST', - headers: { - 'Content-Type': 'application/json' // Adjust content type based on what your backend expects - // Add any necessary headers (e.g., authorization headers) - }, - body: JSON.stringify({ - // or body: form.data, remains to be tested - username: form.data.username, - password: form.data.password - }) + const response = await fetch('https://api.unideb.tech/auth/login', { + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ + username: form.data.username, + password: form.data.password }) - if (!response.ok) { - throw new Error('Network response was NOT ok.') - } - - // You might choose to process the response from the backend here if needed - // For example, getting data back from the backend - const responseData = await response.json() + }) + if (response.status === 200) { + let token = ((await response.json()) as LoginResponse).token + console.log('Login successful, token: ' + token) + cookies.set('token', token, {}) + throw redirect(303, '/dash/') + } else { + let resp = (await response.json()) as ResponseType + console.log(resp.message) + throw error(resp.error.statusCode, resp.message) - return { - form: responseData // Optionally, return the response from the backend to the client - } - } catch (error) { - return fail(500, { - error: error - }) + // TODO: handle errors on client side } } } diff --git a/src/routes/dash/login/+page.svelte b/src/routes/dash/login/+page.svelte index 63f2d2b..ddeb16e 100644 --- a/src/routes/dash/login/+page.svelte +++ b/src/routes/dash/login/+page.svelte @@ -14,6 +14,7 @@ import type { PageData } from './$types'; export let data: PageData; + @@ -24,7 +25,7 @@ - + From c5edf90558768aba58652ac2725a6a2ff870e33d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sopronyi=20Zolt=C3=A1n?= <70892729+Sopa02@users.noreply.github.com> Date: Tue, 28 Nov 2023 22:57:41 +0100 Subject: [PATCH 3/3] IMG-49 feat: login error handling --- src/routes/dash/login/+page.server.ts | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/routes/dash/login/+page.server.ts b/src/routes/dash/login/+page.server.ts index 48d9a79..996713b 100644 --- a/src/routes/dash/login/+page.server.ts +++ b/src/routes/dash/login/+page.server.ts @@ -1,6 +1,6 @@ import type { PageServerLoad, Actions } from './$types' import { fail } from '@sveltejs/kit' -import { superValidate } from 'sveltekit-superforms/server' +import { setError, superValidate } from 'sveltekit-superforms/server' import { loginSchema } from '$lib/schema' import { redirect } from '@sveltejs/kit' import { actionResult } from 'sveltekit-superforms/server' @@ -48,9 +48,7 @@ export const actions: Actions = { } else { let resp = (await response.json()) as ResponseType console.log(resp.message) - throw error(resp.error.statusCode, resp.message) - - // TODO: handle errors on client side + return setError(form, 'username', resp.message) } } }