diff --git a/client/src/App.tsx b/client/src/App.tsx
index 5199afa..3fad6fd 100644
--- a/client/src/App.tsx
+++ b/client/src/App.tsx
@@ -28,6 +28,7 @@ import OAuthCallback from './pages/AuthManager/callback/AuthCallback';
const App: React.FC = () => {
const [isAuthenticated, setIsAuthenticated] = useState(ApiService.isLoggedIn());
const [isTeacherAuthenticated, setIsTeacherAuthenticated] = useState(ApiService.isLoggedInTeacher());
+ const [isRoomRequireAuthentication, setRoomsRequireAuth] = useState(null);
const location = useLocation();
// Check login status every time the route changes
@@ -37,7 +38,13 @@ const App: React.FC = () => {
setIsTeacherAuthenticated(ApiService.isLoggedInTeacher());
};
+ const fetchAuthenticatedRooms = async () => {
+ const data = await ApiService.getRoomsRequireAuth();
+ setRoomsRequireAuth(data);
+ };
+
checkLoginStatus();
+ fetchAuthenticatedRooms();
}, [location]);
const handleLogout = () => {
@@ -76,7 +83,7 @@ const App: React.FC = () => {
{/* Pages espace étudiant */}
: }
+ element={( !isRoomRequireAuthentication || isAuthenticated ) ? : }
/>
{/* Pages authentification */}
diff --git a/client/src/pages/AuthManager/callback/AuthCallback.tsx b/client/src/pages/AuthManager/callback/AuthCallback.tsx
index 6ba290d..046abc7 100644
--- a/client/src/pages/AuthManager/callback/AuthCallback.tsx
+++ b/client/src/pages/AuthManager/callback/AuthCallback.tsx
@@ -9,9 +9,11 @@ const OAuthCallback: React.FC = () => {
useEffect(() => {
const searchParams = new URLSearchParams(location.search);
const user = searchParams.get('user');
+ const username = searchParams.get('username');
if (user) {
apiService.saveToken(user);
+ apiService.saveUsername(username || "");
navigate('/');
} else {
navigate('/login');
diff --git a/client/src/pages/Student/JoinRoom/JoinRoom.tsx b/client/src/pages/Student/JoinRoom/JoinRoom.tsx
index e29bfb7..75516b0 100644
--- a/client/src/pages/Student/JoinRoom/JoinRoom.tsx
+++ b/client/src/pages/Student/JoinRoom/JoinRoom.tsx
@@ -15,9 +15,11 @@ import LoadingButton from '@mui/lab/LoadingButton';
import LoginContainer from '../../../components/LoginContainer/LoginContainer'
+import ApiService from '../../../services/ApiService'
+
const JoinRoom: React.FC = () => {
const [roomName, setRoomName] = useState('');
- const [username, setUsername] = useState('');
+ const [username, setUsername] = useState(ApiService.getUsername());
const [socket, setSocket] = useState(null);
const [isWaitingForTeacher, setIsWaitingForTeacher] = useState(false);
const [question, setQuestion] = useState();
diff --git a/client/src/services/ApiService.tsx b/client/src/services/ApiService.tsx
index d5c0b28..b63bbdd 100644
--- a/client/src/services/ApiService.tsx
+++ b/client/src/services/ApiService.tsx
@@ -105,7 +105,43 @@ class ApiService {
}
}
+ public saveUsername(username: string): void {
+ if (!username || username.length === 0) {
+ return;
+ }
+
+ const object = {
+ username: username
+ }
+
+ localStorage.setItem("username", JSON.stringify(object));
+ }
+
+ public getUsername(): string {
+ const objectStr = localStorage.getItem("username");
+
+ if (!objectStr) {
+ return "";
+ }
+
+ const object = JSON.parse(objectStr)
+
+ return object.username;
+ }
+
+ // Route to know if rooms need authentication to join
+ public async getRoomsRequireAuth(): Promise {
+ const url: string = this.constructRequestUrl(`/auth/getRoomsRequireAuth`);
+ const result: AxiosResponse = await axios.get(url);
+
+ if (result.status == 200) {
+ return result.data.roomsRequireAuth;
+ }
+ return false;
+ }
+
public logout(): void {
+ localStorage.removeItem("username");
return localStorage.removeItem("jwt");
}
diff --git a/docker-compose.yaml b/docker-compose.yaml
index 898a78a..770f6db 100644
--- a/docker-compose.yaml
+++ b/docker-compose.yaml
@@ -30,6 +30,7 @@ services:
SITE_URL: http://localhost
FRONTEND_PORT: 5173
USE_PORTS: false
+ AUTHENTICATED_ROOMS: false
volumes:
- ./server/auth_config.json:/usr/src/app/serveur/config/auth_config.json
depends_on:
diff --git a/server/.env.example b/server/.env.example
index 8553a4b..3ab7212 100644
--- a/server/.env.example
+++ b/server/.env.example
@@ -19,3 +19,5 @@ SESSION_Secret='session_secret'
SITE_URL=http://localhost
FRONTEND_PORT=5173
USE_PORTS=false
+
+AUTHENTICATED_ROOMS=false
diff --git a/server/__tests__/auth.test.js b/server/__tests__/auth.test.js
index 0099d03..f3f92d5 100644
--- a/server/__tests__/auth.test.js
+++ b/server/__tests__/auth.test.js
@@ -205,3 +205,40 @@ describe(
});
})
);
+
+describe(
+ "Rooms requiring authentication", () => {
+ // Making a copy of env variables to restore them later
+ const OLD_ENV_VARIABLES = process.env;
+
+ let authConfigInstance;
+
+ beforeAll(() => {
+ authConfigInstance = new AuthConfig();
+ });
+
+ // Clearing cache just in case
+ beforeEach(() => {
+ jest.resetModules();
+ process.env = { ...OLD_ENV_VARIABLES };
+ });
+
+ // Resetting the old values
+ afterAll(() => {
+ process.env = OLD_ENV_VARIABLES;
+ });
+
+ // tests cases as [environment variable value, expected value]
+ const cases = [["true", true], ["false", false], ["", false], ["other_than_true_false", false]];
+ test.each(cases)(
+ "Given %p as AUTHENTICATED_ROOMS environment variable value, returns %p",
+ (envVarArg, expectedResult) => {
+ process.env.AUTHENTICATED_ROOMS = envVarArg;
+ const isAuthRequired = authConfigInstance.getRoomsRequireAuth();
+
+ expect(isAuthRequired).toEqual(expectedResult);
+ }
+ );
+
+ }
+)
diff --git a/server/auth/auth-manager.js b/server/auth/auth-manager.js
index fce031e..27082f9 100644
--- a/server/auth/auth-manager.js
+++ b/server/auth/auth-manager.js
@@ -44,7 +44,7 @@ class AuthManager{
async login(userInfo,req,res,next){
const tokenToSave = jwt.create(userInfo.email, userInfo._id,userInfo.roles);
- res.redirect(`/auth/callback?user=${tokenToSave}`);
+ res.redirect(`/auth/callback?user=${tokenToSave}&username=${userInfo.name}`);
console.info(`L'utilisateur '${userInfo.name}' vient de se connecter`)
}
diff --git a/server/config/auth.js b/server/config/auth.js
index 8f4605e..2b7c4df 100644
--- a/server/config/auth.js
+++ b/server/config/auth.js
@@ -175,6 +175,17 @@ class AuthConfig {
}
}
+ // Check if students must be authenticated to join a room
+ getRoomsRequireAuth() {
+ const roomRequireAuth = process.env.AUTHENTICATED_ROOMS;
+
+ if (!roomRequireAuth || roomRequireAuth !== "true") {
+ return false;
+ }
+
+ return true;
+ }
+
}
diff --git a/server/controllers/auth.js b/server/controllers/auth.js
index 21fa3b1..76769fb 100644
--- a/server/controllers/auth.js
+++ b/server/controllers/auth.js
@@ -20,6 +20,17 @@ class authController {
}
}
+ async getRoomsRequireAuth(req, res, next) {
+ const authC = new AuthConfig();
+ const roomsRequireAuth = authC.getRoomsRequireAuth();
+
+ const response = {
+ roomsRequireAuth
+ }
+
+ return res.json(response);
+ }
+
}
module.exports = new authController;
\ No newline at end of file
diff --git a/server/routers/auth.js b/server/routers/auth.js
index c560864..7260669 100644
--- a/server/routers/auth.js
+++ b/server/routers/auth.js
@@ -5,5 +5,6 @@ const jwt = require('../middleware/jwtToken.js');
const authController = require('../controllers/auth.js')
router.get("/getActiveAuth",authController.getActive);
+router.get("/getRoomsRequireAuth", authController.getRoomsRequireAuth);
module.exports = router;
\ No newline at end of file