Compare commits

...

11 commits

Author SHA1 Message Date
Eddi3_As
68f301b972 Merge remote-tracking branch 'test/main' into PFEH25-merge-it2main 2025-02-03 18:45:48 -05:00
Eddi3_As
3b6e009d73 FIX eslint et tests 2025-02-03 18:44:31 -05:00
Christopher (Cris) Fuhrman
cb069bebeb
Merge pull request #190 from ets-cfuhrman-pfe/gab9281-patch-1
Some checks failed
CI/CD Pipeline for Backend / build_and_push_backend (push) Has been cancelled
CI/CD Pipeline for Nginx Router / build_and_push_nginx (push) Has been cancelled
CI/CD Pipeline for Frontend / build_and_push_frontend (push) Has been cancelled
Tests / tests (client) (push) Has been cancelled
Tests / tests (server) (push) Has been cancelled
Update LICENSE
2025-02-01 11:08:31 -05:00
Christopher (Cris) Fuhrman
4b9ded9a26
Merge pull request #219 from ets-cfuhrman-pfe/JubaAzul/issue218
Some checks are pending
CI/CD Pipeline for Backend / build_and_push_backend (push) Waiting to run
CI/CD Pipeline for Nginx Router / build_and_push_nginx (push) Waiting to run
CI/CD Pipeline for Frontend / build_and_push_frontend (push) Waiting to run
Tests / tests (client) (push) Waiting to run
Tests / tests (server) (push) Waiting to run
L'affichage de la bonne réponse dans les rétroactions ne fonctionne plus
2025-01-31 22:58:29 -05:00
JubaAzul
e8b1163733 L'affichage de la bonne réponse dans les rétroactions ne fonctionne plus
Fixes #218
2025-01-31 15:55:37 -05:00
Christopher (Cris) Fuhrman
e9ae3237a0
Merge pull request #193 from ets-cfuhrman-pfe/JubaAzul/issue137
Some checks are pending
CI/CD Pipeline for Backend / build_and_push_backend (push) Waiting to run
CI/CD Pipeline for Nginx Router / build_and_push_nginx (push) Waiting to run
CI/CD Pipeline for Frontend / build_and_push_frontend (push) Waiting to run
Tests / tests (client) (push) Waiting to run
Tests / tests (server) (push) Waiting to run
Ce n'est pas évident que le format [markdown] doit être utilisé pour les images
2025-01-31 09:39:52 -05:00
JubaAzul
c65181f7bf L'affichage de la bonne réponse dans les rétroactions ne fonctionne plus
Fixes #218
2025-01-30 23:01:04 -05:00
JubaAzul
9323763046 Merge branch 'main' into JubaAzul/issue137 2025-01-17 12:13:45 -05:00
JubaAzul
69b5d3f2f9 Amélioration avec interaction 2025-01-14 16:21:32 -05:00
JubaAzul
ce6d9f9a2e Ce n'est pas évident que le format [markdown] doit être utilisé pour les images
Fixes #137
2025-01-14 15:06:41 -05:00
41c85b1144
Update LICENSE
Ajout de l'équipe automne 2024
2025-01-13 12:09:55 -05:00
20 changed files with 204 additions and 86 deletions

View file

@ -2,6 +2,7 @@ MIT License
Copyright (c) 2023 ETS-PFE004-Plateforme-sondage-minitest Copyright (c) 2023 ETS-PFE004-Plateforme-sondage-minitest
Copyright (c) 2024 Louis-Antoine Caron, Mathieu Roy, Mélanie St-Hilaire, Samy Waddah Copyright (c) 2024 Louis-Antoine Caron, Mathieu Roy, Mélanie St-Hilaire, Samy Waddah
Copyright (c) 2024 Gabriel Moisan-Matte, Mathieu Sévigny-Lavallée, Jerry Kwok Hiu Fung, Bruno Roesner, Florent Serres
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View file

@ -1,4 +1,4 @@
import React from 'react'; import React, { useState } from 'react';
import { render, screen, fireEvent } from '@testing-library/react'; import { render, screen, fireEvent } from '@testing-library/react';
import '@testing-library/jest-dom'; import '@testing-library/jest-dom';
import { act } from 'react'; import { act } from 'react';
@ -17,21 +17,30 @@ const question = questions[0];
describe('MultipleChoiceQuestionDisplay', () => { describe('MultipleChoiceQuestionDisplay', () => {
const mockHandleOnSubmitAnswer = jest.fn(); const mockHandleOnSubmitAnswer = jest.fn();
const sampleProps = {
question: question, const TestWrapper = ({ showAnswer }: { showAnswer: boolean }) => {
handleOnSubmitAnswer: mockHandleOnSubmitAnswer, const [showAnswerState, setShowAnswerState] = useState(showAnswer);
showAnswer: false
const handleOnSubmitAnswer = (answer: string) => {
mockHandleOnSubmitAnswer(answer);
setShowAnswerState(true);
};
return (
<MemoryRouter>
<MultipleChoiceQuestionDisplay
question={question}
handleOnSubmitAnswer={handleOnSubmitAnswer}
showAnswer={showAnswerState}
/>
</MemoryRouter>
);
}; };
const choices = question.choices; const choices = question.choices;
beforeEach(() => { beforeEach(() => {
render( render(<TestWrapper showAnswer={false} />);
<MemoryRouter>
<MultipleChoiceQuestionDisplay
{...sampleProps}
/>
</MemoryRouter>);
}); });
test('renders the question and choices', () => { test('renders the question and choices', () => {
@ -55,7 +64,6 @@ describe('MultipleChoiceQuestionDisplay', () => {
act(() => { act(() => {
fireEvent.click(choiceButton); fireEvent.click(choiceButton);
}); });
const submitButton = screen.getByText('Répondre'); const submitButton = screen.getByText('Répondre');
act(() => { act(() => {
fireEvent.click(submitButton); fireEvent.click(submitButton);
@ -63,4 +71,51 @@ describe('MultipleChoiceQuestionDisplay', () => {
expect(mockHandleOnSubmitAnswer).toHaveBeenCalledWith('Choice 1'); expect(mockHandleOnSubmitAnswer).toHaveBeenCalledWith('Choice 1');
}); });
});
it('should show ✅ next to the correct answer and ❌ next to the wrong answers when showAnswer is true', async () => {
const choiceButton = screen.getByText('Choice 1').closest('button');
if (!choiceButton) throw new Error('Choice button not found');
// Click on choiceButton
act(() => {
fireEvent.click(choiceButton);
});
const button = screen.getByText("Répondre");
act(() => {
fireEvent.click(button);
});
// Wait for the DOM to update
const correctAnswer = screen.getByText("Choice 1").closest('button');
expect(correctAnswer).toBeInTheDocument();
expect(correctAnswer?.textContent).toContain('✅');
const wrongAnswer1 = screen.getByText("Choice 2").closest('button');
expect(wrongAnswer1).toBeInTheDocument();
expect(wrongAnswer1?.textContent).toContain('❌');
});
it('should not show ✅ or ❌ when repondre button is not clicked', async () => {
const choiceButton = screen.getByText('Choice 1').closest('button');
if (!choiceButton) throw new Error('Choice button not found');
// Click on choiceButton
act(() => {
fireEvent.click(choiceButton);
});
// Check for correct answer
const correctAnswer = screen.getByText("Choice 1").closest('button');
expect(correctAnswer).toBeInTheDocument();
expect(correctAnswer?.textContent).not.toContain('✅');
// Check for wrong answers
const wrongAnswer1 = screen.getByText("Choice 2");
expect(wrongAnswer1).toBeInTheDocument();
expect(wrongAnswer1?.textContent).not.toContain('❌');
});
});

View file

@ -1,5 +1,5 @@
// TrueFalseQuestion.test.tsx // TrueFalseQuestion.test.tsx
import React from 'react'; import React, { useState } from 'react';
import { render, fireEvent, screen, act } from '@testing-library/react'; import { render, fireEvent, screen, act } from '@testing-library/react';
import '@testing-library/jest-dom'; import '@testing-library/jest-dom';
import { MemoryRouter } from 'react-router-dom'; import { MemoryRouter } from 'react-router-dom';
@ -12,17 +12,28 @@ describe('TrueFalseQuestion Component', () => {
const trueFalseQuestion = const trueFalseQuestion =
parse(`${sampleStem}{T}`)[0] as TrueFalseQuestion; parse(`${sampleStem}{T}`)[0] as TrueFalseQuestion;
const sampleProps = {
question: trueFalseQuestion, const TestWrapper = ({ showAnswer }: { showAnswer: boolean }) => {
handleOnSubmitAnswer: mockHandleSubmitAnswer, const [showAnswerState, setShowAnswerState] = useState(showAnswer);
showAnswer: false
const handleOnSubmitAnswer = (answer: boolean) => {
mockHandleSubmitAnswer(answer);
setShowAnswerState(true);
};
return (
<MemoryRouter>
<TrueFalseQuestionDisplay
question={trueFalseQuestion}
handleOnSubmitAnswer={handleOnSubmitAnswer}
showAnswer={showAnswerState}
/>
</MemoryRouter>
);
}; };
beforeEach(() => { beforeEach(() => {
render( render(<TestWrapper showAnswer={false} />);
<MemoryRouter>
<TrueFalseQuestionDisplay {...sampleProps} />
</MemoryRouter>);
}); });
it('renders correctly', () => { it('renders correctly', () => {
@ -73,4 +84,50 @@ describe('TrueFalseQuestion Component', () => {
expect(mockHandleSubmitAnswer).toHaveBeenCalledWith(false); expect(mockHandleSubmitAnswer).toHaveBeenCalledWith(false);
}); });
it('should show ✅ next to the correct answer and ❌ next to the wrong answers when showAnswer is true', async () => {
const choiceButton = screen.getByText('Vrai').closest('button');
if (!choiceButton) throw new Error('T button not found');
// Click on choiceButton
act(() => {
fireEvent.click(choiceButton);
});
const button = screen.getByText("Répondre");
act(() => {
fireEvent.click(button);
});
// Wait for the DOM to update
const correctAnswer = screen.getByText("Vrai").closest('button');
expect(correctAnswer).toBeInTheDocument();
expect(correctAnswer?.textContent).toContain('✅');
const wrongAnswer1 = screen.getByText("Faux").closest('button');
expect(wrongAnswer1).toBeInTheDocument();
expect(wrongAnswer1?.textContent).toContain('❌');
});
it('should not show ✅ or ❌ when repondre button is not clicked', async () => {
const choiceButton = screen.getByText('Vrai').closest('button');
if (!choiceButton) throw new Error('Choice button not found');
// Click on choiceButton
act(() => {
fireEvent.click(choiceButton);
});
// Check for correct answer
const correctAnswer = screen.getByText("Vrai").closest('button');
expect(correctAnswer).toBeInTheDocument();
expect(correctAnswer?.textContent).not.toContain('✅');
// Check for wrong answers
const wrongAnswer1 = screen.getByText("Faux");
expect(wrongAnswer1).toBeInTheDocument();
expect(wrongAnswer1?.textContent).not.toContain('❌');
});
}); });

View file

@ -153,7 +153,7 @@ const GiftCheatSheet: React.FC = () => {
</pre> </pre>
</div> </div>
<div className="question-type"> <div className="question-type" id="images-section">
<h4> 9. Images </h4> <h4> 9. Images </h4>
<p>Il est possible d&apos;insérer une image dans une question, une réponse (choix multiple) et dans une rétroaction. D&apos;abord, <strong>le format de l&apos;élément doit être [markdown]</strong>. Ensuite utilisez la syntaxe suivante&nbsp;:</p> <p>Il est possible d&apos;insérer une image dans une question, une réponse (choix multiple) et dans une rétroaction. D&apos;abord, <strong>le format de l&apos;élément doit être [markdown]</strong>. Ensuite utilisez la syntaxe suivante&nbsp;:</p>
<pre> <pre>
@ -185,8 +185,7 @@ const GiftCheatSheet: React.FC = () => {
Attention: l&apos;ancienne fonctionnalité avec les balises <code>{'<img>'}</code> n&apos;est plus Attention: l&apos;ancienne fonctionnalité avec les balises <code>{'<img>'}</code> n&apos;est plus
supportée. supportée.
</p> </p>
</div> </div>
<div className="question-type"> <div className="question-type">
<h4> 10. Informations supplémentaires </h4> <h4> 10. Informations supplémentaires </h4>
<p> <p>

View file

@ -12,7 +12,6 @@ interface Props {
} }
const MultipleChoiceQuestionDisplay: React.FC<Props> = (props) => { const MultipleChoiceQuestionDisplay: React.FC<Props> = (props) => {
const { question, showAnswer, handleOnSubmitAnswer } = props; const { question, showAnswer, handleOnSubmitAnswer } = props;
const [answer, setAnswer] = useState<string>(); const [answer, setAnswer] = useState<string>();
@ -24,7 +23,6 @@ const MultipleChoiceQuestionDisplay: React.FC<Props> = (props) => {
setAnswer(choice); setAnswer(choice);
}; };
const alpha = Array.from(Array(26)).map((_e, i) => i + 65); const alpha = Array.from(Array(26)).map((_e, i) => i + 65);
const alphabet = alpha.map((x) => String.fromCharCode(x)); const alphabet = alpha.map((x) => String.fromCharCode(x));
return ( return (
@ -37,25 +35,23 @@ const MultipleChoiceQuestionDisplay: React.FC<Props> = (props) => {
const selected = answer === choice.formattedText.text ? 'selected' : ''; const selected = answer === choice.formattedText.text ? 'selected' : '';
return ( return (
<div key={choice.formattedText.text + i} className="choice-container"> <div key={choice.formattedText.text + i} className="choice-container">
<Button <Button
variant="text" variant="text"
className="button-wrapper" className="button-wrapper"
onClick={() => !showAnswer && handleOnClickAnswer(choice.formattedText.text)} onClick={() => !showAnswer && handleOnClickAnswer(choice.formattedText.text)}>
> {showAnswer? (<div> {(choice.isCorrect ? '✅' : '❌')}</div>)
{choice.formattedFeedback === null && :``}
showAnswer &&
(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}`}>
<div dangerouslySetInnerHTML={{ __html: FormattedTextTemplate(choice.formattedText) }} /> <div dangerouslySetInnerHTML={{ __html: FormattedTextTemplate(choice.formattedText) }} />
</div> </div>
</Button> {choice.formattedFeedback && showAnswer && (
{choice.formattedFeedback && showAnswer && (
<div className="feedback-container mb-1 mt-1/2"> <div className="feedback-container mb-1 mt-1/2">
{choice.isCorrect ? '✅' : '❌'}
<div dangerouslySetInnerHTML={{ __html: FormattedTextTemplate(choice.formattedFeedback) }} /> <div dangerouslySetInnerHTML={{ __html: FormattedTextTemplate(choice.formattedFeedback) }} />
</div> </div>
)} )}
</Button>
</div> </div>
); );
})} })}

View file

@ -22,7 +22,6 @@ const TrueFalseQuestionDisplay: React.FC<Props> = (props) => {
const selectedTrue = answer ? 'selected' : ''; const selectedTrue = answer ? 'selected' : '';
const selectedFalse = answer !== undefined && !answer ? 'selected' : ''; const selectedFalse = answer !== undefined && !answer ? 'selected' : '';
const correctAnswer = question.isTrue === answer;
return ( return (
<div className="question-container"> <div className="question-container">
<div className="question content"> <div className="question content">
@ -34,7 +33,7 @@ const TrueFalseQuestionDisplay: React.FC<Props> = (props) => {
onClick={() => !showAnswer && setAnswer(true)} onClick={() => !showAnswer && setAnswer(true)}
fullWidth fullWidth
> >
{showAnswer && (correctAnswer ? '✅' : '❌')} {showAnswer? (<div> {(question.isTrue ? '✅' : '❌')}</div>):``}
<div className={`circle ${selectedTrue}`}>V</div> <div className={`circle ${selectedTrue}`}>V</div>
<div className={`answer-text ${selectedTrue}`}>Vrai</div> <div className={`answer-text ${selectedTrue}`}>Vrai</div>
</Button> </Button>
@ -43,7 +42,7 @@ const TrueFalseQuestionDisplay: React.FC<Props> = (props) => {
onClick={() => !showAnswer && setAnswer(false)} onClick={() => !showAnswer && setAnswer(false)}
fullWidth fullWidth
> >
{showAnswer && (!correctAnswer ? '✅' : '❌')} {showAnswer? (<div> {(!question.isTrue ? '✅' : '❌')}</div>):``}
<div className={`circle ${selectedFalse}`}>F</div> <div className={`circle ${selectedFalse}`}>F</div>
<div className={`answer-text ${selectedFalse}`}>Faux</div> <div className={`answer-text ${selectedFalse}`}>Faux</div>
</Button> </Button>

View file

@ -61,6 +61,14 @@ const QuizForm: React.FC = () => {
}; };
}, []); }, []);
const scrollToImagesSection = (event: { preventDefault: () => void; }) => {
event.preventDefault();
const section = document.getElementById('images-section');
if (section) {
section.scrollIntoView({ behavior: 'smooth' });
}
};
useEffect(() => { useEffect(() => {
const fetchData = async () => { const fetchData = async () => {
const userFolders = await ApiService.getUserFolders(); const userFolders = await ApiService.getUserFolders();
@ -277,10 +285,18 @@ const QuizForm: React.FC = () => {
</div> </div>
<h4>Mes images :</h4> <h4>Mes images :</h4>
<div> <div>
<div>(Cliquez sur un lien pour le copier)</div> <div>
<ul> <div style={{ display: "inline" }}>(Voir section </div>
<a href="#images-section"style={{ textDecoration: "none" }} onClick={scrollToImagesSection}>
<u><em><h4 style={{ display: "inline" }}> 9. Images </h4></em></u>
</a>
<div style={{ display: "inline" }}> ci-dessous</div>
<div style={{ display: "inline" }}>)</div>
<br />
<em> - Cliquez sur un lien pour le copier</em>
</div>
<ul>
{imageLinks.map((link, index) => { {imageLinks.map((link, index) => {
const imgTag = `![alt_text](${escapeForGIFT(link)} "texte de l'infobulle")`; const imgTag = `![alt_text](${escapeForGIFT(link)} "texte de l'infobulle")`;
return ( return (

View file

@ -1,4 +1,4 @@
const request = require("supertest");
const AuthConfig = require("../config/auth.js"); const AuthConfig = require("../config/auth.js");
const AuthManager = require("../auth/auth-manager.js"); const AuthManager = require("../auth/auth-manager.js");
@ -115,7 +115,7 @@ describe(
expressMock.get = () => {} expressMock.get = () => {}
let authConfigInstance; let authConfigInstance;
let logSpy; let authmanagerInstance;
// Initialisez l'instance avec la configuration mockée // Initialisez l'instance avec la configuration mockée
beforeAll(() => { beforeAll(() => {
@ -158,6 +158,7 @@ describe(
}; };
authConfigInstance.loadConfigTest(validModule); // On injecte la configuration mockée authConfigInstance.loadConfigTest(validModule); // On injecte la configuration mockée
authmanagerInstance = new AuthManager(expressMock,authConfigInstance.config); authmanagerInstance = new AuthManager(expressMock,authConfigInstance.config);
authmanagerInstance.getUserModel();
expect(logSpy).toHaveBeenCalledTimes(0); expect(logSpy).toHaveBeenCalledTimes(0);
logSpy.mockClear(); logSpy.mockClear();
}); });
@ -200,7 +201,7 @@ describe(
}; };
authConfigInstance.loadConfigTest(validModuleInvalidProvider); // On injecte la configuration mockée authConfigInstance.loadConfigTest(validModuleInvalidProvider); // On injecte la configuration mockée
authmanagerInstance = new AuthManager(expressMock,authConfigInstance.config); authmanagerInstance = new AuthManager(expressMock,authConfigInstance.config);
expect(logSpy).toHaveBeenCalledTimes(2); expect(logSpy).toHaveBeenCalledTimes(4);
logSpy.mockClear(); logSpy.mockClear();
}); });
}) })

View file

@ -103,8 +103,9 @@ app.use(session({
cookie: { secure: process.env.NODE_ENV === 'production' } cookie: { secure: process.env.NODE_ENV === 'production' }
})); }));
authManager = new AuthManager(app,null,userModel) let authManager = new AuthManager(app,null,userModel);
app.use(errorHandler) authManager.getUserModel();
app.use(errorHandler);
// Start server // Start server
async function start() { async function start() {

View file

@ -2,8 +2,10 @@ const fs = require('fs');
const AuthConfig = require('../config/auth.js'); const AuthConfig = require('../config/auth.js');
const jwt = require('../middleware/jwtToken.js'); const jwt = require('../middleware/jwtToken.js');
const emailer = require('../config/email.js'); const emailer = require('../config/email.js');
const model = require('../controllers/users.js'); const MISSING_REQUIRED_PARAMETER = {
message: 'Paramètre requis manquant.',
code: 400
};
class AuthManager{ class AuthManager{
constructor(expressapp,configs=null,userModel){ constructor(expressapp,configs=null,userModel){
this.modules = [] this.modules = []
@ -33,7 +35,7 @@ class AuthManager{
this.modules.push(new Module(this,this.configs.auth[name])); this.modules.push(new Module(this,this.configs.auth[name]));
console.info(`Module d'authentification '${name}' ajouté`) console.info(`Module d'authentification '${name}' ajouté`)
} else{ } else{
console.error(`Le module d'authentification ${name} n'as pas été chargé car il est introuvable`) console.error(`Le module d'authentification ${name} n'as pas été chargé car il est introuvable`);
} }
} }
@ -42,12 +44,14 @@ class AuthManager{
try{ try{
module.registerAuth(this.app) module.registerAuth(this.app)
} catch(error){ } catch(error){
console.error(`L'enregistrement du module ${module} a échoué.`) console.error(`L'enregistrement du module ${module} a échoué.`);
console.error(`Error: ${error} `);
} }
} }
} }
async login(userInfo,req,res,next){ // eslint-disable-next-line no-unused-vars
async login(userInfo,req,res,next){ //passport and simpleauth use next
const tokenToSave = jwt.create(userInfo.email, userInfo._id,userInfo.roles); const tokenToSave = jwt.create(userInfo.email, userInfo._id,userInfo.roles);
res.redirect(`/auth/callback?user=${tokenToSave}&username=${userInfo.name}`); res.redirect(`/auth/callback?user=${tokenToSave}&username=${userInfo.name}`);
console.info(`L'utilisateur '${userInfo.name}' vient de se connecter`) console.info(`L'utilisateur '${userInfo.name}' vient de se connecter`)
@ -55,7 +59,7 @@ class AuthManager{
async register(userInfos){ async register(userInfos){
if (!userInfos.email || !userInfos.password) { if (!userInfos.email || !userInfos.password) {
throw new AppError(MISSING_REQUIRED_PARAMETER); throw MISSING_REQUIRED_PARAMETER;
} }
const user = await this.simpleregister.register(userInfos); const user = await this.simpleregister.register(userInfos);
emailer.registerConfirmation(user.email) emailer.registerConfirmation(user.email)

View file

@ -2,7 +2,6 @@ var OAuth2Strategy = require('passport-oauth2')
var authUserAssoc = require('../../../models/authUserAssociation') var authUserAssoc = require('../../../models/authUserAssociation')
var users = require('../../../models/users') var users = require('../../../models/users')
var { hasNestedValue } = require('../../../utils') var { hasNestedValue } = require('../../../utils')
var jwt = require('../../../middleware/jwtToken')
class PassportOAuth { class PassportOAuth {
constructor(passportjs, auth_name) { constructor(passportjs, auth_name) {

View file

@ -2,7 +2,6 @@ var OpenIDConnectStrategy = require('passport-openidconnect')
var authUserAssoc = require('../../../models/authUserAssociation') var authUserAssoc = require('../../../models/authUserAssociation')
var users = require('../../../models/users') var users = require('../../../models/users')
var { hasNestedValue } = require('../../../utils') var { hasNestedValue } = require('../../../utils')
var jwt = require('../../../middleware/jwtToken')
class PassportOpenIDConnect { class PassportOpenIDConnect {
constructor(passportjs, auth_name) { constructor(passportjs, auth_name) {
@ -15,7 +14,8 @@ class PassportOpenIDConnect {
const config = await fetch(provider.OIDC_CONFIG_URL) const config = await fetch(provider.OIDC_CONFIG_URL)
return await config.json() return await config.json()
} catch (error) { } catch (error) {
console.error(`Les informations de connexions de la connexion OIDC ${name} n'ont pu être chargées.`) console.error(`Les informations de connexions de la connexion OIDC ${name} n'ont pu être chargées.`);
console.error(`Error: ${error} `);
} }
} }
@ -70,10 +70,11 @@ class PassportOpenIDConnect {
user_account.name = received_user.name user_account.name = received_user.name
user_account.roles = received_user.roles user_account.roles = received_user.roles
await users.editUser(user_account) await users.editUser(user_account);
return done(null, user_account); return done(null, user_account);
} catch (error) { } catch (error) {
console.error(`Error: ${error} `);
} }
})); }));

View file

@ -24,7 +24,8 @@ class PassportJs{
this.registeredProviders[provider.type].register(expressapp,passport,this.endpoint,name,provider) this.registeredProviders[provider.type].register(expressapp,passport,this.endpoint,name,provider)
authprovider.create(auth_id) authprovider.create(auth_id)
} catch(error){ } catch(error){
console.error(`La connexion ${name} de type ${provider.type} n'as pu être chargé.`) console.error(`La connexion ${name} de type ${provider.type} n'as pu être chargé.`);
console.error(`Error: ${error} `);
} }
} }
} }
@ -45,7 +46,8 @@ class PassportJs{
this.registeredProviders[providerType]= new Provider(this,auth_id) this.registeredProviders[providerType]= new Provider(this,auth_id)
console.info(`Le type de connexion '${providerType}' a été ajouté dans passportjs.`) console.info(`Le type de connexion '${providerType}' a été ajouté dans passportjs.`)
} catch(error){ } catch(error){
console.error(`Le type de connexion '${providerType}' n'as pas pu être chargé dans passportjs.`) console.error(`Le type de connexion '${providerType}' n'as pas pu être chargé dans passportjs.`);
console.error(`Error: ${error} `);
} }
} }

View file

@ -15,12 +15,13 @@ class SimpleAuth {
async registerAuth(expressapp) { async registerAuth(expressapp) {
try { try {
expressapp.post(`${this.endpoint}/register`, (req, res, next) => this.register(this, req, res)); expressapp.post(`${this.endpoint}/register`, (req, res) => this.register(this, req, res));
expressapp.post(`${this.endpoint}/login`, (req, res, next) => this.authenticate(this, req, res)); expressapp.post(`${this.endpoint}/login`, (req, res, next) => this.authenticate(this, req, res, next));
expressapp.post(`${this.endpoint}/reset-password`, (req, res, next) => this.resetPassword(this, req, res)); expressapp.post(`${this.endpoint}/reset-password`, (req, res, next) => this.resetPassword(this, req, res, next));
expressapp.post(`${this.endpoint}/change-password`, jwt.authenticate, (req, res, next) => this.changePassword(this, req, res)); expressapp.post(`${this.endpoint}/change-password`, jwt.authenticate, (req, res, next) => this.changePassword(this, req, res, next));
} catch (error) { } catch (error) {
console.error(`La connexion ${name} de type ${provider.type} n'as pu être chargé.`) console.error(`La connexion ${name} de type ${this.providers.type} n'as pu être chargé.`);
console.error(`Error: ${error} `);
} }
} }

View file

@ -16,7 +16,8 @@ class AuthConfig {
this.config = JSON.parse(configData); this.config = JSON.parse(configData);
} catch (error) { } catch (error) {
console.error("Erreur lors de la lecture du fichier de configuration. Ne pas se fier si vous n'avez pas mit de fichier de configuration."); console.error("Erreur lors de la lecture du fichier de configuration. Ne pas se fier si vous n'avez pas mit de fichier de configuration.");
this.config = {} this.config = {};
throw error;
} }
return this.config return this.config
} }

View file

@ -20,7 +20,7 @@ class authController {
} }
} }
async getRoomsRequireAuth(req, res, next) { async getRoomsRequireAuth(req, res) {
const authC = new AuthConfig(); const authC = new AuthConfig();
const roomsRequireAuth = authC.getRoomsRequireAuth(); const roomsRequireAuth = authC.getRoomsRequireAuth();

View file

@ -19,7 +19,7 @@ class AuthUserAssociation {
const collection = conn.collection('authUserAssociation'); const collection = conn.collection('authUserAssociation');
const provider_id = await authProvider.getId(provider_name) const provider_id = await authProvider.getId(provider_name)
const userAssociation = await collection.findOne({ authProvider_id: provider_id,auth_id,auth_id }); const userAssociation = await collection.findOne({ authProvider_id: provider_id, auth_id: auth_id });
return userAssociation return userAssociation
} }

View file

@ -1,13 +0,0 @@
const db = require('../config/db.js')
const { ObjectId } = require('mongodb');
class AuthUserAssoc {
constructor(authProviderId, authId, userId) {
this._id = new ObjectId();
this.authProvider_id = authProviderId;
this.auth_id = authId;
this.user_id = userId;
}
}

View file

@ -1,7 +1,6 @@
const bcrypt = require("bcrypt"); const bcrypt = require("bcrypt");
const AppError = require("../middleware/AppError.js"); const AppError = require("../middleware/AppError.js");
const { USER_ALREADY_EXISTS } = require("../constants/errorCodes"); const { USER_ALREADY_EXISTS } = require("../constants/errorCodes");
const Folders = require("../models/folders.js");
class Users { class Users {
@ -67,7 +66,7 @@ class Users {
return user; return user;
} }
/*
async login(email, password) { async login(email, password) {
try { try {
await this.db.connect(); await this.db.connect();
@ -96,7 +95,7 @@ class Users {
throw error; throw error;
} }
} }
*/
async resetPassword(email) { async resetPassword(email) {
const newPassword = this.generatePassword(); const newPassword = this.generatePassword();

View file

@ -1,6 +1,5 @@
const express = require('express'); const express = require('express');
const router = express.Router(); const router = express.Router();
const jwt = require('../middleware/jwtToken.js');
const authController = require('../controllers/auth.js') const authController = require('../controllers/auth.js')