Compare commits

...

1 Commits

Author SHA1 Message Date
Fred 53883f9e04 feat authentification 2025-04-23 15:02:53 +02:00
4 changed files with 247 additions and 3 deletions

22
package-lock.json generated
View File

@ -9,10 +9,12 @@
"version": "0.1.0",
"dependencies": {
"@prisma/client": "^6.6.0",
"bcryptjs": "^3.0.2",
"next": "15.3.0",
"prisma": "^6.6.0",
"react": "^19.0.0",
"react-dom": "^19.0.0"
"react-dom": "^19.0.0",
"slugify": "^1.6.6"
},
"devDependencies": {
"@eslint/eslintrc": "^3",
@ -2461,6 +2463,15 @@
"dev": true,
"license": "MIT"
},
"node_modules/bcryptjs": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/bcryptjs/-/bcryptjs-3.0.2.tgz",
"integrity": "sha512-k38b3XOZKv60C4E2hVsXTolJWfkGRMbILBIe2IBITXciy5bOsTKot5kDrf3ZfufQtQOUN5mXceUEpU1rTl9Uog==",
"license": "BSD-3-Clause",
"bin": {
"bcrypt": "bin/bcrypt"
}
},
"node_modules/brace-expansion": {
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
@ -5787,6 +5798,15 @@
"is-arrayish": "^0.3.1"
}
},
"node_modules/slugify": {
"version": "1.6.6",
"resolved": "https://registry.npmjs.org/slugify/-/slugify-1.6.6.tgz",
"integrity": "sha512-h+z7HKHYXj6wJU+AnS/+IH8Uh9fdcX1Lrhg1/VMdf9PwoBQXFcXiAdsy2tSK0P6gKwJLXp02r90ahUCqHk9rrw==",
"license": "MIT",
"engines": {
"node": ">=8.0.0"
}
},
"node_modules/source-map-js": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",

View File

@ -6,14 +6,17 @@
"dev": "next dev --turbopack",
"build": "next build",
"start": "next start",
"lint": "next lint"
"lint": "next lint",
"start:migrate:prod" : "npx prisma migrate deploy && npm run start"
},
"dependencies": {
"@prisma/client": "^6.6.0",
"bcryptjs": "^3.0.2",
"next": "15.3.0",
"prisma": "^6.6.0",
"react": "^19.0.0",
"react-dom": "^19.0.0"
"react-dom": "^19.0.0",
"slugify": "^1.6.6"
},
"devDependencies": {
"@eslint/eslintrc": "^3",

View File

@ -0,0 +1,179 @@
"use server"
import prisma from "@/lib/db";
import bcrypt from "bcryptjs";
import { cookies } from "next/headers";
import slugify from "slugify";
export async function register(formData : FormData){
//Permet de récupérer les données demandées à l'utilisateur lors de l'inscription
const {email,password,passwordRepeat} = Object.fromEntries(formData)
if(password !== passwordRepeat){
throw new Error("Le passwords ne correspond pas")
}
try{
//Vérification du mail
const verifUser = await prisma.utilisateur.findFirst({
where : {
ut_mail : email.toString()
}
})
if(verifUser){
throw new Error("Utilisateur déjà inscrit")
}
//slugify de l'email
const slug = slugify(email.toString().substring(0,email.toString().indexOf("@")),{lower:true,strict:true})
//hash du mdp
const salt = await bcrypt.genSalt(10)
const hashedPassword = await bcrypt.hash(password.toString(),salt)
//creation de l'utilisateur
const result = await prisma.utilisateur.create({
data :{
ut_mail : email.toString(),
ut_mdp : hashedPassword.toString(),
ut_slug : slug
}
})
if(result){
return {success: true}
}
throw new Error("Anomalie lors de la création du user")
}catch(err){
const error = err as Error
throw new Error(error.message || "une erreur à été rencontrée lors de la création de l'utilisateur")
}
}
export async function login(formData : FormData){
const {email,password} = Object.fromEntries(formData)
try{
//vérification si l'utilisateur est trouvé
const user = await prisma.utilisateur.findFirst({
where : {
ut_mail : email.toString()
}
})
if(!user){
throw new Error("Invalide crédential")
}
//vérification du mdp
const isPasswordValid = await bcrypt.compare(password.toString(), user.ut_mdp)
if(!isPasswordValid){
throw new Error("Invalide crédential")
}
//vérification si une session de connexion existe
const existingSession = await prisma.session.findFirst({
where : {
se_ut_id : user.ut_id
}
})
//vérification si la session existe mais expiré
// delete de l'enreg pour le recréer
let verifDeleteSession = false
if(existingSession && new Date() > existingSession.expireAt ){
const deleteSession = await prisma.session.delete({
where : {
se_id : existingSession.se_id
}
})
if(deleteSession){
verifDeleteSession = true
}
}
//vérification si une session de connexion existe et tjr actif
// on regenere le cookie ensuite
let verifValiditeSession = false
if(existingSession && new Date() < existingSession.expireAt){
verifValiditeSession = true
}
let sessionidCreate = ""
if(!existingSession || verifDeleteSession){
const createSession = await prisma.session.create({
data : {
se_ut_id : user.ut_id,
expireAt : new Date(Date.now() + 7*24*60*60*1000)
}
})
if(createSession){
sessionidCreate = createSession.se_id
}
}
const cookieStore = await cookies()
if(sessionidCreate !== ""){
cookieStore.set("sessionId",sessionidCreate,{
httpOnly : true,
secure: process.env.NODE_ENV ==="production",
path:"/",
maxAge: 24*60*60,
sameSite: "lax"
})
}
if(verifValiditeSession && existingSession?.se_id){
cookieStore.set("sessionId",existingSession?.se_id,{
httpOnly : true,
secure: process.env.NODE_ENV ==="production",
path:"/",
maxAge: 24*60*60,
sameSite: "lax"
})
}
return {success : true}
}catch(err){
const error = err as Error
throw new Error(error.message || "une erreur à été rencontrée lors de la connexion de l'utilisateur")
}
}
export async function verifSession(){
try{
const cookie = await cookies()
const verif = cookie.get("sessionId")
if(verif){
const verifExpireSession = await prisma.session.findUnique({
where : {
se_id : verif.value
}
})
if(verifExpireSession && new Date() > verifExpireSession.expireAt){
await prisma.session.delete({
where : {
se_id : verifExpireSession.se_id
}
})
return {success : false}
}else{
cookie.set("sessionId",verif.value,{
httpOnly : true,
secure: process.env.NODE_ENV ==="production",
path:"/",
maxAge: 24*60*60,
sameSite: "lax"
})
return {success : true}
}
}
return {success : false}
}catch(err){
const error = err as Error
throw new Error(error.message || "une erreur à été rencontrée lors de la vérification de la session")
}
}

42
src/actions/user/user.ts Normal file
View File

@ -0,0 +1,42 @@
import prisma from "@/lib/db";
export async function getInfoUser(slug : string){
try{
const user = await prisma.utilisateur.findFirst({
where : {
ut_slug : slug
}
})
if(user){
return {success : true, user}
}
return {success : false, message : "Impossible de trouver les infos de l'utilisateur"}
}catch(err){
const error = err as Error
throw new Error(error.message || "une erreur à été rencontrée lors de la recherche de l'utilisateur")
}
}
export async function deleteUser(slug : string){
try{
const user = await prisma.utilisateur.findFirst({
where : {
ut_slug : slug
}
})
if(user){
await prisma.utilisateur.delete({
where : {
ut_id : user.ut_id
}
})
return {success : true}
}
return {success : false, message : "Impossible de supprimer l'utilisateur"}
}catch(err){
const error = err as Error
throw new Error(error.message || "une erreur à été rencontrée lors suppression de l'utilisateur")
}
}