mirror of
https://github.com/ets-cfuhrman-pfe/EvalueTonSavoir.git
synced 2025-08-11 21:23:54 -04:00
Compare commits
28 commits
d57c61f78f
...
4959e02acf
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4959e02acf | ||
|
|
e0ac770230 | ||
|
|
f4e21ee7a9 | ||
|
|
ecf4f9a819 | ||
|
|
ebd6101a64 | ||
|
|
c3de76cd20 | ||
|
|
b46c1c1934 | ||
|
|
5c64f60021 | ||
|
|
f2fe6031bb | ||
|
|
3712464873 | ||
|
|
c754d71623 | ||
|
|
e2c4e5cba2 | ||
|
|
e113e2f9e9 | ||
|
|
327875dceb | ||
|
|
00c0abdf73 | ||
|
|
ed78dc12ef | ||
|
|
d75850dac4 | ||
|
|
92b97681fc | ||
|
|
e04d09b8c5 | ||
|
|
123c49662f | ||
|
|
4181a73a7e | ||
|
|
8be2efbe48 | ||
|
|
46dae02d47 | ||
|
|
c8f9c5470c | ||
|
|
e4aa91863c | ||
|
|
2b9665a47d | ||
|
|
0a8f8580f4 | ||
|
|
f5a2be82ca |
21 changed files with 2288 additions and 3192 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -73,7 +73,7 @@ web_modules/
|
||||||
.yarn-integrity
|
.yarn-integrity
|
||||||
|
|
||||||
# dotenv environment variable files
|
# dotenv environment variable files
|
||||||
.env
|
server/.env
|
||||||
.env.development.local
|
.env.development.local
|
||||||
.env.test.local
|
.env.test.local
|
||||||
.env.production.local
|
.env.production.local
|
||||||
|
|
|
||||||
|
|
@ -1,2 +1 @@
|
||||||
**/node_modules
|
**/node_modules
|
||||||
.env
|
|
||||||
2
client/.env
Normal file
2
client/.env
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
VITE_BACKEND_URL=http://localhost:4400
|
||||||
|
VITE_AZURE_BACKEND_URL=http://localhost:4400
|
||||||
|
|
@ -1,7 +1,2 @@
|
||||||
global.import = {
|
process.env.VITE_BACKEND_URL = 'http://localhost:4000/';
|
||||||
meta: {
|
process.env.VITE_BACKEND_SOCKET_URL = 'https://ets-glitch-backend.glitch.me/';
|
||||||
env: {
|
|
||||||
VITE_BACKEND_URL: 'https://ets-glitch-backend.glitch.me/'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
|
||||||
5234
client/package-lock.json
generated
5234
client/package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
|
@ -5,11 +5,11 @@ import { ENV_VARIABLES } from '../../constants';
|
||||||
|
|
||||||
jest.mock('socket.io-client');
|
jest.mock('socket.io-client');
|
||||||
|
|
||||||
jest.mock('../../constants', () => ({
|
// jest.mock('../../constants', () => ({
|
||||||
ENV_VARIABLES: {
|
// ENV_VARIABLES: {
|
||||||
VITE_BACKEND_URL: 'https://ets-glitch-backend.glitch.me/'
|
// VITE_BACKEND_SOCKET_URL: 'https://ets-glitch-backend.glitch.me/'
|
||||||
}
|
// }
|
||||||
}));
|
// }));
|
||||||
|
|
||||||
describe('WebSocketService', () => {
|
describe('WebSocketService', () => {
|
||||||
let mockSocket: Partial<Socket>;
|
let mockSocket: Partial<Socket>;
|
||||||
|
|
@ -29,13 +29,13 @@ describe('WebSocketService', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
test('connect should initialize socket connection', () => {
|
test('connect should initialize socket connection', () => {
|
||||||
WebsocketService.connect(ENV_VARIABLES.VITE_BACKEND_URL);
|
WebsocketService.connect(ENV_VARIABLES.VITE_BACKEND_SOCKET_URL);
|
||||||
expect(io).toHaveBeenCalled();
|
expect(io).toHaveBeenCalled();
|
||||||
expect(WebsocketService['socket']).toBe(mockSocket);
|
expect(WebsocketService['socket']).toBe(mockSocket);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('disconnect should terminate socket connection', () => {
|
test('disconnect should terminate socket connection', () => {
|
||||||
mockSocket = WebsocketService.connect(ENV_VARIABLES.VITE_BACKEND_URL);
|
mockSocket = WebsocketService.connect(ENV_VARIABLES.VITE_BACKEND_SOCKET_URL);
|
||||||
expect(WebsocketService['socket']).toBeTruthy();
|
expect(WebsocketService['socket']).toBeTruthy();
|
||||||
WebsocketService.disconnect();
|
WebsocketService.disconnect();
|
||||||
expect(mockSocket.disconnect).toHaveBeenCalled();
|
expect(mockSocket.disconnect).toHaveBeenCalled();
|
||||||
|
|
@ -43,7 +43,7 @@ describe('WebSocketService', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
test('createRoom should emit create-room event', () => {
|
test('createRoom should emit create-room event', () => {
|
||||||
WebsocketService.connect(ENV_VARIABLES.VITE_BACKEND_URL);
|
WebsocketService.connect(ENV_VARIABLES.VITE_BACKEND_SOCKET_URL);
|
||||||
WebsocketService.createRoom();
|
WebsocketService.createRoom();
|
||||||
expect(mockSocket.emit).toHaveBeenCalledWith('create-room');
|
expect(mockSocket.emit).toHaveBeenCalledWith('create-room');
|
||||||
});
|
});
|
||||||
|
|
@ -52,7 +52,7 @@ describe('WebSocketService', () => {
|
||||||
const roomName = 'testRoom';
|
const roomName = 'testRoom';
|
||||||
const question = { id: 1, text: 'Sample Question' };
|
const question = { id: 1, text: 'Sample Question' };
|
||||||
|
|
||||||
mockSocket = WebsocketService.connect(ENV_VARIABLES.VITE_BACKEND_URL);
|
mockSocket = WebsocketService.connect(ENV_VARIABLES.VITE_BACKEND_SOCKET_URL);
|
||||||
WebsocketService.nextQuestion(roomName, question);
|
WebsocketService.nextQuestion(roomName, question);
|
||||||
expect(mockSocket.emit).toHaveBeenCalledWith('next-question', { roomName, question });
|
expect(mockSocket.emit).toHaveBeenCalledWith('next-question', { roomName, question });
|
||||||
});
|
});
|
||||||
|
|
@ -61,7 +61,7 @@ describe('WebSocketService', () => {
|
||||||
const roomName = 'testRoom';
|
const roomName = 'testRoom';
|
||||||
const questions = [{ id: 1, text: 'Sample Question' }];
|
const questions = [{ id: 1, text: 'Sample Question' }];
|
||||||
|
|
||||||
mockSocket = WebsocketService.connect(ENV_VARIABLES.VITE_BACKEND_URL);
|
mockSocket = WebsocketService.connect(ENV_VARIABLES.VITE_BACKEND_SOCKET_URL);
|
||||||
WebsocketService.launchStudentModeQuiz(roomName, questions);
|
WebsocketService.launchStudentModeQuiz(roomName, questions);
|
||||||
expect(mockSocket.emit).toHaveBeenCalledWith('launch-student-mode', {
|
expect(mockSocket.emit).toHaveBeenCalledWith('launch-student-mode', {
|
||||||
roomName,
|
roomName,
|
||||||
|
|
@ -72,7 +72,7 @@ describe('WebSocketService', () => {
|
||||||
test('endQuiz should emit end-quiz event with correct parameters', () => {
|
test('endQuiz should emit end-quiz event with correct parameters', () => {
|
||||||
const roomName = 'testRoom';
|
const roomName = 'testRoom';
|
||||||
|
|
||||||
mockSocket = WebsocketService.connect(ENV_VARIABLES.VITE_BACKEND_URL);
|
mockSocket = WebsocketService.connect(ENV_VARIABLES.VITE_BACKEND_SOCKET_URL);
|
||||||
WebsocketService.endQuiz(roomName);
|
WebsocketService.endQuiz(roomName);
|
||||||
expect(mockSocket.emit).toHaveBeenCalledWith('end-quiz', { roomName });
|
expect(mockSocket.emit).toHaveBeenCalledWith('end-quiz', { roomName });
|
||||||
});
|
});
|
||||||
|
|
@ -81,7 +81,7 @@ describe('WebSocketService', () => {
|
||||||
const enteredRoomName = 'testRoom';
|
const enteredRoomName = 'testRoom';
|
||||||
const username = 'testUser';
|
const username = 'testUser';
|
||||||
|
|
||||||
mockSocket = WebsocketService.connect(ENV_VARIABLES.VITE_BACKEND_URL);
|
mockSocket = WebsocketService.connect(ENV_VARIABLES.VITE_BACKEND_SOCKET_URL);
|
||||||
WebsocketService.joinRoom(enteredRoomName, username);
|
WebsocketService.joinRoom(enteredRoomName, username);
|
||||||
expect(mockSocket.emit).toHaveBeenCalledWith('join-room', { enteredRoomName, username });
|
expect(mockSocket.emit).toHaveBeenCalledWith('join-room', { enteredRoomName, username });
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -56,7 +56,7 @@ const MultipleChoiceQuestion: React.FC<Props> = (props) => {
|
||||||
(choice.isCorrect ? '✅' : '❌')}
|
(choice.isCorrect ? '✅' : '❌')}
|
||||||
<div className={`circle ${selected}`}>{alphabet[i]}</div>
|
<div className={`circle ${selected}`}>{alphabet[i]}</div>
|
||||||
<div className={`answer-text ${selected}`}>
|
<div className={`answer-text ${selected}`}>
|
||||||
{formatLatex(choice.text.text)}
|
<div dangerouslySetInnerHTML={{ __html: formatLatex(choice.text.text) }} />
|
||||||
</div>
|
</div>
|
||||||
</Button>
|
</Button>
|
||||||
{choice.feedback && showAnswer && (
|
{choice.feedback && showAnswer && (
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,11 @@
|
||||||
// constants.tsx
|
// constants.tsx
|
||||||
const ENV_VARIABLES = {
|
const ENV_VARIABLES = {
|
||||||
MODE: 'production',
|
MODE: 'production',
|
||||||
VITE_BACKEND_URL: process.env.VITE_BACKEND_URL || ""
|
VITE_BACKEND_URL: process.env.VITE_BACKEND_URL || "",
|
||||||
|
VITE_BACKEND_SOCKET_URL: process.env.VITE_BACKEND_SOCKET_URL || "",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
console.log(`ENV_VARIABLES.VITE_BACKEND_URL=${ENV_VARIABLES.VITE_BACKEND_URL}`);
|
||||||
|
console.log(`ENV_VARIABLES.VITE_BACKEND_SOCKET_URL=${ENV_VARIABLES.VITE_BACKEND_SOCKET_URL}`);
|
||||||
|
|
||||||
export { ENV_VARIABLES };
|
export { ENV_VARIABLES };
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,8 @@ const JoinRoom: React.FC = () => {
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const handleCreateSocket = () => {
|
const handleCreateSocket = () => {
|
||||||
const socket = webSocketService.connect(ENV_VARIABLES.VITE_BACKEND_URL);
|
console.log(`JoinRoom: handleCreateSocket: ${ENV_VARIABLES.VITE_BACKEND_SOCKET_URL}`);
|
||||||
|
const socket = webSocketService.connect(ENV_VARIABLES.VITE_BACKEND_SOCKET_URL);
|
||||||
|
|
||||||
socket.on('join-success', () => {
|
socket.on('join-success', () => {
|
||||||
setIsWaitingForTeacher(true);
|
setIsWaitingForTeacher(true);
|
||||||
|
|
@ -63,10 +64,10 @@ const JoinRoom: React.FC = () => {
|
||||||
socket.on('connect_error', (error) => {
|
socket.on('connect_error', (error) => {
|
||||||
switch (error.message) {
|
switch (error.message) {
|
||||||
case 'timeout':
|
case 'timeout':
|
||||||
setConnectionError("Le serveur n'est pas disponible");
|
setConnectionError("JoinRoom: timeout: Le serveur n'est pas disponible");
|
||||||
break;
|
break;
|
||||||
case 'websocket error':
|
case 'websocket error':
|
||||||
setConnectionError("Le serveur n'est pas disponible");
|
setConnectionError("JoinRoom: websocket error: Le serveur n'est pas disponible");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
setIsConnecting(false);
|
setIsConnecting(false);
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,7 @@ import {
|
||||||
FileDownload,
|
FileDownload,
|
||||||
Add,
|
Add,
|
||||||
Upload,
|
Upload,
|
||||||
|
FolderCopy,
|
||||||
ContentCopy,
|
ContentCopy,
|
||||||
Edit,
|
Edit,
|
||||||
Share,
|
Share,
|
||||||
|
|
@ -414,7 +415,7 @@ const Dashboard: React.FC = () => {
|
||||||
color="primary"
|
color="primary"
|
||||||
onClick={handleDuplicateFolder}
|
onClick={handleDuplicateFolder}
|
||||||
disabled={selectedFolderId == ''} // cannot action on all
|
disabled={selectedFolderId == ''} // cannot action on all
|
||||||
> <ContentCopy /> </IconButton>
|
> <FolderCopy /> </IconButton>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
|
||||||
<Tooltip title="Supprimer dossier" placement="top">
|
<Tooltip title="Supprimer dossier" placement="top">
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,6 @@
|
||||||
|
|
||||||
.quizEditor .editSection {
|
.quizEditor .editSection {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 78vh;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -49,6 +49,7 @@ const ManageRoom: React.FC = () => {
|
||||||
setQuiz(quiz as QuizType);
|
setQuiz(quiz as QuizType);
|
||||||
|
|
||||||
if (!socket) {
|
if (!socket) {
|
||||||
|
console.log(`no socket in ManageRoom, creating one.`);
|
||||||
createWebSocketRoom();
|
createWebSocketRoom();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -80,15 +81,16 @@ const ManageRoom: React.FC = () => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const createWebSocketRoom = () => {
|
const createWebSocketRoom = () => {
|
||||||
|
console.log('Creating WebSocket room...');
|
||||||
setConnectingError('');
|
setConnectingError('');
|
||||||
const socket = webSocketService.connect(ENV_VARIABLES.VITE_BACKEND_URL);
|
const socket = webSocketService.connect(ENV_VARIABLES.VITE_BACKEND_SOCKET_URL);
|
||||||
|
|
||||||
socket.on('connect', () => {
|
socket.on('connect', () => {
|
||||||
webSocketService.createRoom();
|
webSocketService.createRoom();
|
||||||
});
|
});
|
||||||
socket.on('connect_error', (error) => {
|
socket.on('connect_error', (error) => {
|
||||||
setConnectingError('Erreur lors de la connexion... Veuillez réessayer');
|
setConnectingError('Erreur lors de la connexion... Veuillez réessayer');
|
||||||
console.error('WebSocket connection error:', error);
|
console.error('ManageRoom: WebSocket connection error:', error);
|
||||||
});
|
});
|
||||||
socket.on('create-success', (roomName: string) => {
|
socket.on('create-success', (roomName: string) => {
|
||||||
setRoomName(roomName);
|
setRoomName(roomName);
|
||||||
|
|
|
||||||
|
|
@ -246,7 +246,7 @@ class ApiService {
|
||||||
const result: AxiosResponse = await axios.post(url, body, { headers: headers });
|
const result: AxiosResponse = await axios.post(url, body, { headers: headers });
|
||||||
|
|
||||||
if (result.status !== 200) {
|
if (result.status !== 200) {
|
||||||
throw new Error(`La supression du compte a échoué. Status: ${result.status}`);
|
throw new Error(`La suppression du compte a échoué. Status: ${result.status}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -328,7 +328,8 @@ class ApiService {
|
||||||
if (axios.isAxiosError(error)) {
|
if (axios.isAxiosError(error)) {
|
||||||
const err = error as AxiosError;
|
const err = error as AxiosError;
|
||||||
const data = err.response?.data as { error: string } | undefined;
|
const data = err.response?.data as { error: string } | undefined;
|
||||||
return data?.error || 'Erreur serveur inconnue lors de la requête.';
|
const url = err.config?.url || 'URL inconnue';
|
||||||
|
return data?.error || `Erreur serveur inconnue lors de la requête (${url}).`;
|
||||||
}
|
}
|
||||||
|
|
||||||
return `Une erreur inattendue s'est produite.`
|
return `Une erreur inattendue s'est produite.`
|
||||||
|
|
|
||||||
|
|
@ -21,11 +21,20 @@ class WebSocketService {
|
||||||
private socket: Socket | null = null;
|
private socket: Socket | null = null;
|
||||||
|
|
||||||
connect(backendUrl: string): Socket {
|
connect(backendUrl: string): Socket {
|
||||||
// console.log(backendUrl);
|
console.log(`WebSocketService.connect('${backendUrl}')`);
|
||||||
this.socket = io(`${backendUrl}`, {
|
|
||||||
|
// // Ensure the URL uses wss: if the URL starts with https:
|
||||||
|
// const protocol = backendUrl.startsWith('https:') ? 'wss:' : 'ws:';
|
||||||
|
// console.log(`WebSocketService.connect: protocol=${protocol}`);
|
||||||
|
// const url = backendUrl.replace(/^http(s):/, protocol);
|
||||||
|
// console.log(`WebSocketService.connect: changed url=${url}`);
|
||||||
|
const url = backendUrl || window.location.host;
|
||||||
|
|
||||||
|
this.socket = io(url, {
|
||||||
transports: ['websocket'],
|
transports: ['websocket'],
|
||||||
reconnectionAttempts: 1
|
reconnectionAttempts: 1
|
||||||
});
|
});
|
||||||
|
|
||||||
return this.socket;
|
return this.socket;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
"target": "ESNext",
|
"target": "ESNext",
|
||||||
"useDefineForClassFields": true,
|
"useDefineForClassFields": true,
|
||||||
"lib": ["ES2020", "DOM", "DOM.Iterable"],
|
"lib": ["ES2020", "DOM", "DOM.Iterable"],
|
||||||
"module": "ES2020",
|
"module": "ESNext",
|
||||||
"skipLibCheck": true,
|
"skipLibCheck": true,
|
||||||
|
|
||||||
/* Bundler mode */
|
/* Bundler mode */
|
||||||
|
|
|
||||||
|
|
@ -3,13 +3,22 @@ import react from '@vitejs/plugin-react-swc';
|
||||||
import pluginChecker from 'vite-plugin-checker';
|
import pluginChecker from 'vite-plugin-checker';
|
||||||
import EnvironmentPlugin from 'vite-plugin-environment';
|
import EnvironmentPlugin from 'vite-plugin-environment';
|
||||||
|
|
||||||
|
// Filter out environment variables with invalid identifiers
|
||||||
|
const filteredEnv = Object.keys(process.env).reduce((acc, key) => {
|
||||||
|
// Only include environment variables with valid JavaScript identifiers
|
||||||
|
if (/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(key)) {
|
||||||
|
acc[key] = process.env[key];
|
||||||
|
}
|
||||||
|
return acc;
|
||||||
|
}, {});
|
||||||
|
|
||||||
// https://vitejs.dev/config/
|
// https://vitejs.dev/config/
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
base: "/",
|
base: "/",
|
||||||
plugins: [
|
plugins: [
|
||||||
react(),
|
react(),
|
||||||
pluginChecker({ typescript: true }),
|
pluginChecker({ typescript: true }),
|
||||||
EnvironmentPlugin('all'),
|
EnvironmentPlugin(filteredEnv),
|
||||||
],
|
],
|
||||||
preview: {
|
preview: {
|
||||||
port: 5173,
|
port: 5173,
|
||||||
|
|
@ -21,4 +30,12 @@ export default defineConfig({
|
||||||
host: true,
|
host: true,
|
||||||
origin: "http://0.0.0.0:5173",
|
origin: "http://0.0.0.0:5173",
|
||||||
},
|
},
|
||||||
|
build: {
|
||||||
|
sourcemap: true, // Enable source maps
|
||||||
|
rollupOptions: {
|
||||||
|
output: {
|
||||||
|
sourcemapExcludeSources: true, // Exclude sources from source maps
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,3 @@
|
||||||
version: '3'
|
|
||||||
|
|
||||||
services:
|
services:
|
||||||
|
|
||||||
frontend:
|
frontend:
|
||||||
|
|
@ -7,6 +5,10 @@ services:
|
||||||
container_name: frontend
|
container_name: frontend
|
||||||
ports:
|
ports:
|
||||||
- "5173:5173"
|
- "5173:5173"
|
||||||
|
environment:
|
||||||
|
VITE_BACKEND_URL: "http://localhost:4400"
|
||||||
|
# don't define VITE_BACKEND_SOCKET_URL so it will default to window.location.host
|
||||||
|
# VITE_BACKEND_SOCKET_URL: ""
|
||||||
restart: always
|
restart: always
|
||||||
|
|
||||||
backend:
|
backend:
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
// Import API
|
// Import API
|
||||||
const express = require("express");
|
const express = require("express");
|
||||||
const http = require("http");
|
const http = require("http");
|
||||||
const dotenv = require('dotenv')
|
const dotenv = require('dotenv');
|
||||||
|
|
||||||
// Import Sockets
|
// Import Sockets
|
||||||
const { setupWebsocket } = require("./socket/socket");
|
const { setupWebsocket } = require("./socket/socket");
|
||||||
|
|
@ -39,9 +39,9 @@ module.exports.images = imagesControllerInstance;
|
||||||
const userRouter = require('./routers/users.js');
|
const userRouter = require('./routers/users.js');
|
||||||
const folderRouter = require('./routers/folders.js');
|
const folderRouter = require('./routers/folders.js');
|
||||||
const quizRouter = require('./routers/quiz.js');
|
const quizRouter = require('./routers/quiz.js');
|
||||||
const imagesRouter = require('./routers/images.js')
|
const imagesRouter = require('./routers/images.js');
|
||||||
|
|
||||||
// Setup environement
|
// Setup environment
|
||||||
dotenv.config();
|
dotenv.config();
|
||||||
const errorHandler = require("./middleware/errorHandler.js");
|
const errorHandler = require("./middleware/errorHandler.js");
|
||||||
|
|
||||||
|
|
@ -50,7 +50,7 @@ const app = express();
|
||||||
const cors = require("cors");
|
const cors = require("cors");
|
||||||
const bodyParser = require('body-parser');
|
const bodyParser = require('body-parser');
|
||||||
|
|
||||||
const configureServer = (httpServer) => {
|
const configureServer = (httpServer, isDev) => {
|
||||||
return new Server(httpServer, {
|
return new Server(httpServer, {
|
||||||
path: "/socket.io",
|
path: "/socket.io",
|
||||||
cors: {
|
cors: {
|
||||||
|
|
@ -58,14 +58,22 @@ const configureServer = (httpServer) => {
|
||||||
methods: ["GET", "POST"],
|
methods: ["GET", "POST"],
|
||||||
credentials: true,
|
credentials: true,
|
||||||
},
|
},
|
||||||
|
secure: !isDev, // true for https, false for http
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
// Start sockets
|
// Start sockets (depending on the dev or prod environment)
|
||||||
const server = http.createServer(app);
|
let server = http.createServer(app);
|
||||||
|
let isDev = process.env.NODE_ENV === 'development';
|
||||||
|
|
||||||
|
console.log(`Environnement: ${process.env.NODE_ENV} (${isDev ? 'dev' : 'prod'})`);
|
||||||
|
|
||||||
const io = configureServer(server);
|
const io = configureServer(server);
|
||||||
|
console.log(`server.io configured: ${io.secure ? 'secure' : 'not secure'}`);
|
||||||
|
|
||||||
setupWebsocket(io);
|
setupWebsocket(io);
|
||||||
|
console.log(`Websocket setup with on() listeners.`);
|
||||||
|
|
||||||
app.use(cors());
|
app.use(cors());
|
||||||
app.use(bodyParser.urlencoded({ extended: true }));
|
app.use(bodyParser.urlencoded({ extended: true }));
|
||||||
app.use(bodyParser.json());
|
app.use(bodyParser.json());
|
||||||
|
|
@ -76,22 +84,20 @@ app.use('/api/folder', folderRouter);
|
||||||
app.use('/api/quiz', quizRouter);
|
app.use('/api/quiz', quizRouter);
|
||||||
app.use('/api/image', imagesRouter);
|
app.use('/api/image', imagesRouter);
|
||||||
|
|
||||||
app.use(errorHandler)
|
app.use(errorHandler);
|
||||||
|
|
||||||
// Start server
|
// Start server
|
||||||
async function start() {
|
async function start() {
|
||||||
|
|
||||||
const port = process.env.PORT || 4400;
|
const port = process.env.PORT || 4400;
|
||||||
|
|
||||||
// Check DB connection
|
// Check DB connection
|
||||||
await db.connect()
|
await db.connect();
|
||||||
db.getConnection();
|
db.getConnection();
|
||||||
console.log(`Connexion MongoDB établie`);
|
console.log(`Connexion MongoDB établie`);
|
||||||
|
|
||||||
server.listen(port, () => {
|
server.listen(port, () => {
|
||||||
console.log(`Serveur écoutant sur le port ${port}`);
|
console.log(`Serveur écoutant sur le port ${port}`);
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
start();
|
start();
|
||||||
|
|
|
||||||
75
server/package-lock.json
generated
75
server/package-lock.json
generated
|
|
@ -21,6 +21,7 @@
|
||||||
"socket.io-client": "^4.7.2"
|
"socket.io-client": "^4.7.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"cross-env": "^7.0.3",
|
||||||
"jest": "^29.7.0",
|
"jest": "^29.7.0",
|
||||||
"jest-mock": "^29.7.0",
|
"jest-mock": "^29.7.0",
|
||||||
"nodemon": "^3.0.1",
|
"nodemon": "^3.0.1",
|
||||||
|
|
@ -1231,9 +1232,9 @@
|
||||||
"integrity": "sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q=="
|
"integrity": "sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q=="
|
||||||
},
|
},
|
||||||
"node_modules/@types/cors": {
|
"node_modules/@types/cors": {
|
||||||
"version": "2.8.15",
|
"version": "2.8.17",
|
||||||
"resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.15.tgz",
|
"resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.17.tgz",
|
||||||
"integrity": "sha512-n91JxbNLD8eQIuXDIChAN1tCKNWCEgpceU9b7ZMbFA+P+Q4yIeh80jizFLEvolRPc1ES0VdwFlGv+kJTSirogw==",
|
"integrity": "sha512-8CGDvrBj1zgo2qE+oS3pOCyYNqCPryMWY2bGfwA0dcfopWGgxs+78df0Rs3rc9THP4JkOhLsAa+15VdpAqkcUA==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/node": "*"
|
"@types/node": "*"
|
||||||
}
|
}
|
||||||
|
|
@ -2046,9 +2047,9 @@
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/cookie": {
|
"node_modules/cookie": {
|
||||||
"version": "0.6.0",
|
"version": "0.7.1",
|
||||||
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz",
|
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz",
|
||||||
"integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==",
|
"integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 0.6"
|
"node": ">= 0.6"
|
||||||
}
|
}
|
||||||
|
|
@ -2102,6 +2103,24 @@
|
||||||
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
|
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/cross-env": {
|
||||||
|
"version": "7.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz",
|
||||||
|
"integrity": "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"cross-spawn": "^7.0.1"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"cross-env": "src/bin/cross-env.js",
|
||||||
|
"cross-env-shell": "src/bin/cross-env-shell.js"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10.14",
|
||||||
|
"npm": ">=6",
|
||||||
|
"yarn": ">=1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/cross-spawn": {
|
"node_modules/cross-spawn": {
|
||||||
"version": "7.0.3",
|
"version": "7.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
|
||||||
|
|
@ -2286,16 +2305,16 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/engine.io": {
|
"node_modules/engine.io": {
|
||||||
"version": "6.5.5",
|
"version": "6.6.2",
|
||||||
"resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.5.5.tgz",
|
"resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.6.2.tgz",
|
||||||
"integrity": "sha512-C5Pn8Wk+1vKBoHghJODM63yk8MvrO9EWZUfkAt5HAqIgPE4/8FF0PEGHXtEd40l223+cE5ABWuPzm38PHFXfMA==",
|
"integrity": "sha512-gmNvsYi9C8iErnZdVcJnvCpSKbWTt1E8+JZo8b+daLninywUWi5NQ5STSHZ9rFjFO7imNcvb8Pc5pe/wMR5xEw==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/cookie": "^0.4.1",
|
"@types/cookie": "^0.4.1",
|
||||||
"@types/cors": "^2.8.12",
|
"@types/cors": "^2.8.12",
|
||||||
"@types/node": ">=10.0.0",
|
"@types/node": ">=10.0.0",
|
||||||
"accepts": "~1.3.4",
|
"accepts": "~1.3.4",
|
||||||
"base64id": "2.0.0",
|
"base64id": "2.0.0",
|
||||||
"cookie": "~0.4.1",
|
"cookie": "~0.7.2",
|
||||||
"cors": "~2.8.5",
|
"cors": "~2.8.5",
|
||||||
"debug": "~4.3.1",
|
"debug": "~4.3.1",
|
||||||
"engine.io-parser": "~5.2.1",
|
"engine.io-parser": "~5.2.1",
|
||||||
|
|
@ -2347,19 +2366,19 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/engine.io/node_modules/cookie": {
|
"node_modules/engine.io/node_modules/cookie": {
|
||||||
"version": "0.4.2",
|
"version": "0.7.2",
|
||||||
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz",
|
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz",
|
||||||
"integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==",
|
"integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 0.6"
|
"node": ">= 0.6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/engine.io/node_modules/debug": {
|
"node_modules/engine.io/node_modules/debug": {
|
||||||
"version": "4.3.4",
|
"version": "4.3.7",
|
||||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
|
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz",
|
||||||
"integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
|
"integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"ms": "2.1.2"
|
"ms": "^2.1.3"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6.0"
|
"node": ">=6.0"
|
||||||
|
|
@ -2371,9 +2390,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/engine.io/node_modules/ms": {
|
"node_modules/engine.io/node_modules/ms": {
|
||||||
"version": "2.1.2",
|
"version": "2.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
||||||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
|
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
|
||||||
},
|
},
|
||||||
"node_modules/error-ex": {
|
"node_modules/error-ex": {
|
||||||
"version": "1.3.2",
|
"version": "1.3.2",
|
||||||
|
|
@ -2496,16 +2515,16 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/express": {
|
"node_modules/express": {
|
||||||
"version": "4.21.0",
|
"version": "4.21.1",
|
||||||
"resolved": "https://registry.npmjs.org/express/-/express-4.21.0.tgz",
|
"resolved": "https://registry.npmjs.org/express/-/express-4.21.1.tgz",
|
||||||
"integrity": "sha512-VqcNGcj/Id5ZT1LZ/cfihi3ttTn+NJmkli2eZADigjq29qTlWi/hAQ43t/VLPq8+UX06FCEx3ByOYet6ZFblng==",
|
"integrity": "sha512-YSFlK1Ee0/GC8QaO91tHcDxJiE/X4FbpAyQWkxAvG6AXCuR65YzK8ua6D9hvi/TzUfZMpc+BwuM1IPw8fmQBiQ==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"accepts": "~1.3.8",
|
"accepts": "~1.3.8",
|
||||||
"array-flatten": "1.1.1",
|
"array-flatten": "1.1.1",
|
||||||
"body-parser": "1.20.3",
|
"body-parser": "1.20.3",
|
||||||
"content-disposition": "0.5.4",
|
"content-disposition": "0.5.4",
|
||||||
"content-type": "~1.0.4",
|
"content-type": "~1.0.4",
|
||||||
"cookie": "0.6.0",
|
"cookie": "0.7.1",
|
||||||
"cookie-signature": "1.0.6",
|
"cookie-signature": "1.0.6",
|
||||||
"debug": "2.6.9",
|
"debug": "2.6.9",
|
||||||
"depd": "2.0.0",
|
"depd": "2.0.0",
|
||||||
|
|
@ -5092,15 +5111,15 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/socket.io": {
|
"node_modules/socket.io": {
|
||||||
"version": "4.7.2",
|
"version": "4.8.1",
|
||||||
"resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.7.2.tgz",
|
"resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.8.1.tgz",
|
||||||
"integrity": "sha512-bvKVS29/I5fl2FGLNHuXlQaUH/BlzX1IN6S+NKLNZpBsPZIDH+90eQmCs2Railn4YUiww4SzUedJ6+uzwFnKLw==",
|
"integrity": "sha512-oZ7iUCxph8WYRHHcjBEc9unw3adt5CmSNlppj/5Q4k2RIrhl8Z5yY2Xr4j9zj0+wzVZ0bxmYoGSzKJnRl6A4yg==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"accepts": "~1.3.4",
|
"accepts": "~1.3.4",
|
||||||
"base64id": "~2.0.0",
|
"base64id": "~2.0.0",
|
||||||
"cors": "~2.8.5",
|
"cors": "~2.8.5",
|
||||||
"debug": "~4.3.2",
|
"debug": "~4.3.2",
|
||||||
"engine.io": "~6.5.2",
|
"engine.io": "~6.6.0",
|
||||||
"socket.io-adapter": "~2.5.2",
|
"socket.io-adapter": "~2.5.2",
|
||||||
"socket.io-parser": "~4.2.4"
|
"socket.io-parser": "~4.2.4"
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "webpack --config webpack.config.js",
|
"build": "webpack --config webpack.config.js",
|
||||||
"start": "node app.js",
|
"start": "node app.js",
|
||||||
"dev": "nodemon app.js",
|
"dev": "cross-env NODE_ENV=development nodemon app.js",
|
||||||
"test": "jest --colors"
|
"test": "jest --colors"
|
||||||
},
|
},
|
||||||
"keywords": [],
|
"keywords": [],
|
||||||
|
|
@ -25,6 +25,7 @@
|
||||||
"socket.io-client": "^4.7.2"
|
"socket.io-client": "^4.7.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"cross-env": "^7.0.3",
|
||||||
"jest": "^29.7.0",
|
"jest": "^29.7.0",
|
||||||
"jest-mock": "^29.7.0",
|
"jest-mock": "^29.7.0",
|
||||||
"nodemon": "^3.0.1",
|
"nodemon": "^3.0.1",
|
||||||
|
|
|
||||||
|
|
@ -68,7 +68,7 @@ const setupWebsocket = (io) => {
|
||||||
});
|
});
|
||||||
|
|
||||||
socket.on("next-question", ({ roomName, question }) => {
|
socket.on("next-question", ({ roomName, question }) => {
|
||||||
console.log("next-question", roomName, question);
|
// console.log("next-question", roomName, question);
|
||||||
socket.to(roomName).emit("next-question", question);
|
socket.to(roomName).emit("next-question", question);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue