Page de login "terminée"
Système presque fini manque juste les cookies et check de la connexion
This commit is contained in:
parent
44370a1b00
commit
081acb3a41
8 changed files with 237 additions and 26 deletions
|
@ -38,6 +38,7 @@
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@prisma/client": "^5.22.0",
|
"@prisma/client": "^5.22.0",
|
||||||
"@types/node": "^22.10.1",
|
"@types/node": "^22.10.1",
|
||||||
|
"argon2": "^0.41.1",
|
||||||
"prisma": "^5.22.0",
|
"prisma": "^5.22.0",
|
||||||
"redis": "^4.7.0",
|
"redis": "^4.7.0",
|
||||||
"svelte-radix": "^2.0.1"
|
"svelte-radix": "^2.0.1"
|
||||||
|
|
31
pnpm-lock.yaml
generated
31
pnpm-lock.yaml
generated
|
@ -14,6 +14,9 @@ importers:
|
||||||
'@types/node':
|
'@types/node':
|
||||||
specifier: ^22.10.1
|
specifier: ^22.10.1
|
||||||
version: 22.10.1
|
version: 22.10.1
|
||||||
|
argon2:
|
||||||
|
specifier: ^0.41.1
|
||||||
|
version: 0.41.1
|
||||||
prisma:
|
prisma:
|
||||||
specifier: ^5.22.0
|
specifier: ^5.22.0
|
||||||
version: 5.22.0
|
version: 5.22.0
|
||||||
|
@ -344,6 +347,10 @@ packages:
|
||||||
resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==}
|
resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==}
|
||||||
engines: {node: '>= 8'}
|
engines: {node: '>= 8'}
|
||||||
|
|
||||||
|
'@phc/format@1.0.0':
|
||||||
|
resolution: {integrity: sha512-m7X9U6BG2+J+R1lSOdCiITLLrxm+cWlNI3HUFA92oLO77ObGNzaKdh8pMLqdZcshtkKuV84olNNXDfMc4FezBQ==}
|
||||||
|
engines: {node: '>=10'}
|
||||||
|
|
||||||
'@pkgjs/parseargs@0.11.0':
|
'@pkgjs/parseargs@0.11.0':
|
||||||
resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==}
|
resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==}
|
||||||
engines: {node: '>=14'}
|
engines: {node: '>=14'}
|
||||||
|
@ -647,6 +654,10 @@ packages:
|
||||||
arg@5.0.2:
|
arg@5.0.2:
|
||||||
resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==}
|
resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==}
|
||||||
|
|
||||||
|
argon2@0.41.1:
|
||||||
|
resolution: {integrity: sha512-dqCW8kJXke8Ik+McUcMDltrbuAWETPyU6iq+4AhxqKphWi7pChB/Zgd/Tp/o8xRLbg8ksMj46F/vph9wnxpTzQ==}
|
||||||
|
engines: {node: '>=16.17.0'}
|
||||||
|
|
||||||
argparse@2.0.1:
|
argparse@2.0.1:
|
||||||
resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==}
|
resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==}
|
||||||
|
|
||||||
|
@ -1141,6 +1152,14 @@ packages:
|
||||||
natural-compare@1.4.0:
|
natural-compare@1.4.0:
|
||||||
resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==}
|
resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==}
|
||||||
|
|
||||||
|
node-addon-api@8.3.0:
|
||||||
|
resolution: {integrity: sha512-8VOpLHFrOQlAH+qA0ZzuGRlALRA6/LVh8QJldbrC4DY0hXoMP0l4Acq8TzFC018HztWiRqyCEj2aTWY2UvnJUg==}
|
||||||
|
engines: {node: ^18 || ^20 || >= 21}
|
||||||
|
|
||||||
|
node-gyp-build@4.8.4:
|
||||||
|
resolution: {integrity: sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==}
|
||||||
|
hasBin: true
|
||||||
|
|
||||||
node-releases@2.0.18:
|
node-releases@2.0.18:
|
||||||
resolution: {integrity: sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==}
|
resolution: {integrity: sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==}
|
||||||
|
|
||||||
|
@ -1844,6 +1863,8 @@ snapshots:
|
||||||
'@nodelib/fs.scandir': 2.1.5
|
'@nodelib/fs.scandir': 2.1.5
|
||||||
fastq: 1.17.1
|
fastq: 1.17.1
|
||||||
|
|
||||||
|
'@phc/format@1.0.0': {}
|
||||||
|
|
||||||
'@pkgjs/parseargs@0.11.0':
|
'@pkgjs/parseargs@0.11.0':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
|
@ -2133,6 +2154,12 @@ snapshots:
|
||||||
|
|
||||||
arg@5.0.2: {}
|
arg@5.0.2: {}
|
||||||
|
|
||||||
|
argon2@0.41.1:
|
||||||
|
dependencies:
|
||||||
|
'@phc/format': 1.0.0
|
||||||
|
node-addon-api: 8.3.0
|
||||||
|
node-gyp-build: 4.8.4
|
||||||
|
|
||||||
argparse@2.0.1: {}
|
argparse@2.0.1: {}
|
||||||
|
|
||||||
aria-query@5.3.2: {}
|
aria-query@5.3.2: {}
|
||||||
|
@ -2619,6 +2646,10 @@ snapshots:
|
||||||
|
|
||||||
natural-compare@1.4.0: {}
|
natural-compare@1.4.0: {}
|
||||||
|
|
||||||
|
node-addon-api@8.3.0: {}
|
||||||
|
|
||||||
|
node-gyp-build@4.8.4: {}
|
||||||
|
|
||||||
node-releases@2.0.18: {}
|
node-releases@2.0.18: {}
|
||||||
|
|
||||||
normalize-path@3.0.0: {}
|
normalize-path@3.0.0: {}
|
||||||
|
|
18
src/lib/components/ui/tabs/index.ts
Normal file
18
src/lib/components/ui/tabs/index.ts
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
import { Tabs as TabsPrimitive } from "bits-ui";
|
||||||
|
import Content from "./tabs-content.svelte";
|
||||||
|
import List from "./tabs-list.svelte";
|
||||||
|
import Trigger from "./tabs-trigger.svelte";
|
||||||
|
|
||||||
|
const Root = TabsPrimitive.Root;
|
||||||
|
|
||||||
|
export {
|
||||||
|
Root,
|
||||||
|
Content,
|
||||||
|
List,
|
||||||
|
Trigger,
|
||||||
|
//
|
||||||
|
Root as Tabs,
|
||||||
|
Content as TabsContent,
|
||||||
|
List as TabsList,
|
||||||
|
Trigger as TabsTrigger,
|
||||||
|
};
|
21
src/lib/components/ui/tabs/tabs-content.svelte
Normal file
21
src/lib/components/ui/tabs/tabs-content.svelte
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
<script lang="ts">
|
||||||
|
import { Tabs as TabsPrimitive } from "bits-ui";
|
||||||
|
import { cn } from "$lib/utils.js";
|
||||||
|
|
||||||
|
type $$Props = TabsPrimitive.ContentProps;
|
||||||
|
|
||||||
|
let className: $$Props["class"] = undefined;
|
||||||
|
export let value: $$Props["value"];
|
||||||
|
export { className as class };
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<TabsPrimitive.Content
|
||||||
|
class={cn(
|
||||||
|
"ring-offset-background focus-visible:ring-ring mt-2 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
{value}
|
||||||
|
{...$$restProps}
|
||||||
|
>
|
||||||
|
<slot />
|
||||||
|
</TabsPrimitive.Content>
|
19
src/lib/components/ui/tabs/tabs-list.svelte
Normal file
19
src/lib/components/ui/tabs/tabs-list.svelte
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
<script lang="ts">
|
||||||
|
import { Tabs as TabsPrimitive } from "bits-ui";
|
||||||
|
import { cn } from "$lib/utils.js";
|
||||||
|
|
||||||
|
type $$Props = TabsPrimitive.ListProps;
|
||||||
|
|
||||||
|
let className: $$Props["class"] = undefined;
|
||||||
|
export { className as class };
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<TabsPrimitive.List
|
||||||
|
class={cn(
|
||||||
|
"bg-muted text-muted-foreground inline-flex h-10 items-center justify-center rounded-md p-1",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
{...$$restProps}
|
||||||
|
>
|
||||||
|
<slot />
|
||||||
|
</TabsPrimitive.List>
|
23
src/lib/components/ui/tabs/tabs-trigger.svelte
Normal file
23
src/lib/components/ui/tabs/tabs-trigger.svelte
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
<script lang="ts">
|
||||||
|
import { Tabs as TabsPrimitive } from "bits-ui";
|
||||||
|
import { cn } from "$lib/utils.js";
|
||||||
|
|
||||||
|
type $$Props = TabsPrimitive.TriggerProps;
|
||||||
|
type $$Events = TabsPrimitive.TriggerEvents;
|
||||||
|
|
||||||
|
let className: $$Props["class"] = undefined;
|
||||||
|
export let value: $$Props["value"];
|
||||||
|
export { className as class };
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<TabsPrimitive.Trigger
|
||||||
|
class={cn(
|
||||||
|
"ring-offset-background focus-visible:ring-ring data-[state=active]:bg-background data-[state=active]:text-foreground inline-flex items-center justify-center whitespace-nowrap rounded-sm px-3 py-1.5 text-sm font-medium transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:shadow-sm",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
{value}
|
||||||
|
{...$$restProps}
|
||||||
|
on:click
|
||||||
|
>
|
||||||
|
<slot />
|
||||||
|
</TabsPrimitive.Trigger>
|
|
@ -1,21 +1,80 @@
|
||||||
import type { Actions } from '@sveltejs/kit';
|
import { type Actions, json } from '@sveltejs/kit';
|
||||||
import prismaClient from '$lib/prismaClient';
|
import prismaClient from '$lib/prismaClient';
|
||||||
|
import * as argon2 from 'argon2';
|
||||||
|
import { redirect, error } from '@sveltejs/kit';
|
||||||
|
|
||||||
export const actions: Actions = {
|
export const actions: Actions = {
|
||||||
login: async ({request}) => {
|
login: async ({request}) => {
|
||||||
const formData = await request.formData();
|
const formData = await request.formData();
|
||||||
|
|
||||||
console.log(formData.get("username"));
|
// @ts-ignore Can't be empty
|
||||||
|
const username = formData.get('username').toString();
|
||||||
|
|
||||||
await prismaClient.user.create({
|
// @ts-ignore Can't be empty
|
||||||
data: {
|
const password = formData.get('password').toString();
|
||||||
email: "fdp",
|
|
||||||
username: "test",
|
const user = await prismaClient.user.findFirst({
|
||||||
surname: "azeza",
|
where: {
|
||||||
name: "aiudhza",
|
username: username,
|
||||||
password: "feur"
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (user == null) {
|
||||||
|
return error(400, {message: "Nom d'utilisateur ou mot de passe invalide."});
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// @ts-ignore Already checked for null
|
||||||
|
if (await argon2.verify(user.password, password)) {
|
||||||
|
console.log("login succesful")
|
||||||
|
} else {
|
||||||
|
return error(400, {message: "Nom d'utilisateur ou mot de passe invalide."});
|
||||||
|
}
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
|
} catch (e) {
|
||||||
|
return error(500, {message: "Erreur interne."})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
register: async ({request}) => {
|
||||||
|
const formData = await request.formData();
|
||||||
|
|
||||||
|
// @ts-ignore Can't be empty
|
||||||
|
const username = formData.get('username').toString();
|
||||||
|
// @ts-ignore Can't be empty
|
||||||
|
const email = formData.get('email').toString();
|
||||||
|
// @ts-ignore Can't be empty
|
||||||
|
const password = formData.get('password').toString();
|
||||||
|
|
||||||
|
const user = await prismaClient.user.findFirst({
|
||||||
|
where: {
|
||||||
|
OR: [
|
||||||
|
{
|
||||||
|
email: email
|
||||||
|
},
|
||||||
|
{
|
||||||
|
username: username
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (user != null) {
|
||||||
|
return error(400, { message: "Un compte avec cette email ou nom d'utilisateur éxiste déjà." });
|
||||||
|
}
|
||||||
|
|
||||||
|
const hash = await argon2.hash(password);
|
||||||
|
|
||||||
|
await prismaClient.user.create({
|
||||||
|
data: {
|
||||||
|
email: email,
|
||||||
|
username: username,
|
||||||
|
name: "",
|
||||||
|
surname: "",
|
||||||
|
password: hash,
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return redirect(302, "/chat");
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -4,15 +4,23 @@
|
||||||
import { Input } from "$lib/components/ui/input";
|
import { Input } from "$lib/components/ui/input";
|
||||||
import * as Card from "$lib/components/ui/card";
|
import * as Card from "$lib/components/ui/card";
|
||||||
import { enhance } from '$app/forms';
|
import { enhance } from '$app/forms';
|
||||||
|
import * as Tabs from "$lib/components/ui/tabs";
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="w-full h-full flex justify-center items-center">
|
<div class="w-full h-full flex justify-center items-center">
|
||||||
<Card.Root class="w-[450px]">
|
|
||||||
|
<Tabs.Root value="login" class="w-[450px]">
|
||||||
|
<Tabs.List class="grid w-full grid-cols-2">
|
||||||
|
<Tabs.Trigger value="login">Se connecter</Tabs.Trigger>
|
||||||
|
<Tabs.Trigger value="register">S'inscrire</Tabs.Trigger>
|
||||||
|
</Tabs.List>
|
||||||
|
|
||||||
|
<Tabs.Content value="login">
|
||||||
|
<Card.Root>
|
||||||
<Card.Header>
|
<Card.Header>
|
||||||
<Card.Title>🌳</Card.Title>
|
<Card.Title>🌳 - Arbres</Card.Title>
|
||||||
<Card.Description>Un chat collaboratif</Card.Description>
|
<Card.Description>Connectez vous pour chatter!</Card.Description>
|
||||||
</Card.Header>
|
</Card.Header>
|
||||||
<form method="POST" action="?/login" use:enhance>
|
<form method="POST" action="?/login" use:enhance>
|
||||||
<Card.Content>
|
<Card.Content>
|
||||||
|
@ -30,4 +38,35 @@
|
||||||
</Card.Footer>
|
</Card.Footer>
|
||||||
</form>
|
</form>
|
||||||
</Card.Root>
|
</Card.Root>
|
||||||
|
</Tabs.Content>
|
||||||
|
|
||||||
|
<Tabs.Content value="register">
|
||||||
|
<Card.Root>
|
||||||
|
<Card.Header>
|
||||||
|
<Card.Title>🌳 - Arbres</Card.Title>
|
||||||
|
<Card.Description>Inscrivez-vous pour chatter!</Card.Description>
|
||||||
|
</Card.Header>
|
||||||
|
<form method="POST" action="?/register" use:enhance>
|
||||||
|
<Card.Content>
|
||||||
|
<div class="grid w-full max-w-sm items-center gap-1.5">
|
||||||
|
<Label for="username">Nom d'utilisateur</Label>
|
||||||
|
<Input type="text" name="username" id="username" />
|
||||||
|
</div>
|
||||||
|
<div class="pt-4 grid w-full max-w-sm items-center gap-1.5">
|
||||||
|
<Label for="email">Adresse email</Label>
|
||||||
|
<Input type="text" name="email" id="email" />
|
||||||
|
</div>
|
||||||
|
<div class="pt-4 grid w-full max-w-sm items-center gap-1.5">
|
||||||
|
<Label for="password">Mot de passe</Label>
|
||||||
|
<Input type="password" name="password" id="password" />
|
||||||
|
</div>
|
||||||
|
</Card.Content>
|
||||||
|
<Card.Footer>
|
||||||
|
<Button type="submit">S'inscrire</Button>
|
||||||
|
</Card.Footer>
|
||||||
|
</form>
|
||||||
|
</Card.Root>
|
||||||
|
</Tabs.Content>
|
||||||
|
|
||||||
|
</Tabs.Root>
|
||||||
</div>
|
</div>
|
Loading…
Add table
Reference in a new issue