mirror of
https://github.com/ets-cfuhrman-pfe/EvalueTonSavoir.git
synced 2025-08-11 21:23:54 -04:00
added permission for teacher routes.
coté backend doit etre fait
This commit is contained in:
parent
8770726873
commit
deaaa8bc9b
8 changed files with 87 additions and 34 deletions
9
client/package-lock.json
generated
9
client/package-lock.json
generated
|
|
@ -22,6 +22,7 @@
|
|||
"esbuild": "^0.23.1",
|
||||
"gift-pegjs": "^1.0.2",
|
||||
"jest-environment-jsdom": "^29.7.0",
|
||||
"jwt-decode": "^4.0.0",
|
||||
"katex": "^0.16.11",
|
||||
"marked": "^14.1.2",
|
||||
"nanoid": "^5.0.2",
|
||||
|
|
@ -9417,6 +9418,14 @@
|
|||
"node": ">= 10.0.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/katex": {
|
||||
"version": "0.16.11",
|
||||
"resolved": "https://registry.npmjs.org/katex/-/katex-0.16.11.tgz",
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@
|
|||
"esbuild": "^0.23.1",
|
||||
"gift-pegjs": "^1.0.2",
|
||||
"jest-environment-jsdom": "^29.7.0",
|
||||
"jwt-decode": "^4.0.0",
|
||||
"katex": "^0.16.11",
|
||||
"marked": "^14.1.2",
|
||||
"nanoid": "^5.0.2",
|
||||
|
|
|
|||
|
|
@ -26,23 +26,24 @@ import ApiService from './services/ApiService';
|
|||
import OAuthCallback from './pages/AuthManager/callback/AuthCallback';
|
||||
|
||||
const App: React.FC = () => {
|
||||
const [isAuthenticated, setIsAuthenticated] = useState(ApiService.isLoggedIn()); // Initial check
|
||||
const location = useLocation(); // Hook to detect route changes
|
||||
const [isAuthenticated, setIsAuthenticated] = useState(ApiService.isLoggedIn());
|
||||
const [isTeacherAuthenticated, setIsTeacherAuthenticated] = useState(ApiService.isLoggedInTeacher());
|
||||
const location = useLocation();
|
||||
|
||||
// Check login status every time the route changes
|
||||
useEffect(() => {
|
||||
const checkLoginStatus = () => {
|
||||
const loggedIn = ApiService.isLoggedIn();
|
||||
setIsAuthenticated(loggedIn); // Update state if login status changes
|
||||
console.log('App.tsx - Login status:', loggedIn);
|
||||
setIsAuthenticated(ApiService.isLoggedIn());
|
||||
setIsTeacherAuthenticated(ApiService.isLoggedInTeacher());
|
||||
};
|
||||
|
||||
checkLoginStatus(); // Check login status whenever the route changes
|
||||
}, [location]); // Re-run when the location (route) changes
|
||||
checkLoginStatus();
|
||||
}, [location]);
|
||||
|
||||
const handleLogout = () => {
|
||||
ApiService.logout();
|
||||
setIsAuthenticated(false); // Ensure we log out the user in the state as well
|
||||
setIsAuthenticated(false);
|
||||
setIsTeacherAuthenticated(false);
|
||||
};
|
||||
|
||||
return (
|
||||
|
|
@ -57,19 +58,19 @@ const App: React.FC = () => {
|
|||
{/* Pages espace enseignant */}
|
||||
<Route
|
||||
path="/teacher/dashboard"
|
||||
element={isAuthenticated ? <Dashboard /> : <Navigate to="/login" />}
|
||||
element={isTeacherAuthenticated ? <Dashboard /> : <Navigate to="/login" />}
|
||||
/>
|
||||
<Route
|
||||
path="/teacher/share/:id"
|
||||
element={isAuthenticated ? <Share /> : <Navigate to="/login" />}
|
||||
element={isTeacherAuthenticated ? <Share /> : <Navigate to="/login" />}
|
||||
/>
|
||||
<Route
|
||||
path="/teacher/editor-quiz/:id"
|
||||
element={isAuthenticated ? <QuizForm /> : <Navigate to="/login" />}
|
||||
element={isTeacherAuthenticated ? <QuizForm /> : <Navigate to="/login" />}
|
||||
/>
|
||||
<Route
|
||||
path="/teacher/manage-room/:id"
|
||||
element={isAuthenticated ? <ManageRoom /> : <Navigate to="/login" />}
|
||||
element={isTeacherAuthenticated ? <ManageRoom /> : <Navigate to="/login" />}
|
||||
/>
|
||||
|
||||
{/* Pages espace étudiant */}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import { useEffect } from 'react';
|
||||
import { useNavigate, useLocation } from 'react-router-dom';
|
||||
import apiService from '../../../services/ApiService';
|
||||
import { jwtDecode } from 'jwt-decode';
|
||||
|
||||
const OAuthCallback: React.FC = () => {
|
||||
const navigate = useNavigate();
|
||||
|
|
@ -15,6 +16,10 @@ const OAuthCallback: React.FC = () => {
|
|||
console.log(user);
|
||||
apiService.saveToken(user);
|
||||
|
||||
const decodedToken = jwtDecode(user);
|
||||
const { email } = decodedToken as { email: string;};
|
||||
console.log(email + " connected!");
|
||||
|
||||
// Navigate to the dashboard or another page
|
||||
navigate('/');
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -1,13 +1,12 @@
|
|||
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
|
||||
// JoinRoom.tsx
|
||||
import React, { useEffect, useState } from 'react';
|
||||
|
||||
import { TextField } from '@mui/material';
|
||||
import { TextField, FormLabel, RadioGroup, FormControlLabel, Radio, Box } from '@mui/material';
|
||||
import LoadingButton from '@mui/lab/LoadingButton';
|
||||
|
||||
import LoginContainer from '../../../../components/LoginContainer/LoginContainer'
|
||||
import LoginContainer from '../../../../components/LoginContainer/LoginContainer';
|
||||
import ApiService from '../../../../services/ApiService';
|
||||
|
||||
const Register: React.FC = () => {
|
||||
|
|
@ -15,33 +14,31 @@ const Register: React.FC = () => {
|
|||
|
||||
const [email, setEmail] = useState('');
|
||||
const [password, setPassword] = useState('');
|
||||
const [role, setRole] = useState('etudiant');
|
||||
|
||||
const [connectionError, setConnectionError] = useState<string>('');
|
||||
const [isConnecting] = useState<boolean>(false);
|
||||
|
||||
useEffect(() => {
|
||||
return () => {
|
||||
|
||||
};
|
||||
return () => { };
|
||||
}, []);
|
||||
|
||||
const register = async () => {
|
||||
const result = await ApiService.register(email, password);
|
||||
const result = await ApiService.register(email, password, role);
|
||||
|
||||
if (result != true) {
|
||||
if (result !== true) {
|
||||
setConnectionError(result);
|
||||
return;
|
||||
}
|
||||
|
||||
navigate("/login")
|
||||
navigate("/login");
|
||||
};
|
||||
|
||||
|
||||
return (
|
||||
<LoginContainer
|
||||
title='Créer un compte'
|
||||
error={connectionError}>
|
||||
|
||||
title="Créer un compte"
|
||||
error={connectionError}
|
||||
>
|
||||
<TextField
|
||||
label="Email"
|
||||
variant="outlined"
|
||||
|
|
@ -63,6 +60,20 @@ const Register: React.FC = () => {
|
|||
fullWidth
|
||||
/>
|
||||
|
||||
<Box sx={{ display: 'flex', alignItems: 'center', marginBottom: '1rem' }}>
|
||||
<FormLabel component="legend" sx={{ marginRight: '1rem' }}>Choisir votre rôle</FormLabel>
|
||||
<RadioGroup
|
||||
row
|
||||
aria-label="role"
|
||||
name="role"
|
||||
value={role}
|
||||
onChange={(e) => setRole(e.target.value)}
|
||||
>
|
||||
<FormControlLabel value="etudiant" control={<Radio />} label="Étudiant" />
|
||||
<FormControlLabel value="professeur" control={<Radio />} label="Professeur" />
|
||||
</RadioGroup>
|
||||
</Box>
|
||||
|
||||
<LoadingButton
|
||||
loading={isConnecting}
|
||||
onClick={register}
|
||||
|
|
@ -72,9 +83,7 @@ const Register: React.FC = () => {
|
|||
>
|
||||
S'inscrire
|
||||
</LoadingButton>
|
||||
|
||||
</LoginContainer>
|
||||
|
||||
);
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ const Register: React.FC = () => {
|
|||
}, []);
|
||||
|
||||
const register = async () => {
|
||||
const result = await ApiService.register(email, password);
|
||||
const result = await ApiService.register(email, password, "temp"); // "temp", car ce fichier n'est plus utilisé. il est déplacer dans /AuthManager
|
||||
|
||||
if (result != true) {
|
||||
setConnectionError(result);
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import axios, { AxiosError, AxiosResponse } from 'axios';
|
||||
import {jwtDecode} from 'jwt-decode';
|
||||
import { ENV_VARIABLES } from '../constants';
|
||||
|
||||
import { QuizType } from '../Types/QuizType';
|
||||
|
|
@ -66,8 +67,6 @@ class ApiService {
|
|||
public isLoggedIn(): boolean {
|
||||
const token = this.getToken()
|
||||
|
||||
console.log("Check if loggedIn : " + token);
|
||||
|
||||
if (token == null) {
|
||||
return false;
|
||||
}
|
||||
|
|
@ -78,6 +77,35 @@ class ApiService {
|
|||
return true;
|
||||
}
|
||||
|
||||
public isLoggedInTeacher(): boolean {
|
||||
const token = this.getToken();
|
||||
|
||||
console.log("Check if loggedIn : " + token);
|
||||
|
||||
if (token == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
const decodedToken = jwtDecode(token) as { role: string };
|
||||
|
||||
const userRole = decodedToken.role;
|
||||
const requiredRole = 'professeur';
|
||||
|
||||
if (userRole !== requiredRole) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Update token expiry
|
||||
this.saveToken(token);
|
||||
|
||||
return true;
|
||||
} catch (error) {
|
||||
console.error("Error decoding token:", error);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public logout(): void {
|
||||
return localStorage.removeItem("jwt");
|
||||
}
|
||||
|
|
@ -88,7 +116,7 @@ class ApiService {
|
|||
* @returns true if successful
|
||||
* @returns A error string if unsuccessful,
|
||||
*/
|
||||
public async register(email: string, password: string): Promise<any> {
|
||||
public async register(email: string, password: string, role: string): Promise<any> {
|
||||
try {
|
||||
|
||||
if (!email || !password) {
|
||||
|
|
@ -97,7 +125,7 @@ class ApiService {
|
|||
|
||||
const url: string = this.constructRequestUrl(`/user/register`);
|
||||
const headers = this.constructRequestHeaders();
|
||||
const body = { email, password };
|
||||
const body = { email, password, role };
|
||||
|
||||
const result: AxiosResponse = await axios.post(url, body, { headers: headers });
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ services:
|
|||
|
||||
frontend:
|
||||
build:
|
||||
context: ./server
|
||||
context: ./client
|
||||
dockerfile: Dockerfile
|
||||
container_name: frontend
|
||||
ports:
|
||||
|
|
|
|||
Loading…
Reference in a new issue