From 2291e12b3a02d4bbb27f7ea3f785b2f5c1cf809b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9o?= <43091603+glazk0@users.noreply.github.com> Date: Sun, 17 Sep 2023 23:04:10 +0200 Subject: [PATCH] feat: forgor :skull: --- src/routes/forgot-password/+page.server.ts | 137 +++++++++++++++++++++ src/routes/forgot-password/+page.svelte | 95 ++++++++++++++ 2 files changed, 232 insertions(+) create mode 100644 src/routes/forgot-password/+page.server.ts create mode 100644 src/routes/forgot-password/+page.svelte diff --git a/src/routes/forgot-password/+page.server.ts b/src/routes/forgot-password/+page.server.ts new file mode 100644 index 0000000..ef5e5b7 --- /dev/null +++ b/src/routes/forgot-password/+page.server.ts @@ -0,0 +1,137 @@ +import { API_URL } from '$env/static/private'; + +import { fail, redirect, type Actions } from '@sveltejs/kit'; + +import type { PageServerLoad } from './$types'; + +import { superValidate } from 'sveltekit-superforms/server'; +import { z } from 'zod'; + +const forgotSchema = z.object({ + email: z + .string() + .email({ + message: 'Email invalide' + }) + .trim(), + code: z + .string({ + required_error: 'Code manquant' + }) + .regex(/^[0-9]{4}$/, { + message: 'Code invalide, il doit contenir 4 chiffres' + }) + .optional(), + passwd: z.string().optional() +}); + +const confirmationSchema = z.object({ + email: z + .string() + .email({ + message: 'Email invalide' + }) + .trim(), + code: z + .string({ + required_error: 'Code manquant' + }) + .regex(/^[0-9]{4}$/, { + message: 'Code invalide, il doit contenir 4 chiffres' + }), + passwd: z.string() +}); + +export const load = (async ({ locals: { user } }) => { + if (user) throw redirect(303, '/dashboard'); + + const form = await superValidate(forgotSchema); + + return { + form + }; +}) satisfies PageServerLoad; + +export const actions = { + forgot: async ({ request, cookies }) => { + const form = await superValidate(request, forgotSchema); + + if (!form.valid) { + return fail(400, { form }); + } + + const data = { + email: form.data.email + } as Record; + + if (form.data.code) { + data.code = parseInt(form.data.code); + } + + if (form.data.passwd) { + data.password = form.data.passwd; + } + + const res = await fetch(`${API_URL}/user/fpw`, { + method: 'POST', + body: JSON.stringify(data) + }); + + console.log(res); + + if (res.ok) { + const token = res.headers.get('Authorization')?.split('Bearer ')[1]; + + if (token) { + cookies.set('session', token, { + path: '/' + }); + + throw redirect(303, '/dashboard'); + } + return { + form + }; + } + + form.errors.passwd = ['Code invalide ou expiré']; + + return fail(400, { + form + }); + }, + confirmation: async ({ request, cookies }) => { + const form = await superValidate(request, confirmationSchema); + + if (!form.valid) { + return fail(400, { form }); + } + + const res = await fetch(`${API_URL}/confirmation`, { + method: 'POST', + body: JSON.stringify({ + email: form.data.email, + passwd: form.data.passwd, + code: parseInt(form.data.code) + }) + }); + + if (res.ok) { + const token = res.headers.get('Authorization')?.split('Bearer ')[1]; + + if (!token) throw new Error('No token'); + + cookies.set('session', token, { + path: '/' + }); + + throw redirect(303, '/dashboard'); + } + + form.errors.code = [`Une erreur s'est produite (${res.status} ${res.statusText})`]; + + return fail(400, { + form + }); + } +} satisfies Actions; diff --git a/src/routes/forgot-password/+page.svelte b/src/routes/forgot-password/+page.svelte new file mode 100644 index 0000000..6ad4af2 --- /dev/null +++ b/src/routes/forgot-password/+page.svelte @@ -0,0 +1,95 @@ + + +
+
+
+

+ {confirmation ? 'Changer le mot de passe' : 'Mot de passe oublié'} +

+
+ + + {#if $errors.email}{$errors.email}{/if} + + {#if confirmation} +
+ + + {#if $errors.passwd}{$errors.passwd}{/if} + + + + {#if $errors.code}{$errors.code}{/if} +
+ {/if} + + + +
    +
  • + Se connecter +
  • + {#if confirmation} +
  • + +
  • + {/if} +
+
+
+
+