From a2886fc1e057542c65a8b8351eadbb18cc010a47 Mon Sep 17 00:00:00 2001 From: Alex <$(pass /github/email)> Date: Wed, 26 Feb 2025 21:42:49 +0100 Subject: [PATCH] backend changed verification model --- .../src/routes/auth/confirming/+page.svelte | 17 +++++ .../auth/password/change/+page.server.js | 33 ++++++++ .../routes/auth/password/change/+page.svelte | 45 +++++++++++ .../auth/password/change/[id]/+page.server.js | 49 ++++++++++++ .../auth/password/change/[id]/+page.svelte | 76 +++++++++++++++++++ internal/models/verification.go | 4 +- 6 files changed, 222 insertions(+), 2 deletions(-) create mode 100644 frontend/src/routes/auth/confirming/+page.svelte create mode 100644 frontend/src/routes/auth/password/change/+page.server.js create mode 100644 frontend/src/routes/auth/password/change/+page.svelte create mode 100644 frontend/src/routes/auth/password/change/[id]/+page.server.js create mode 100644 frontend/src/routes/auth/password/change/[id]/+page.svelte diff --git a/frontend/src/routes/auth/confirming/+page.svelte b/frontend/src/routes/auth/confirming/+page.svelte new file mode 100644 index 0000000..b45486b --- /dev/null +++ b/frontend/src/routes/auth/confirming/+page.svelte @@ -0,0 +1,17 @@ + + +
+
+

{$t('email_sent')}

+

+ {$t(message)} +

+
+
diff --git a/frontend/src/routes/auth/password/change/+page.server.js b/frontend/src/routes/auth/password/change/+page.server.js new file mode 100644 index 0000000..cf14af9 --- /dev/null +++ b/frontend/src/routes/auth/password/change/+page.server.js @@ -0,0 +1,33 @@ +import { BASE_API_URI } from '$lib/utils/constants'; +import { formatError } from '$lib/utils/helpers'; +import { fail, redirect } from '@sveltejs/kit'; + +/** @type {import('./$types').Actions} */ +export const actions = { + default: async ({ fetch, request }) => { + const formData = await request.formData(); + const email = String(formData.get('email')); + + /** @type {RequestInit} */ + const requestInitOptions = { + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ email: email }) + }; + + const res = await fetch(`${BASE_API_URI}/users/password/request-change/`, requestInitOptions); + + if (!res.ok) { + const response = await res.json(); + const errors = formatError(response.errors); + return fail(400, { errors: errors }); + } + + const response = await res.json(); + + // redirect the user + throw redirect(302, `/auth/confirming?message=${response.message}`); + } +}; diff --git a/frontend/src/routes/auth/password/change/+page.svelte b/frontend/src/routes/auth/password/change/+page.svelte new file mode 100644 index 0000000..e786bdd --- /dev/null +++ b/frontend/src/routes/auth/password/change/+page.svelte @@ -0,0 +1,45 @@ + + +
+
+

{$t('forgot_password')}

+ {#if form?.errors} + {#each form?.errors as error (error.id)} +

+ {$t(error.key)} +

+ {/each} + {/if} + +
+ {$t('user.email')}: + +
+ +
+
diff --git a/frontend/src/routes/auth/password/change/[id]/+page.server.js b/frontend/src/routes/auth/password/change/[id]/+page.server.js new file mode 100644 index 0000000..54670ec --- /dev/null +++ b/frontend/src/routes/auth/password/change/[id]/+page.server.js @@ -0,0 +1,49 @@ +import { BASE_API_URI } from '$lib/utils/constants'; +import { formatError } from '$lib/utils/helpers'; +import { fail, redirect } from '@sveltejs/kit'; + +/** @type {import('./$types').Actions} */ +export const actions = { + default: async ({ fetch, request }) => { + const formData = await request.formData(); + const password = String(formData.get('user[password]')).trim(); + const confirmPassword = String(formData.get('confirm_password')).trim(); + let token = String(formData.get('token')); + const userID = String(formData.get('user_id')); + + // Some validations + /** @type {string | Array<{field: string, key: string}> | Record} */ + const fieldsError = []; + if (password.length < 8) { + fieldsError.push({ field: 'user.user', key: 'validation.password' }); + } + if (confirmPassword !== password) { + fieldsError.push({ field: 'user.user', key: 'validation.password_match' }); + } + if (Object.keys(fieldsError).length > 0) { + return fail(400, { errors: formatError(fieldsError) }); + } + + /** @type {RequestInit} */ + const requestInitOptions = { + method: 'PATCH', + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ token: token, password: password }) + }; + + const res = await fetch(`${BASE_API_URI}/users/password/change/${userID}/`, requestInitOptions); + + if (!res.ok) { + const response = await res.json(); + const errors = formatError(response.errors); + return fail(400, { errors: errors }); + } + + const response = await res.json(); + + // redirect the user + throw redirect(302, `/auth/login?message=${response.message}`); + } +}; diff --git a/frontend/src/routes/auth/password/change/[id]/+page.svelte b/frontend/src/routes/auth/password/change/[id]/+page.svelte new file mode 100644 index 0000000..dc79774 --- /dev/null +++ b/frontend/src/routes/auth/password/change/[id]/+page.svelte @@ -0,0 +1,76 @@ + + +
+
+

{$t('change_password')}

+ {#if form?.errors} + {#each form?.errors as error (error.id)} +

+ {$t(error.key)} +

+ {/each} + {/if} + + + + + + + + +
diff --git a/internal/models/verification.go b/internal/models/verification.go index bf8027b..daaed2c 100644 --- a/internal/models/verification.go +++ b/internal/models/verification.go @@ -5,9 +5,9 @@ import "time" type Verification struct { UpdatedAt time.Time CreatedAt time.Time - EmailVerifiedAt *time.Time `gorm:"Default:NULL" json:"email_verified_at"` - IDVerifiedAt *time.Time `gorm:"Default:NULL" json:"id_verified_at"` + VerifiedAt *time.Time `gorm:"Default:NULL" json:"verified_at"` VerificationToken string `json:"token"` ID uint `gorm:"primaryKey"` UserID uint `gorm:"unique;" json:"user_id"` + Type string }