From 4ffbdf76d644341b1cf084bb93e774efa35cea25 Mon Sep 17 00:00:00 2001 From: Alix Jaugey Date: Thu, 21 Mar 2024 12:02:15 +0100 Subject: [PATCH 1/9] Fix logout functionality in HeaderManager.js --- FRONT/js/view/HeaderManager.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/FRONT/js/view/HeaderManager.js b/FRONT/js/view/HeaderManager.js index b6aeff6..6959462 100644 --- a/FRONT/js/view/HeaderManager.js +++ b/FRONT/js/view/HeaderManager.js @@ -33,10 +33,12 @@ class HeaderManager { // add the event listener to log out accountButton.addEventListener('click', (e) => { e.preventDefault(); - document.dispatchEvent(new CustomEvent('USER_NOT_LOGGED_IN', { detail: { userExist: true } })); - + // remove the user from the local storage window.localStorage.removeItem('userToken'); + + document.dispatchEvent(new CustomEvent('USER_LOGGED_OUT', { detail: { userExist: true } })); + }); }); From c590d716cd2e96ab5a025b6492bb8ef743c954a6 Mon Sep 17 00:00:00 2001 From: Alix Jaugey Date: Thu, 21 Mar 2024 15:28:45 +0100 Subject: [PATCH 2/9] Remove unused import statement in AuthController.js --- API/controllers/AuthController.js | 1 - 1 file changed, 1 deletion(-) diff --git a/API/controllers/AuthController.js b/API/controllers/AuthController.js index 05785f2..30cc2d6 100644 --- a/API/controllers/AuthController.js +++ b/API/controllers/AuthController.js @@ -4,7 +4,6 @@ */ const express = require('express'); -const { login } = require('../data/queries/AuthorizedUserQueries'); const { handle } = require('./functionHandler'); const AuthManager = require('../model/Managers/AuthManager'); const router = express.Router(); From 39cbb3347ae7d11faea847e777a5147bfc4eff58 Mon Sep 17 00:00:00 2001 From: Alix Jaugey Date: Thu, 21 Mar 2024 15:29:21 +0100 Subject: [PATCH 3/9] Fix document reload issue and improve error handling --- FRONT/js/model/data/DocumentManager.js | 14 ++++++++++---- FRONT/js/model/popups/DocumentClickedPopup.js | 19 ++++++------------- 2 files changed, 16 insertions(+), 17 deletions(-) diff --git a/FRONT/js/model/data/DocumentManager.js b/FRONT/js/model/data/DocumentManager.js index e2bf884..97c6625 100644 --- a/FRONT/js/model/data/DocumentManager.js +++ b/FRONT/js/model/data/DocumentManager.js @@ -78,7 +78,7 @@ class DocumentManager extends DataManager { } } - + let toReturn = []; let data; @@ -146,8 +146,10 @@ class DocumentManager extends DataManager { console.log(e); } - // depending on what appened we either reload the page or return a message - if (data) { } // TODO: message popup that reload the view + if (data) { + window.location.reload(); + } + } /** @@ -166,7 +168,9 @@ class DocumentManager extends DataManager { } // depending on the api call, either tell the element was added, or return an error message - if (data) { } // TODO: message popup that reload the view / error message + if (data) { + window.location.reload(); + } } @@ -178,6 +182,8 @@ class DocumentManager extends DataManager { let data; try { data = await super.update(object); + alert('Document renommé avec succès !'); + window.location.reload(); } catch (e) { console.log(e); } diff --git a/FRONT/js/model/popups/DocumentClickedPopup.js b/FRONT/js/model/popups/DocumentClickedPopup.js index f518abc..6f557a5 100644 --- a/FRONT/js/model/popups/DocumentClickedPopup.js +++ b/FRONT/js/model/popups/DocumentClickedPopup.js @@ -102,7 +102,6 @@ class DocumentClickedPopup extends Popup { admin_only: true, action: async (dataMap, docId) => { const documentManager = dataMap['manager']; - const popupManager = dataMap['popupManager']; super.close(); @@ -110,16 +109,13 @@ class DocumentClickedPopup extends Popup { try { // archive the document await documentManager.archive(docId); - messageContent = `Le document ${this.document.getFileName()} a été archivé avec succès. - Vous pouvez le retrouver dans la liste des documents archivés. (connexion requise)`; + messageContent = `Le document ${this.document.getFileName()} a été archivé avec succès.\nsVous pouvez le retrouver dans la liste des documents archivés. (connexion requise)`; } catch (e) { console.log(e); messageContent = `Une erreur est survenue lors de l'archivage du document ${this.document.getFileName()}. Veuillez réessayer.`; } finally { - popupManager.open('message-popup', { - title: 'Archivage du document', - message: messageContent - }); + alert(messageContent); + window.location.reload(); } }, archive_button: false @@ -138,16 +134,13 @@ class DocumentClickedPopup extends Popup { try { // archive the document await documentManager.unarchive(docId); - messageContent = `Le document ${this.document.getFileName()} a été désarchivé avec succès. - Vous pouvez le retrouver dans la liste des documents non archivés.`; + messageContent = `Le document ${this.document.getFileName()} a été désarchivé avec succès.\nVous pouvez le retrouver dans la liste des documents non archivés.`; } catch (e) { console.log(e); messageContent = `Une erreur est survenue lors du désarchivage du document ${this.document.getFileName()}. Veuillez réessayer.`; } finally { - popupManager.open('message-popup', { - title: 'Désarchivage du document', - message: messageContent - }); + alert(messageContent); + window.location.reload(); } }, archive_button: true From 051dc103f2dec6e3bbef2d6c7618432f1d323a6b Mon Sep 17 00:00:00 2001 From: Alix Jaugey Date: Thu, 21 Mar 2024 15:29:30 +0100 Subject: [PATCH 4/9] Update login.html with new placeholder for identifier field --- FRONT/visual/pages/login.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FRONT/visual/pages/login.html b/FRONT/visual/pages/login.html index 819274e..677312b 100644 --- a/FRONT/visual/pages/login.html +++ b/FRONT/visual/pages/login.html @@ -29,7 +29,7 @@

Connexion

- +
From cbf2f5e85e533fc4072ac472675b09f03d3d4a4f Mon Sep 17 00:00:00 2001 From: Alix Jaugey Date: Thu, 21 Mar 2024 15:30:54 +0100 Subject: [PATCH 5/9] Fix user registration and error handling --- API/model/Managers/AuthManager.js | 15 ++++++++++----- FRONT/js/data/dao/AuthDao.js | 2 +- FRONT/js/model/auth/AuthManager.js | 2 +- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/API/model/Managers/AuthManager.js b/API/model/Managers/AuthManager.js index 788b5e9..6b84d49 100644 --- a/API/model/Managers/AuthManager.js +++ b/API/model/Managers/AuthManager.js @@ -87,14 +87,19 @@ async function register(data) { data.username = data.username.trim(); data.password = data.password.trim(); - await queries.createUser(data); - - // Check if the user exists, if not throw an error with 'Bad credentials' so that no information is leaked - assert(await userExist(), 'Bad credentials'); + try { + await userExist(); + } catch (e) { + if (e.message.includes('not found')) { + await queries.createUser(data); + } + } - return await login(data); + // Check if the user exists, if not throw an error + assert(await userExist(), 'Oops, something went wrong. Please try again.'); + return login(data); } diff --git a/FRONT/js/data/dao/AuthDao.js b/FRONT/js/data/dao/AuthDao.js index b92b387..14139cd 100644 --- a/FRONT/js/data/dao/AuthDao.js +++ b/FRONT/js/data/dao/AuthDao.js @@ -44,7 +44,7 @@ class AuthDao extends Dao { */ async register(user) { let resp = await this.post('/register', user); - return await resp.json(); + return await resp.text(); } /** diff --git a/FRONT/js/model/auth/AuthManager.js b/FRONT/js/model/auth/AuthManager.js index d1abd58..9de38cd 100644 --- a/FRONT/js/model/auth/AuthManager.js +++ b/FRONT/js/model/auth/AuthManager.js @@ -39,7 +39,7 @@ class AuthManager { response = await this.dao.checkForExistingUser(); toReturn.userExists = response.status === 200; - if (toReturn) { + if (toReturn.userExists) { let responseBody = await response.json(); if (responseBody.logged) { document.dispatchEvent(new Event('USER_LOGGED_IN')); From 4774601972beb9db7a05cbb4eb486f995e2d7e3b Mon Sep 17 00:00:00 2001 From: Alix Jaugey Date: Thu, 21 Mar 2024 15:31:13 +0100 Subject: [PATCH 6/9] Fix document renaming and update file paths --- API/data/queries/DocumentsQueries.js | 6 +++++- API/data/queries/VersionQueries.js | 9 ++++++--- API/model/Managers/DocumentManager.js | 2 +- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/API/data/queries/DocumentsQueries.js b/API/data/queries/DocumentsQueries.js index 960c360..aeb7441 100644 --- a/API/data/queries/DocumentsQueries.js +++ b/API/data/queries/DocumentsQueries.js @@ -181,12 +181,16 @@ async function rename(id, title) { assert(id, '[DocumentsQueries.rename] The document ID is required'); assert(title, '[DocumentsQueries.rename] The file name is required'); + // get the old name for to change the folder and files names + const old = await getById(id); + const oldTitle = old.name; + // Update the document name const documentQuery = 'UPDATE document SET file_name = ? WHERE id = ?'; await query(documentQuery, [title, id]); // Update the version file paths - await versionQueries.updatePathes(id, title); + await versionQueries.updatePathes(id, oldTitle, title); }); } diff --git a/API/data/queries/VersionQueries.js b/API/data/queries/VersionQueries.js index be6fb10..2533d87 100644 --- a/API/data/queries/VersionQueries.js +++ b/API/data/queries/VersionQueries.js @@ -121,16 +121,19 @@ async function getPdfPath(id, date) { * @param {string} newName - The new name to replace in the file paths. * @returns {Promise} A promise that resolves with the result of the update operation. */ -async function updatePathes(docId, newName) { +async function updatePathes(docId, oldTitle, newName) { // Check if the required fields are present assert(docId, '[VersionQueries.updatePathes] The document ID is required'); assert(newName, '[VersionQueries.updatePathes] The new name is required'); - + return await executeWithCleanup(async (query) => { + console.log('oldTitle: ', oldTitle); + console.log('newName: ', newName); + let queryStr = 'UPDATE version SET file_path = REPLACE(file_path, ?, ?) WHERE doc_id = ?'; - return await query(queryStr, [newName, docId, newName]); + return await query(queryStr, [oldTitle, newName, docId]); }); diff --git a/API/model/Managers/DocumentManager.js b/API/model/Managers/DocumentManager.js index 5997af6..2875ab9 100644 --- a/API/model/Managers/DocumentManager.js +++ b/API/model/Managers/DocumentManager.js @@ -132,7 +132,7 @@ async function updateTitle(id, title) { id = parseInt(id); assert(Number(id), '[DocumentManager.updateTitle] Document ID must be a number'); - changeFolderAndFilesNames(path.join(__dirname, '../Docs', oldName), title); + changeFolderAndFilesNames(path.join(__dirname, '../../Docs', oldName), title); await queries.rename(id, title); } From 41494c3a82a826abdf9e024b2735ab70a9b051d9 Mon Sep 17 00:00:00 2001 From: Alix Jaugey Date: Thu, 21 Mar 2024 15:32:46 +0100 Subject: [PATCH 7/9] Add documentation & some bug correction (button showing when not wanted in signedList page) --- FRONT/js/model/Canvas.js | 4 ++++ FRONT/js/model/Instantiator.js | 14 ++++++++++++++ FRONT/js/model/template/MainUserTemplateManager.js | 4 ++-- FRONT/js/view/signedList.js | 7 +++++++ 4 files changed, 27 insertions(+), 2 deletions(-) diff --git a/FRONT/js/model/Canvas.js b/FRONT/js/model/Canvas.js index a731ad4..866082a 100644 --- a/FRONT/js/model/Canvas.js +++ b/FRONT/js/model/Canvas.js @@ -138,6 +138,10 @@ class Canvas { return this.#canvas.toDataURL("image/png"); } + /** + * Exports the canvas as a Blob object. + * @returns {Promise} A promise that resolves with the Blob object representing the canvas. + */ exportToBlob() { return new Promise((resolve) => { this.#canvas.toBlob((blob) => { diff --git a/FRONT/js/model/Instantiator.js b/FRONT/js/model/Instantiator.js index c74fc9b..d67292f 100644 --- a/FRONT/js/model/Instantiator.js +++ b/FRONT/js/model/Instantiator.js @@ -144,6 +144,10 @@ class Instantiator { return new DocumentManager(); } + /** + * Retrieves the user manager instance. + * @returns {UserManager} The user manager instance. + */ static async getUserManager() { await Promise.all([ this.#loadSequentially([this.#pathes.data.access.Dao, this.#pathes.data.access.UserDao]), @@ -220,6 +224,11 @@ class Instantiator { } + /** + * Creates an instance of the MainUserDocSignedTemplateManager class. + * @param {Container} container - The container object. + * @returns {MainUserDocSignedTemplateManager} The MainUserDocSignedTemplateManager instance. + */ static async mainUserDocSignedTemplateManager(container) { await this.#loadSequentially([ this.#pathes.template.manager, @@ -229,6 +238,11 @@ class Instantiator { return new MainUserDocSignedTemplateManager(container); } + /** + * Creates a new instance of the MainUserDocWaitingTemplateManager class. + * @param {Container} container - The container object. + * @returns {MainUserDocWaitingTemplateManager} The new instance of MainUserDocWaitingTemplateManager. + */ static async mainUserDocWaitingTemplateManager(container) { await this.#loadSequentially([ this.#pathes.template.manager, diff --git a/FRONT/js/model/template/MainUserTemplateManager.js b/FRONT/js/model/template/MainUserTemplateManager.js index 48d4512..7fa363e 100644 --- a/FRONT/js/model/template/MainUserTemplateManager.js +++ b/FRONT/js/model/template/MainUserTemplateManager.js @@ -40,7 +40,7 @@ class MainUserTemplateManager extends TemplateManager { // values is a map that contains the values to be replaced in the template, // the key is the name of the variable in the template and the value is the value to replace let values = []; - + values['id'] = user.id; if (!user.archived_date) { @@ -48,7 +48,7 @@ class MainUserTemplateManager extends TemplateManager { const outdatedCount = user.docs_signatures.filter(doc => doc.toUpdate === true).length; const waitingCount = user.docs_waiting.length; - values['DisplayName'] = user.display_name; + values['DisplayName'] = user.display_name; values['Signed'] = signedCount < 10 ? '0' + signedCount : signedCount; values['Outdated'] = outdatedCount < 10 ? '0' + outdatedCount : outdatedCount; values['Waiting'] = waitingCount < 10 ? '0' + waitingCount : waitingCount; diff --git a/FRONT/js/view/signedList.js b/FRONT/js/view/signedList.js index fe7058c..f530cab 100644 --- a/FRONT/js/view/signedList.js +++ b/FRONT/js/view/signedList.js @@ -36,10 +36,12 @@ class SignedListView extends View { async #init(authManager) { this.#setPageTitle(); await this.initTemplateManager(); + this.isLogged = false; // Wait for auth Check document.addEventListener('USER_LOGGED_IN', () => { this.#displayUsers().then(() => { + this.isLogged = true; this.addButtons(); this.#manageSearch(); }); @@ -47,6 +49,7 @@ class SignedListView extends View { // if the user is not logged in, we redirect to the index page document.addEventListener('USER_NOT_LOGGED_IN', () => { + this.isLogged = false; this.#displayUsers().then(() => { this.removeButtons(); this.#manageSearch(); @@ -172,5 +175,9 @@ class SignedListView extends View { let userList = users.filter(user => user.getDisplayName().toLowerCase().includes(searchValue.toLowerCase())); await this.templateManager.addSignedUsers(userList); + if (!this.isLogged) { + this.removeButtons(); + } + } } \ No newline at end of file From 6ebab7642dbd9c3db984c1f9a204539111ca0abf Mon Sep 17 00:00:00 2001 From: Alix Jaugey Date: Thu, 21 Mar 2024 15:40:20 +0100 Subject: [PATCH 8/9] Fix login error handling in AuthManager --- FRONT/js/data/dao/AuthDao.js | 8 ++++++-- FRONT/js/model/auth/AuthManager.js | 2 ++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/FRONT/js/data/dao/AuthDao.js b/FRONT/js/data/dao/AuthDao.js index 14139cd..a598b22 100644 --- a/FRONT/js/data/dao/AuthDao.js +++ b/FRONT/js/data/dao/AuthDao.js @@ -26,7 +26,9 @@ class AuthDao extends Dao { */ async login(user) { let resp = await this.post('/login', user); - return await resp.text(); + if (resp.status === 200) { + return await resp.text(); + } } /** @@ -44,7 +46,9 @@ class AuthDao extends Dao { */ async register(user) { let resp = await this.post('/register', user); - return await resp.text(); + if (resp.status === 200) { + return await resp.text(); + } } /** diff --git a/FRONT/js/model/auth/AuthManager.js b/FRONT/js/model/auth/AuthManager.js index 9de38cd..a6e5978 100644 --- a/FRONT/js/model/auth/AuthManager.js +++ b/FRONT/js/model/auth/AuthManager.js @@ -68,6 +68,7 @@ class AuthManager { */ async login(user) { let response = await this.dao.login(user); + if (!response) throw new Error('Login failed'); this.#setToken(response); } @@ -78,6 +79,7 @@ class AuthManager { */ async register(user) { let response = await this.dao.register(user); + if (!response) throw new Error('Login failed'); this.#setToken(response); } From a3eaab9a4ab179fedc0f14b82fbe19654a5107c9 Mon Sep 17 00:00:00 2001 From: Alix Jaugey Date: Thu, 21 Mar 2024 15:41:37 +0100 Subject: [PATCH 9/9] Update status check in register method --- FRONT/js/data/dao/AuthDao.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FRONT/js/data/dao/AuthDao.js b/FRONT/js/data/dao/AuthDao.js index a598b22..c3e42a7 100644 --- a/FRONT/js/data/dao/AuthDao.js +++ b/FRONT/js/data/dao/AuthDao.js @@ -46,7 +46,7 @@ class AuthDao extends Dao { */ async register(user) { let resp = await this.post('/register', user); - if (resp.status === 200) { + if (resp.status === 201) { return await resp.text(); } }