backend changed verification model
This commit is contained in:
17
frontend/src/routes/auth/confirming/+page.svelte
Normal file
17
frontend/src/routes/auth/confirming/+page.svelte
Normal file
@@ -0,0 +1,17 @@
|
||||
<script>
|
||||
import { page } from '$app/state';
|
||||
import { t } from 'svelte-i18n';
|
||||
let message = '';
|
||||
if (page.url.search) {
|
||||
message = page.url.search.split('=')[1].replaceAll('%20', ' ');
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="container">
|
||||
<div class="content">
|
||||
<h1 class="step-title title">{$t('email_sent')}</h1>
|
||||
<h4 class="step-subtitle normal">
|
||||
{$t(message)}
|
||||
</h4>
|
||||
</div>
|
||||
</div>
|
||||
33
frontend/src/routes/auth/password/change/+page.server.js
Normal file
33
frontend/src/routes/auth/password/change/+page.server.js
Normal file
@@ -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}`);
|
||||
}
|
||||
};
|
||||
45
frontend/src/routes/auth/password/change/+page.svelte
Normal file
45
frontend/src/routes/auth/password/change/+page.svelte
Normal file
@@ -0,0 +1,45 @@
|
||||
<script>
|
||||
import { applyAction, enhance } from '$app/forms';
|
||||
import { receive, send } from '$lib/utils/helpers';
|
||||
import { t } from 'svelte-i18n';
|
||||
|
||||
/** @type {import('./$types').ActionData} */
|
||||
export let form;
|
||||
|
||||
/** @type {import('./$types').SubmitFunction} */
|
||||
const handleRequestChange = async () => {
|
||||
return async ({ result }) => {
|
||||
await applyAction(result);
|
||||
};
|
||||
};
|
||||
</script>
|
||||
|
||||
<div class="container">
|
||||
<form class="content" method="POST" use:enhance={handleRequestChange}>
|
||||
<h1 class="step-title">{$t('forgot_password')}</h1>
|
||||
{#if form?.errors}
|
||||
{#each form?.errors as error (error.id)}
|
||||
<h4
|
||||
class="step-subtitle warning"
|
||||
in:receive={{ key: error.id }}
|
||||
out:send={{ key: error.id }}
|
||||
>
|
||||
{$t(error.key)}
|
||||
</h4>
|
||||
{/each}
|
||||
{/if}
|
||||
|
||||
<div class="input-box">
|
||||
<span class="label">{$t('user.email')}:</span>
|
||||
<input
|
||||
class="input"
|
||||
type="email"
|
||||
name="email"
|
||||
id="email"
|
||||
placeholder={$t('placeholder.email')}
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
<button class="button-dark">{$t('confirm')}</button>
|
||||
</form>
|
||||
</div>
|
||||
@@ -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<string, {key: string}>} */
|
||||
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}`);
|
||||
}
|
||||
};
|
||||
76
frontend/src/routes/auth/password/change/[id]/+page.svelte
Normal file
76
frontend/src/routes/auth/password/change/[id]/+page.svelte
Normal file
@@ -0,0 +1,76 @@
|
||||
<script>
|
||||
import { applyAction, enhance } from '$app/forms';
|
||||
import { page } from '$app/state';
|
||||
import { receive, send } from '$lib/utils/helpers';
|
||||
|
||||
import { t } from 'svelte-i18n';
|
||||
import InputField from '$lib/components/InputField.svelte';
|
||||
import { onMount } from 'svelte';
|
||||
|
||||
let password = '',
|
||||
confirm_password = '';
|
||||
|
||||
/** @type{string | null} */
|
||||
let token = null;
|
||||
|
||||
onMount(() => {
|
||||
token = page.url.searchParams.get('token');
|
||||
console.log(token);
|
||||
if (!token) {
|
||||
form ||= { errors: [] }; // Ensure form exists with an errors array
|
||||
form.errors.push({
|
||||
field: 'server.general',
|
||||
key: 'server.error.no_auth_token',
|
||||
id: Math.random() * 1000
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
/** @type {import('./$types').ActionData} */
|
||||
export let form;
|
||||
|
||||
/** @type {import('./$types').SubmitFunction} */
|
||||
const handleChange = async () => {
|
||||
return async ({ result }) => {
|
||||
await applyAction(result);
|
||||
};
|
||||
};
|
||||
</script>
|
||||
|
||||
<div class="container">
|
||||
<form class="content" method="POST" use:enhance={handleChange}>
|
||||
<h1 class="step-title title">{$t('change_password')}</h1>
|
||||
{#if form?.errors}
|
||||
{#each form?.errors as error (error.id)}
|
||||
<h4
|
||||
class="step-subtitle warning"
|
||||
in:receive={{ key: error.id }}
|
||||
out:send={{ key: error.id }}
|
||||
>
|
||||
{$t(error.key)}
|
||||
</h4>
|
||||
{/each}
|
||||
{/if}
|
||||
|
||||
<input type="hidden" name="user_id" value={page.params.id} />
|
||||
<input type="hidden" name="token" value={token} />
|
||||
<InputField
|
||||
name="user[password]"
|
||||
type="password"
|
||||
label={$t('password')}
|
||||
placeholder={$t('placeholder.password')}
|
||||
bind:value={password}
|
||||
otherPasswordValue={confirm_password}
|
||||
/>
|
||||
<InputField
|
||||
name="confirm_password"
|
||||
type="password"
|
||||
label={$t('confirm_password')}
|
||||
placeholder={$t('placeholder.password')}
|
||||
bind:value={confirm_password}
|
||||
otherPasswordValue={password}
|
||||
/>
|
||||
|
||||
<button class="button-dark">{$t('change_password')} </button>
|
||||
</form>
|
||||
</div>
|
||||
Reference in New Issue
Block a user