Commit
•
113d498
1
Parent(s):
9b30f5f
✨ Login page + error handling
Browse files- package.json +1 -0
- pnpm-lock.yaml +6 -0
- src/routes/+error.svelte +21 -0
- src/routes/connexion/+error.svelte +7 -0
- src/routes/connexion/+layout.svelte +46 -0
- src/routes/connexion/+page.server.ts +44 -0
- src/routes/connexion/+page.svelte +1 -0
package.json
CHANGED
@@ -39,6 +39,7 @@
|
|
39 |
},
|
40 |
"type": "module",
|
41 |
"dependencies": {
|
|
|
42 |
"form-data": "^4.0.0",
|
43 |
"lodash": "^4.17.21",
|
44 |
"mailgun.js": "^8.0.2",
|
|
|
39 |
},
|
40 |
"type": "module",
|
41 |
"dependencies": {
|
42 |
+
"bcryptjs": "^2.4.3",
|
43 |
"form-data": "^4.0.0",
|
44 |
"lodash": "^4.17.21",
|
45 |
"mailgun.js": "^8.0.2",
|
pnpm-lock.yaml
CHANGED
@@ -12,6 +12,7 @@ specifiers:
|
|
12 |
'@unocss/preset-icons': ^0.46.3
|
13 |
'@unocss/preset-uno': ^0.46.3
|
14 |
'@unocss/reset': ^0.46.3
|
|
|
15 |
eslint: ^8.16.0
|
16 |
eslint-config-prettier: ^8.3.0
|
17 |
eslint-plugin-svelte3: ^4.0.0
|
@@ -32,6 +33,7 @@ specifiers:
|
|
32 |
vite: ^3.1.0
|
33 |
|
34 |
dependencies:
|
|
|
35 |
form-data: 4.0.0
|
36 |
lodash: 4.17.21
|
37 |
mailgun.js: 8.0.2
|
@@ -1543,6 +1545,10 @@ packages:
|
|
1543 |
resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==}
|
1544 |
dev: false
|
1545 |
|
|
|
|
|
|
|
|
|
1546 |
/binary-extensions/2.2.0:
|
1547 |
resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==}
|
1548 |
engines: {node: '>=8'}
|
|
|
12 |
'@unocss/preset-icons': ^0.46.3
|
13 |
'@unocss/preset-uno': ^0.46.3
|
14 |
'@unocss/reset': ^0.46.3
|
15 |
+
bcryptjs: ^2.4.3
|
16 |
eslint: ^8.16.0
|
17 |
eslint-config-prettier: ^8.3.0
|
18 |
eslint-plugin-svelte3: ^4.0.0
|
|
|
33 |
vite: ^3.1.0
|
34 |
|
35 |
dependencies:
|
36 |
+
bcryptjs: 2.4.3
|
37 |
form-data: 4.0.0
|
38 |
lodash: 4.17.21
|
39 |
mailgun.js: 8.0.2
|
|
|
1545 |
resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==}
|
1546 |
dev: false
|
1547 |
|
1548 |
+
/bcryptjs/2.4.3:
|
1549 |
+
resolution: {integrity: sha512-V/Hy/X9Vt7f3BbPJEi8BdVFMByHi+jNXrYkW3huaybV/kQ0KJg0Y6PkEMbn+zeT+i+SiKZ/HMqJGIIt4LZDqNQ==}
|
1550 |
+
dev: false
|
1551 |
+
|
1552 |
/binary-extensions/2.2.0:
|
1553 |
resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==}
|
1554 |
engines: {node: '>=8'}
|
src/routes/+error.svelte
ADDED
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<script lang="ts">
|
2 |
+
import { page } from '$app/stores';
|
3 |
+
import Container from '$lib/components/Container.svelte';
|
4 |
+
</script>
|
5 |
+
|
6 |
+
<Container class="flex items-center h-full">
|
7 |
+
<div class="mx-auto text-center">
|
8 |
+
<p class="text-3xl">Erreur <b class="text-sunray">{$page.status}</b></p>
|
9 |
+
<p class="text-2xl">{$page.error?.message}</p>
|
10 |
+
<p>
|
11 |
+
En cas de problème, contactez-moi à <a
|
12 |
+
href="mailto:contact@bergereenchantee.fr"
|
13 |
+
rel="external"
|
14 |
+
class="link">contact@bergereenchantee.fr</a
|
15 |
+
>
|
16 |
+
ou sur la page <a href="/contact" class="link">contact</a>.
|
17 |
+
</p>
|
18 |
+
</div>
|
19 |
+
</Container>
|
20 |
+
|
21 |
+
<slot />
|
src/routes/connexion/+error.svelte
ADDED
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<script lang="ts">
|
2 |
+
import { page } from '$app/stores';
|
3 |
+
</script>
|
4 |
+
|
5 |
+
<div class="border border-red-500 bg-red-300 rounded-lg pa-2">
|
6 |
+
{$page.error?.message}
|
7 |
+
</div>
|
src/routes/connexion/+layout.svelte
ADDED
@@ -0,0 +1,46 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<script lang="ts">
|
2 |
+
import { enhance } from '$app/forms';
|
3 |
+
import Container from '$lib/components/Container.svelte';
|
4 |
+
</script>
|
5 |
+
|
6 |
+
<Container>
|
7 |
+
<slot />
|
8 |
+
|
9 |
+
<form method="post" use:enhance>
|
10 |
+
<div class="my-4">
|
11 |
+
<label for="email" class="text-sunray text-xl block">Email</label>
|
12 |
+
<input
|
13 |
+
type="email"
|
14 |
+
class="input block"
|
15 |
+
required
|
16 |
+
name="email"
|
17 |
+
id="email"
|
18 |
+
placeholder="E-mail"
|
19 |
+
/>
|
20 |
+
</div>
|
21 |
+
|
22 |
+
<div class="my-4">
|
23 |
+
<label for="password" class="text-sunray text-xl block">Mot de passe</label>
|
24 |
+
<input
|
25 |
+
type="password"
|
26 |
+
class="input required"
|
27 |
+
name="password"
|
28 |
+
id="password"
|
29 |
+
placeholder="Mot de passe"
|
30 |
+
/>
|
31 |
+
</div>
|
32 |
+
|
33 |
+
<button type="submit" class="btn cursor-pointer">Connexion</button>
|
34 |
+
</form>
|
35 |
+
|
36 |
+
<p>Pour créer un compte, vous devez effectuer une commande au préalable.</p>
|
37 |
+
|
38 |
+
<p>
|
39 |
+
En cas de problème, contactez-moi à <a
|
40 |
+
href="mailto:contact@bergereenchantee.fr"
|
41 |
+
rel="external"
|
42 |
+
class="link">contact@bergereenchantee.fr</a
|
43 |
+
>
|
44 |
+
ou sur la page <a href="/contact" class="link">contact</a>.
|
45 |
+
</p>
|
46 |
+
</Container>
|
src/routes/connexion/+page.server.ts
ADDED
@@ -0,0 +1,44 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import { error, redirect } from '@sveltejs/kit';
|
2 |
+
import { users } from '$lib/server/db';
|
3 |
+
import bcrypt from 'bcryptjs';
|
4 |
+
import type { Actions } from './$types';
|
5 |
+
|
6 |
+
export const actions: Actions = {
|
7 |
+
default: async (event) => {
|
8 |
+
const data = await event.request.formData();
|
9 |
+
const email = data.get('email').trim();
|
10 |
+
|
11 |
+
const user = await users.findOne({ email }, { collation: { locale: 'en', strength: 1 } });
|
12 |
+
|
13 |
+
if (!user) {
|
14 |
+
throw error(404, "Utilisateur non trouvé pour l'email: " + email);
|
15 |
+
}
|
16 |
+
|
17 |
+
const password = data.get('password').trim();
|
18 |
+
|
19 |
+
if (!(await bcrypt.compare(password as string, user.hash))) {
|
20 |
+
throw error(401, 'Mauvais mot de passe');
|
21 |
+
}
|
22 |
+
|
23 |
+
let token = user.token;
|
24 |
+
|
25 |
+
if (!token) {
|
26 |
+
token = crypto.randomUUID();
|
27 |
+
await users.updateOne({ _id: user._id }, { $set: { token } });
|
28 |
+
}
|
29 |
+
|
30 |
+
event.cookies.set('bergereToken', token, {
|
31 |
+
path: '/',
|
32 |
+
sameSite: 'lax',
|
33 |
+
secure: true,
|
34 |
+
httpOnly: true,
|
35 |
+
maxAge: 24 * 3600 * 365 * 3
|
36 |
+
});
|
37 |
+
|
38 |
+
if (event.url.searchParams.get('suivant')) {
|
39 |
+
throw redirect(303, event.url.searchParams.get('suivant'));
|
40 |
+
}
|
41 |
+
|
42 |
+
return { success: true };
|
43 |
+
}
|
44 |
+
};
|
src/routes/connexion/+page.svelte
ADDED
@@ -0,0 +1 @@
|
|
|
|
|
1 |
+
<!-- See layout.svelte. Moved code there to be able to render error in-page -->
|