diff --git a/Back-end/src/main/java/com/example/starter/AuthHandler.java b/Back-end/src/main/java/com/example/starter/AuthHandler.java index 2e62e0e..12205b3 100644 --- a/Back-end/src/main/java/com/example/starter/AuthHandler.java +++ b/Back-end/src/main/java/com/example/starter/AuthHandler.java @@ -30,8 +30,9 @@ public class AuthHandler { String email = body.getString("email"); String gender = body.getString("gender"); String password = body.getString("password"); + String pseudo = body.getString("pseudo"); - if (name == null || surname == null || email == null || gender == null || password == null) { + if (name == null || surname == null || email == null || gender == null || password == null || pseudo == null) { context.response() .setStatusCode(400) .end(new JsonObject().put("error", "Tous les champs sont requis").encode()); @@ -41,8 +42,8 @@ public class AuthHandler { String hashedPassword = BCrypt.withDefaults().hashToString(12, password.toCharArray()); databaseService.pool - .preparedQuery("INSERT INTO users (name, surname, email, gender, password) VALUES (?, ?, ?, ?, ?)") - .execute(Tuple.of(name, surname, email, gender, hashedPassword)) + .preparedQuery("INSERT INTO users (name, surname, email, gender, password, pseudo) VALUES (?, ?, ?, ?, ?, ?)") + .execute(Tuple.of(name, surname, email, gender, hashedPassword,pseudo)) .onSuccess(result -> { context.response() .setStatusCode(201) diff --git a/Back-end/src/main/java/com/example/starter/MainVerticle.java b/Back-end/src/main/java/com/example/starter/MainVerticle.java index b669774..b45f367 100644 --- a/Back-end/src/main/java/com/example/starter/MainVerticle.java +++ b/Back-end/src/main/java/com/example/starter/MainVerticle.java @@ -56,12 +56,16 @@ public class MainVerticle extends AbstractVerticle { router.post("/modifRangeData").handler(setWeatherData::setRangeData); router.post("/deleteObject").handler(setObjects::deleteObject); router.get("/users").handler(queryUsers::getUsers); + router.post("/user").handler(queryUsers::getUser); router.post("/setUserPoints").handler(setUser::setUserPoints); router.post("/deleteUser").handler(setUser::deleteUser); + router.post("/updateProfil").handler(setUser::updateUserProfile); + router.post("/changePassword").handler(setUser::changeUserPassword); // Routes d'authentification router.post("/signup").handler(authHandler::handleSignup); router.post("/login").handler(authHandler::handleLogin); + // Création du serveur HTTP vertx.createHttpServer() diff --git a/Back-end/src/main/java/com/example/starter/QueryUsers.java b/Back-end/src/main/java/com/example/starter/QueryUsers.java index e065c02..6305e81 100644 --- a/Back-end/src/main/java/com/example/starter/QueryUsers.java +++ b/Back-end/src/main/java/com/example/starter/QueryUsers.java @@ -4,6 +4,7 @@ import io.vertx.core.json.JsonArray; import io.vertx.core.json.JsonObject; import io.vertx.ext.web.RoutingContext; import io.vertx.sqlclient.Row; +import io.vertx.sqlclient.Tuple; public class QueryUsers { private DatabaseService databaseService; @@ -25,19 +26,20 @@ public class QueryUsers { .onSuccess(rows -> { JsonArray users = new JsonArray(); for (Row row : rows) { - int points=row.getInteger("points"); + int points = row.getInteger("points"); JsonObject user = new JsonObject() .put("id", row.getInteger("id")) .put("name", row.getString("name")) .put("surname", row.getString("surname")) .put("email", row.getString("email")) .put("gender", row.getString("gender")) - .put("points",points); - if(points<=60){ + .put("pseudo",row.getString("pseudo")) + .put("points", points); + if (points <= 60) { user.put("role", "user"); - }else if(points<=100){ + } else if (points <= 100) { user.put("role", "complexe"); - }else if(points>=200){ + } else if (points >= 200) { user.put("role", "admin"); } users.add(user); @@ -48,4 +50,56 @@ public class QueryUsers { }); } + + public void getUser(RoutingContext context) { + JsonObject body = context.body().asJsonObject(); + if (body == null) { + context.response() + .setStatusCode(400) + .end(new JsonObject().put("error", "Corps de la requête manquant").encode()); + return; + } + //Integer idUser = body.getInteger("idUser"); + Integer idUser = 4; + databaseService.pool + .preparedQuery("SELECT * FROM users WHERE id=?;") + .execute(Tuple.of(idUser)) + .onFailure(e -> { + System.err.println("Erreur de récupération de la BDD :" + e.getMessage()); + context.response() + .setStatusCode(500) + .end(new JsonObject().put("error", "Erreur de récupération de la BDD").encode()); + }) + .onSuccess(rows -> { + if (rows.size() == 0) { + context.response() + .setStatusCode(404) + .end(new JsonObject().put("error", "Utilisateur non trouvé").encode()); + return; + } + + Row row = rows.iterator().next(); + int points = row.getInteger("points"); + JsonObject user = new JsonObject() + .put("id", row.getInteger("id")) + .put("name", row.getString("name")) + .put("surname", row.getString("surname")) + .put("email", row.getString("email")) + .put("gender", row.getString("gender")) + .put("pseudo",row.getString("pseudo")) + .put("points", points); + + if (points <= 60) { + user.put("role", "user"); + } else if (points <= 100) { + user.put("role", "complexe"); + } else if (points >= 200) { + user.put("role", "admin"); + } + + context.response() + .putHeader("content-type", "application/json; charset=UTF-8") + .end(user.encode()); + }); + } } diff --git a/Back-end/src/main/java/com/example/starter/SetUser.java b/Back-end/src/main/java/com/example/starter/SetUser.java index 6bcd9b2..47aa996 100644 --- a/Back-end/src/main/java/com/example/starter/SetUser.java +++ b/Back-end/src/main/java/com/example/starter/SetUser.java @@ -1,5 +1,6 @@ package com.example.starter; +import at.favre.lib.crypto.bcrypt.BCrypt; import io.vertx.core.json.JsonObject; import io.vertx.ext.web.RoutingContext; import io.vertx.sqlclient.Tuple; @@ -10,6 +11,7 @@ public class SetUser { public SetUser(DatabaseService ddbs) { this.databaseService = ddbs; } + public void updateUserPoints(Integer userId, Integer points) { databaseService.pool .preparedQuery("UPDATE users SET points=points+? WHERE id=?") @@ -25,6 +27,105 @@ public class SetUser { } }); } + + public void changeUserPassword(RoutingContext context) { + JsonObject body = context.body().asJsonObject(); + if (body == null) { + context.response() + .setStatusCode(400) + .end(new JsonObject().put("error", "Corps de la requête manquant").encode()); + return; + } + Integer id = body.getInteger("id"); + String oldPassword = body.getString("oldPassword"); + String newPassword = body.getString("newPassword"); + + databaseService.pool + .preparedQuery("SELECT password FROM users WHERE id=?") + .execute(Tuple.of(id)) + .onFailure(e -> { + System.err.println("Erreur de récupération de la BDD :" + e.getMessage()); + context.response() + .setStatusCode(500) + .end(new JsonObject().put("error", "Erreur de récupération de la BDD").encode()); + }) + .onSuccess(rows -> { + if (rows.rowCount() == 0) { + context.response() + .setStatusCode(404) + .end(new JsonObject().put("error", "Utilisateur non trouvé").encode()); + return; + } + + String currentPassword = rows.iterator().next().getString("password"); + BCrypt.Result verification = BCrypt.verifyer().verify(oldPassword.toCharArray(), currentPassword); + + if (!verification.verified) { + context.response() + .setStatusCode(401) + .end(new JsonObject().put("error", "Ancien mot de passe incorrect").encode()); + return; + } + String hashedPassword = BCrypt.withDefaults().hashToString(12, newPassword.toCharArray()); + + databaseService.pool + .preparedQuery("UPDATE users SET password=? WHERE id=?") + .execute(Tuple.of(hashedPassword, id)) + .onFailure(e -> { + System.err.println("Erreur lors de la mise à jour du mot de passe :" + e.getMessage()); + context.response() + .setStatusCode(500) + .end(new JsonObject() + .put("error", "Erreur lors de la mise à jour du mot de passe") + .encode()); + }) + .onSuccess(updateRows -> { + context.response() + .putHeader("content-type", "application/json: charset=UTF-8") + .end(new JsonObject().put("success", "Le mot de passe a bien été mis à jour") + .encode()); + }); + }); + } + + public void updateUserProfile(RoutingContext context) { + JsonObject body = context.body().asJsonObject(); + if (body == null) { + context.response() + .setStatusCode(400) + .end(new JsonObject().put("error", "Corps de la requête manquant").encode()); + return; + } + Integer id = body.getInteger("id"); + String name = body.getString("name"); + String surname = body.getString("surname"); + String pseudo = body.getString("pseudo"); + + databaseService.pool + .preparedQuery("UPDATE users SET name=?, surname=?, pseudo=? WHERE id=?") + .execute(Tuple.of(name, surname,pseudo, id)) + .onFailure(e -> { + System.err.println("Erreur de récupération de la BDD :" + e.getMessage()); + context.response() + .setStatusCode(500) + .end(new JsonObject().put("error", "Erreur de récupération de la BDD").encode()); + }) + .onSuccess(rows -> { + if (rows.rowCount() == 0) { + context.response() + .setStatusCode(404) + .end(new JsonObject().put("error", "Utilisateur non trouvé").encode()); + return; + } + context.response() + .putHeader("content-type", "application/json: charset=UTF-8") + .end(new JsonObject() + .put("success", "Les informations de l'utilisateur ont bien été mises à jour") + .encode()); + return; + }); + } + public void setUserPoints(RoutingContext context) { JsonObject body = context.body().asJsonObject(); if (body == null) { @@ -59,36 +160,37 @@ public class SetUser { return; }); } - public void deleteUser(RoutingContext context){ + + public void deleteUser(RoutingContext context) { JsonObject body = context.body().asJsonObject(); - if(body== null){ + if (body == null) { context.response() - .setStatusCode(400) - .end(new JsonObject().put("error","Corps de la requête manquant").encode()); + .setStatusCode(400) + .end(new JsonObject().put("error", "Corps de la requête manquant").encode()); return; } Integer id = body.getInteger("id"); databaseService.pool - .preparedQuery("DELETE FROM users WHERE id=?") - .execute(Tuple.of(id)) - .onFailure(e->{ - System.err.println("Erreur de récupération de la BDD :"+e.getMessage()); - context.response() - .setStatusCode(500) - .end(new JsonObject().put("error","Erreur de récupération de la BDD").encode()); - }) - .onSuccess(rows -> { - if(rows.rowCount()==0){ + .preparedQuery("DELETE FROM users WHERE id=?") + .execute(Tuple.of(id)) + .onFailure(e -> { + System.err.println("Erreur de récupération de la BDD :" + e.getMessage()); context.response() + .setStatusCode(500) + .end(new JsonObject().put("error", "Erreur de récupération de la BDD").encode()); + }) + .onSuccess(rows -> { + if (rows.rowCount() == 0) { + context.response() .setStatusCode(404) .end(new JsonObject().put("error", "Utilisateur non trouvé").encode()); return; - } - context.response() - .putHeader("content-type","application/json: charset=UTF-8") - .end(new JsonObject().put("success", "L'utilisateur à bien été supprimé").encode()); - return; - }); + } + context.response() + .putHeader("content-type", "application/json: charset=UTF-8") + .end(new JsonObject().put("success", "L'utilisateur à bien été supprimé").encode()); + return; + }); } } diff --git a/Front-end/src/App.jsx b/Front-end/src/App.jsx index c80fc95..ff6cf89 100644 --- a/Front-end/src/App.jsx +++ b/Front-end/src/App.jsx @@ -9,7 +9,7 @@ import Objet from "./pages/Gestion/Objet.jsx"; import AddObject from "./pages/Gestion/AddObject.jsx"; import Signup from "./pages/Signup.jsx"; import Login from "./pages/Login.jsx"; -import Settings from "./pages/Settings.jsx"; +import Profil from "./pages/Profil.jsx"; import Sidebar from "./pages/Admin/sidebar.jsx"; import User from "./pages/Admin/User.jsx"; import Dashboard from "./pages/Admin/Dashboard.jsx"; diff --git a/Front-end/src/pages/Gestion/Gestion.jsx b/Front-end/src/pages/Gestion/Gestion.jsx index dce1545..991b850 100644 --- a/Front-end/src/pages/Gestion/Gestion.jsx +++ b/Front-end/src/pages/Gestion/Gestion.jsx @@ -9,7 +9,6 @@ import { UserPlus, RadioTower, Binoculars, - Settings, BadgePlus, } from "lucide-react"; function Gestion() { diff --git a/Front-end/src/pages/Login.jsx b/Front-end/src/pages/Login.jsx index 7a06d01..21e6fae 100644 --- a/Front-end/src/pages/Login.jsx +++ b/Front-end/src/pages/Login.jsx @@ -1,7 +1,7 @@ import React, { useState } from "react"; -import { Mail, Lock } from "lucide-react"; +import { Mail, Lock, AlertCircle } from "lucide-react"; import { useNavigate, Link } from "react-router-dom"; -import axios from "axios"; // Assurez-vous d'avoir axios importé +import axios from "axios"; import { useAuth } from "../AuthContext"; import { API_BASE_URL } from "../config"; @@ -10,6 +10,7 @@ function Login() { email: "", password: "", }); + const [error, setError] = useState(""); const { login } = useAuth(); // Utilisation du hook useAuth pour accéder à la fonction login const navigate = useNavigate(); // Initialisation de useNavigate @@ -19,43 +20,72 @@ function Login() { ...prev, [name]: value, })); + // Réinitialiser l'erreur lorsque l'utilisateur commence à modifier le formulaire + if (error) setError(""); }; const handleSubmit = async (e) => { e.preventDefault(); + setError(""); // Réinitialiser les erreurs à chaque tentative try { - const response = await fetch(`${API_BASE_URL}/login`, { - method: "POST", + const response = await axios.post(`${API_BASE_URL}/login`, formData, { headers: { "Content-Type": "application/json", }, - body: JSON.stringify(formData), }); + const data = response.data; - // Récupérer les données JSON de la réponse - const data = await response.json(); - - // Vérifiez que la réponse contient bien un token if (data.token) { - // Appel de la fonction login du contexte pour stocker le token login(data.token); - - // Rediriger vers la page d'accueil après la connexion navigate("/"); } else { - console.error("Token manquant dans la réponse"); + setError("Authentification échouée : token manquant dans la réponse"); } } catch (error) { console.error("Erreur lors de la connexion", error); + + if (error.response) { + // Le serveur a répondu avec un statut d'erreur (4xx, 5xx) + if (error.response.status === 401) { + setError("Email ou mot de passe incorrect"); + } else if (error.response.status === 422) { + setError("Données de formulaire invalides"); + } else if (error.response.status >= 500) { + setError("Erreur serveur. Veuillez réessayer plus tard."); + } else { + setError( + error.response.data.message || + "Une erreur s'est produite lors de la connexion" + ); + } + } else if (error.request) { + // La requête a été faite mais pas de réponse reçue + setError( + "Impossible de joindre le serveur. Vérifiez votre connexion internet." + ); + } else { + // Une erreur s'est produite lors de la configuration de la requête + setError("Une erreur s'est produite. Veuillez réessayer."); + } } }; + return (