Merge branch 'main' of https://github.com/Charles40130/Projet-Dev-Web-Ing1
This commit is contained in:
commit
bdfa1723e2
@ -78,7 +78,7 @@ public class AuthHandler {
|
||||
}
|
||||
|
||||
databaseService.pool
|
||||
.preparedQuery("SELECT password,points FROM users WHERE email = ?")
|
||||
.preparedQuery("SELECT name, surname, password, points FROM users WHERE email = ?") // Ajout de name et surname
|
||||
.execute(Tuple.of(email))
|
||||
.onSuccess(result -> {
|
||||
if (result.rowCount() == 0) {
|
||||
@ -88,13 +88,20 @@ public class AuthHandler {
|
||||
return;
|
||||
}
|
||||
|
||||
String storedHashedPassword = result.iterator().next().getString("password");
|
||||
Integer nbPointsUser = result.iterator().next().getInteger("points");
|
||||
var row = result.iterator().next();
|
||||
String storedHashedPassword = row.getString("password");
|
||||
Integer nbPointsUser = row.getInteger("points");
|
||||
String name = row.getString("name");
|
||||
String surname = row.getString("surname");
|
||||
|
||||
BCrypt.Result verification = BCrypt.verifyer().verify(password.toCharArray(), storedHashedPassword);
|
||||
|
||||
if (verification.verified) {
|
||||
JsonObject claims = new JsonObject().put("sub", email);
|
||||
JsonObject claims = new JsonObject()
|
||||
.put("sub", email)
|
||||
.put("name", name)
|
||||
.put("surname", surname);
|
||||
|
||||
if (nbPointsUser <= 60) {
|
||||
claims.put("role", "user");
|
||||
} else if (nbPointsUser <= 100) {
|
||||
@ -104,6 +111,7 @@ public class AuthHandler {
|
||||
}
|
||||
|
||||
String token = jwtAuth.generateToken(claims);
|
||||
|
||||
context.response()
|
||||
.setStatusCode(200)
|
||||
.end(new JsonObject().put("token", token).encode());
|
||||
@ -119,5 +127,4 @@ public class AuthHandler {
|
||||
.setStatusCode(500)
|
||||
.end(new JsonObject().put("error", "Erreur serveur").encode());
|
||||
});
|
||||
}
|
||||
}
|
||||
}}
|
||||
126
Front-end/package-lock.json
generated
126
Front-end/package-lock.json
generated
@ -13,6 +13,7 @@
|
||||
"@emotion/styled": "^11.14.0",
|
||||
"@mui/material": "^7.0.1",
|
||||
"axios": "^1.8.4",
|
||||
"jwt-decode": "^4.0.0",
|
||||
"lucide-react": "^0.427.0",
|
||||
"react": "^18.3.1",
|
||||
"react-charts": "^3.0.0-beta.57",
|
||||
@ -2070,7 +2071,6 @@
|
||||
"resolved": "https://registry.npmjs.org/async-function/-/async-function-1.0.0.tgz",
|
||||
"integrity": "sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
@ -2819,6 +2819,71 @@
|
||||
"is-arrayish": "^0.2.1"
|
||||
}
|
||||
},
|
||||
"node_modules/es-abstract": {
|
||||
"version": "1.23.9",
|
||||
"resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.9.tgz",
|
||||
"integrity": "sha512-py07lI0wjxAC/DcfK1S6G7iANonniZwTISvdPzk9hzeH0IZIshbuuFxLIU96OyF89Yb9hiqWn8M/bY83KY5vzA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"array-buffer-byte-length": "^1.0.2",
|
||||
"arraybuffer.prototype.slice": "^1.0.4",
|
||||
"available-typed-arrays": "^1.0.7",
|
||||
"call-bind": "^1.0.8",
|
||||
"call-bound": "^1.0.3",
|
||||
"data-view-buffer": "^1.0.2",
|
||||
"data-view-byte-length": "^1.0.2",
|
||||
"data-view-byte-offset": "^1.0.1",
|
||||
"es-define-property": "^1.0.1",
|
||||
"es-errors": "^1.3.0",
|
||||
"es-object-atoms": "^1.0.0",
|
||||
"es-set-tostringtag": "^2.1.0",
|
||||
"es-to-primitive": "^1.3.0",
|
||||
"function.prototype.name": "^1.1.8",
|
||||
"get-intrinsic": "^1.2.7",
|
||||
"get-proto": "^1.0.0",
|
||||
"get-symbol-description": "^1.1.0",
|
||||
"globalthis": "^1.0.4",
|
||||
"gopd": "^1.2.0",
|
||||
"has-property-descriptors": "^1.0.2",
|
||||
"has-proto": "^1.2.0",
|
||||
"has-symbols": "^1.1.0",
|
||||
"hasown": "^2.0.2",
|
||||
"internal-slot": "^1.1.0",
|
||||
"is-array-buffer": "^3.0.5",
|
||||
"is-callable": "^1.2.7",
|
||||
"is-data-view": "^1.0.2",
|
||||
"is-regex": "^1.2.1",
|
||||
"is-shared-array-buffer": "^1.0.4",
|
||||
"is-string": "^1.1.1",
|
||||
"is-typed-array": "^1.1.15",
|
||||
"is-weakref": "^1.1.0",
|
||||
"math-intrinsics": "^1.1.0",
|
||||
"object-inspect": "^1.13.3",
|
||||
"object-keys": "^1.1.1",
|
||||
"object.assign": "^4.1.7",
|
||||
"own-keys": "^1.0.1",
|
||||
"regexp.prototype.flags": "^1.5.3",
|
||||
"safe-array-concat": "^1.1.3",
|
||||
"safe-push-apply": "^1.0.0",
|
||||
"safe-regex-test": "^1.1.0",
|
||||
"set-proto": "^1.0.0",
|
||||
"string.prototype.trim": "^1.2.10",
|
||||
"string.prototype.trimend": "^1.0.9",
|
||||
"string.prototype.trimstart": "^1.0.8",
|
||||
"typed-array-buffer": "^1.0.3",
|
||||
"typed-array-byte-length": "^1.0.3",
|
||||
"typed-array-byte-offset": "^1.0.4",
|
||||
"typed-array-length": "^1.0.7",
|
||||
"unbox-primitive": "^1.1.0",
|
||||
"which-typed-array": "^1.1.18"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/es-define-property": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
|
||||
@ -3788,12 +3853,63 @@
|
||||
"integrity": "sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw==",
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/is-array-buffer": {
|
||||
"version": "3.0.5",
|
||||
"resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz",
|
||||
"integrity": "sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"call-bind": "^1.0.8",
|
||||
"call-bound": "^1.0.3",
|
||||
"get-intrinsic": "^1.2.6"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/is-arrayish": {
|
||||
"version": "0.2.1",
|
||||
"resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
|
||||
"integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/is-async-function": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.1.1.tgz",
|
||||
"integrity": "sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"async-function": "^1.0.0",
|
||||
"call-bound": "^1.0.3",
|
||||
"get-proto": "^1.0.1",
|
||||
"has-tostringtag": "^1.0.2",
|
||||
"safe-regex-test": "^1.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/is-bigint": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.1.0.tgz",
|
||||
"integrity": "sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"has-bigints": "^1.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/is-binary-path": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
|
||||
@ -4269,6 +4385,14 @@
|
||||
"node": ">=4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/jwt-decode": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/jwt-decode/-/jwt-decode-4.0.0.tgz",
|
||||
"integrity": "sha512-+KJGIyHgkGuIq3IEBNftfhW/LfWhXUIY6OmyVWjliu5KH1y0fw7VQ8YndE2O4qZdMSd9SqbnC8GOcZEy0Om7sA==",
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/keyv": {
|
||||
"version": "4.5.4",
|
||||
"resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz",
|
||||
|
||||
@ -14,6 +14,7 @@
|
||||
"@emotion/styled": "^11.14.0",
|
||||
"@mui/material": "^7.0.1",
|
||||
"axios": "^1.8.4",
|
||||
"jwt-decode": "^4.0.0",
|
||||
"lucide-react": "^0.427.0",
|
||||
"react": "^18.3.1",
|
||||
"react-charts": "^3.0.0-beta.57",
|
||||
|
||||
@ -14,7 +14,7 @@ import Sidebar from "./pages/Admin/sidebar.jsx";
|
||||
import User from "./pages/Admin/User.jsx";
|
||||
import Dashboard from "./pages/Admin/Dashboard.jsx";
|
||||
import AdminObjet from "./pages/Admin/AdminObjet.jsx";
|
||||
import ProtectedRoute from './ProtectedRoute.jsx'; // Correction de l'import
|
||||
import ProtectedRoute from "./ProtectedRoute.jsx";
|
||||
|
||||
function App() {
|
||||
return (
|
||||
@ -23,19 +23,28 @@ function App() {
|
||||
<div>
|
||||
<Header />
|
||||
<Routes>
|
||||
{/* Routes publiques */}
|
||||
<Route path="/" element={<Home />} />
|
||||
<Route path="/about" element={<About />} />
|
||||
<Route path="/gestion" element={<ProtectedRoute element={<Gestion />} />} />
|
||||
<Route path="/gestionObjets" element={<ProtectedRoute element={<ObjectManagement />} />} />
|
||||
<Route path="/objet" element={<ProtectedRoute element={<Objet />} />} />
|
||||
<Route path="/signup" element={<Signup />} />
|
||||
<Route path="/login" element={<Login />} />
|
||||
<Route path="/ajouterObjet" element={<ProtectedRoute element={<AddObject />} />} />
|
||||
<Route path="/profil" element={<ProtectedRoute element={<Profil />}/>} />
|
||||
<Route path="/sidebar" element={<Sidebar />} />
|
||||
<Route path="/user" element={<ProtectedRoute element={<User />}/>} />
|
||||
<Route path="/dashboard" element={<Dashboard />} />
|
||||
<Route path="/adminobjet" element={<ProtectedRoute element={<AdminObjet />} />} />
|
||||
|
||||
{/* Routes protégées pour tous les utilisateurs connectés */}
|
||||
<Route path="/gestion" element={<ProtectedRoute element={<Gestion />} allowedRoles={['admin', 'complexe', 'user']} />} />
|
||||
<Route path="/gestionObjets" element={<ProtectedRoute element={<ObjectManagement />} allowedRoles={['admin', 'complexe', 'user']} />} />
|
||||
<Route path="/objet" element={<ProtectedRoute element={<Objet />} allowedRoles={['admin', 'complexe', 'user']} />} />
|
||||
|
||||
{/* Routes protégées pour les admins et complexes */}
|
||||
<Route path="/ajouterObjet" element={<ProtectedRoute element={<AddObject />} allowedRoles={['admin', 'complexe']} />} />
|
||||
<Route path="/profil" element={<ProtectedRoute element={<Profil />} allowedRoles={['admin', 'complexe']} />} />
|
||||
|
||||
{/* Routes protégées pour tous les utilisateurs connectés */}
|
||||
<Route path="/sidebar" element={<ProtectedRoute element={<Sidebar />} allowedRoles={['admin', 'complexe', 'user']} />} />
|
||||
<Route path="/user" element={<ProtectedRoute element={<User />} allowedRoles={['admin', 'complexe', 'user']} />} />
|
||||
|
||||
{/* Routes protégées pour les admins uniquement */}
|
||||
<Route path="/dashboard" element={<ProtectedRoute element={<Dashboard />} allowedRoles={['admin']} />} />
|
||||
<Route path="/adminobjet" element={<ProtectedRoute element={<AdminObjet />} allowedRoles={['admin']} />} />
|
||||
</Routes>
|
||||
</div>
|
||||
</Router>
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
// src/AuthContext.js
|
||||
import React, { createContext, useContext, useState, useEffect } from "react";
|
||||
import { jwtDecode } from "jwt-decode";
|
||||
|
||||
|
||||
// Créer le contexte
|
||||
const AuthContext = createContext();
|
||||
@ -7,22 +8,25 @@ const AuthContext = createContext();
|
||||
// Hook pour accéder facilement au contexte
|
||||
export const useAuth = () => useContext(AuthContext);
|
||||
|
||||
// Fournisseur de contexte qui gère l'état du token
|
||||
// Fournisseur de contexte qui gère l'état du token et de l'utilisateur
|
||||
export const AuthProvider = ({ children }) => {
|
||||
const [token, setToken] = useState(localStorage.getItem("token"));
|
||||
const [user, setUser] = useState(null);
|
||||
|
||||
// Met à jour le token lorsque localStorage change
|
||||
// Met à jour le token et décode l'utilisateur
|
||||
useEffect(() => {
|
||||
const handleStorageChange = () => {
|
||||
setToken(localStorage.getItem("token"));
|
||||
};
|
||||
|
||||
window.addEventListener("storage", handleStorageChange);
|
||||
|
||||
return () => {
|
||||
window.removeEventListener("storage", handleStorageChange);
|
||||
};
|
||||
}, []);
|
||||
if (token) {
|
||||
try {
|
||||
const decoded = jwtDecode(token);
|
||||
setUser(decoded);
|
||||
} catch (error) {
|
||||
console.error("Erreur lors du décodage du token:", error);
|
||||
setUser(null);
|
||||
}
|
||||
} else {
|
||||
setUser(null);
|
||||
}
|
||||
}, [token]);
|
||||
|
||||
const login = (newToken) => {
|
||||
localStorage.setItem("token", newToken);
|
||||
@ -32,10 +36,11 @@ export const AuthProvider = ({ children }) => {
|
||||
const logout = () => {
|
||||
localStorage.removeItem("token");
|
||||
setToken(null);
|
||||
setUser(null);
|
||||
};
|
||||
|
||||
return (
|
||||
<AuthContext.Provider value={{ token, login, logout }}>
|
||||
<AuthContext.Provider value={{ token, user, login, logout }}>
|
||||
{children}
|
||||
</AuthContext.Provider>
|
||||
);
|
||||
|
||||
@ -1,16 +1,22 @@
|
||||
import { useAuth } from './AuthContext'; // Utilisation du contexte d'authentification
|
||||
import { Navigate } from 'react-router-dom'; // Utilisation de React Router pour la redirection
|
||||
import React from "react";
|
||||
import { Navigate } from "react-router-dom";
|
||||
import { useAuth } from "./AuthContext"; // Utilisation du contexte d'authentification
|
||||
|
||||
function ProtectedRoute({ element }) {
|
||||
const { token } = useAuth(); // Vérifier si un token existe, donc si l'utilisateur est authentifié
|
||||
function ProtectedRoute({ element, allowedRoles }) {
|
||||
const { token, user } = useAuth(); // Vérifier si un token existe, donc si l'utilisateur est authentifié
|
||||
|
||||
// Si l'utilisateur n'est pas authentifié, redirigez-le vers la page de login
|
||||
if (!token) {
|
||||
return <Navigate to="/login" />;
|
||||
}
|
||||
|
||||
// Si l'utilisateur est authentifié, permettez l'accès à la route
|
||||
// Si l'utilisateur est authentifié mais n'a pas le bon rôle
|
||||
if (allowedRoles && !allowedRoles.includes(user?.role)) {
|
||||
return <Navigate to="/" />;
|
||||
}
|
||||
|
||||
// Si l'utilisateur est authentifié et a les bons rôles, permettez l'accès à la route
|
||||
return element;
|
||||
}
|
||||
|
||||
export default ProtectedRoute; // Export de la fonction
|
||||
export default ProtectedRoute;
|
||||
|
||||
@ -8,6 +8,7 @@ function Home() {
|
||||
const [activeFilter, setActiveFilter] = useState('all');
|
||||
const [name, setName] = useState([]);
|
||||
const { token, logout } = useAuth();
|
||||
const { user } = useAuth();
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-gradient-to-br from-blue-50 to-indigo-50">
|
||||
@ -15,10 +16,13 @@ function Home() {
|
||||
<div className="text-center mb-12">
|
||||
<h2 className="text-4xl font-bold text-gray-900 mb-4">
|
||||
Bienvenue dans ta ville intelligente.</h2>
|
||||
{token ? (
|
||||
<><h2>Tu es connecté</h2>
|
||||
|
||||
</>):(
|
||||
{user ? (
|
||||
<>
|
||||
<h1>Bienvenue, {user.name} {user.surname}!</h1>
|
||||
<p>Email : {user.sub}</p>
|
||||
<p>Rôle : {user.role}</p>
|
||||
</>
|
||||
):(
|
||||
<h2>Non connecté</h2>
|
||||
)}
|
||||
<p className="text-xl text-gray-600 max-w-3xl mx-auto">
|
||||
|
||||
Loading…
Reference in New Issue
Block a user