diff --git a/backend/apis/nodejs/src/app.js b/backend/apis/nodejs/src/app.js index 1c376ba..31d5bc3 100644 --- a/backend/apis/nodejs/src/app.js +++ b/backend/apis/nodejs/src/app.js @@ -38,7 +38,9 @@ app.use(cors()); // Enable CORS for all routes app.use(rateLimit({ windowMs: process.env.LIMITER_WINDOW, max: process.env.LIMITER_MAXIMUM_PER_WINDOW, - message: { error: 'Too many requests from this IP, please try again later' } + message: { + error: 'Too many requests from this IP, please try again later' + } })); // Apply the rate limiter middleware to all routes /* @@ -72,4 +74,4 @@ if (process.argv[2] != 'testing') { } // Export the app for testing purposes -module.exports = app; +module.exports = app; \ No newline at end of file diff --git a/backend/apis/nodejs/src/models/activation_model.js b/backend/apis/nodejs/src/models/activation_model.js index d6ac8ba..2625d47 100644 --- a/backend/apis/nodejs/src/models/activation_model.js +++ b/backend/apis/nodejs/src/models/activation_model.js @@ -19,11 +19,11 @@ const knex = require('../utils/knex_config'); * @returns The Person's ID associated with the identifier if present, * null otherwise */ -async function getPersonIdByIdentifier (identifier){ +async function getPersonIdByIdentifier(identifier) { const tuple = await knex('ActivationLink') .where('identifier', identifier) .first(); - if(tuple){ + if (tuple) { return tuple.person_id; } return null; diff --git a/backend/apis/nodejs/src/models/organization_admin_model.js b/backend/apis/nodejs/src/models/organization_admin_model.js index 9cd8e79..d9575a4 100644 --- a/backend/apis/nodejs/src/models/organization_admin_model.js +++ b/backend/apis/nodejs/src/models/organization_admin_model.js @@ -20,7 +20,7 @@ const knex = require('../utils/knex_config'); * @param {*} organizationId * @returns true if administrator, false otherwise */ -async function isPersonOrganizationAdministrator (personId, organizationId) { +async function isPersonOrganizationAdministrator(personId, organizationId) { const isPersonAdmin = await knex('OrganizationAdministrator') .where('id_person', personId) .where('id_organization', organizationId) @@ -36,15 +36,15 @@ async function isPersonOrganizationAdministrator (personId, organizationId) { * @param {*} organizationId * @param {*} requester Id of the person requesting the addition */ -async function addOrganizationAdministrator (personId, organizationId, requester) { +async function addOrganizationAdministrator(personId, organizationId, requester) { const isPersonAdmin = await organization_admin_model.isPersonAdmin(requester, organizationId); - if(isPersonAdmin){ + if (isPersonAdmin) { await knex('OrganizationAdministrator') - .insert({ - id_person: personId, - id_organization: organizationId - }); + .insert({ + id_person: personId, + id_organization: organizationId + }); return true; } return false; @@ -56,7 +56,7 @@ async function addOrganizationAdministrator (personId, organizationId, requester * @param {*} personId * @param {*} organizationId */ -async function removeOrganizationAdmin (personId, organizationId) { +async function removeOrganizationAdmin(personId, organizationId) { const transaction = await knex.transaction(); // We lock the table to ensure that we won't have concurrency issues @@ -71,7 +71,9 @@ async function removeOrganizationAdmin (personId, organizationId) { // TODO: If the user instead deletes their entire profile, the organization will not be deleted. Fix. (database schema) const remainingAdministrators = await transaction('OrganizationAdministrator') - .where({ id_organization: organizationId }); + .where({ + id_organization: organizationId + }); if (remainingAdministrators.length === 0) { // If no more users, delete the organization @@ -87,4 +89,4 @@ module.exports = { isPersonOrganizationAdministrator, addOrganizationAdministrator, removeOrganizationAdmin -}; +}; \ No newline at end of file diff --git a/backend/apis/nodejs/src/models/organization_model.js b/backend/apis/nodejs/src/models/organization_model.js index 92912e4..f0f0e07 100644 --- a/backend/apis/nodejs/src/models/organization_model.js +++ b/backend/apis/nodejs/src/models/organization_model.js @@ -21,7 +21,7 @@ const knex = require('../utils/knex_config'); * @param {*} isHiring * @returns */ -function createOrganization (name, location, description, isHiring) { +function createOrganization(name, location, description, isHiring) { const organization = { name: name, location: location, @@ -36,7 +36,7 @@ function createOrganization (name, location, description, isHiring) { * @param {*} id * @returns the Organization */ -async function getOrganizationById (id) { +async function getOrganizationById(id) { const organization = await knex('Organization') .where('id', id) .select('*') @@ -50,7 +50,7 @@ async function getOrganizationById (id) { * * @returns The inserted Organization */ -async function insertOrganization (organization, organizationAdministratorId) { +async function insertOrganization(organization, organizationAdministratorId) { return await knex.transaction(async (trx) => { // We have to insert either both in Organization and in OrganizationAdministrator // or in neither @@ -76,7 +76,7 @@ async function insertOrganization (organization, organizationAdministratorId) { * @param {*} requester * @returns true if the row was updated, false otherwise */ -async function updateOrganization (organization, organizationId, requester) { +async function updateOrganization(organization, organizationId, requester) { const numberOfUpdatedRows = await knex('Organization') .where('id', organizationId) .whereExists(function () { @@ -96,9 +96,11 @@ async function updateOrganization (organization, organizationId, requester) { * @param {*} requester PersonId of the supposedly administrator * @returns true if the Organization was successfully deleted, false otherwise */ -async function deleteOrganization (organizationId, requester) { +async function deleteOrganization(organizationId, requester) { const numberOfDeletedRows = await knex('Organization') - .where({ id: organizationId }) + .where({ + id: organizationId + }) .whereExists(function () { this.select('*') .from('OrganizationAdministrator') @@ -118,4 +120,4 @@ module.exports = { insertOrganization, updateOrganization, deleteOrganization -}; +}; \ No newline at end of file diff --git a/backend/apis/nodejs/src/models/organization_post_model.js b/backend/apis/nodejs/src/models/organization_post_model.js index 42a9789..e501c4a 100644 --- a/backend/apis/nodejs/src/models/organization_post_model.js +++ b/backend/apis/nodejs/src/models/organization_post_model.js @@ -19,7 +19,7 @@ const knex = require('../utils/knex_config'); * @param {*} content * @param {*} originalAuthor */ -function createOrganizationPost (organizationId, content, originalAuthor) { +function createOrganizationPost(organizationId, content, originalAuthor) { const organizationPost = { organization_id: organizationId, content, @@ -34,7 +34,7 @@ function createOrganizationPost (organizationId, content, originalAuthor) { * @param {*} organization * @returns the inserted OrganizationPost */ -async function insertOrganizationPost (organization) { +async function insertOrganizationPost(organization) { const isOrganizationAdmin = await knex('OrganizationAdministrator') .where('id_person', organization.original_author) .where('id_organization', organization.organization_id) @@ -65,7 +65,7 @@ async function insertOrganizationPost (organization) { * @param {*} personId * @returns true or false */ -async function isPersonPostAdministrator (postId, personId) { +async function isPersonPostAdministrator(postId, personId) { return await knex('OrganizationPost') .join('OrganizationAdministrator', 'OrganizationPost.organization_id', 'OrganizationAdministrator.id_organization') .where('OrganizationPost.id', postId) @@ -80,11 +80,11 @@ async function isPersonPostAdministrator (postId, personId) { * @param {*} postId Id of the Post to delete * @param {*} requester Id of the Person requesting the deletion */ -async function deleteOrganizationPost (postId, requester) { - if(await isPersonPostAdministrator(postId, requester)){ +async function deleteOrganizationPost(postId, requester) { + if (await isPersonPostAdministrator(postId, requester)) { return await knex('OrganizationPost') - .where('id', postId) - .del() == 1; + .where('id', postId) + .del() == 1; } return false; } @@ -94,4 +94,4 @@ module.exports = { insertOrganizationPost, isPersonPostAdministrator, deleteOrganizationPost -}; +}; \ No newline at end of file diff --git a/backend/apis/nodejs/src/models/person_model.js b/backend/apis/nodejs/src/models/person_model.js index c7b04cb..3eb05ff 100644 --- a/backend/apis/nodejs/src/models/person_model.js +++ b/backend/apis/nodejs/src/models/person_model.js @@ -25,7 +25,7 @@ const bcrypt = require('bcrypt'); * @param {*} placeOfLiving * @returns */ -function createPerson (email, password, displayName, dateOfBirth, available, enabled, placeOfLiving, aboutMe, qualification) { +function createPerson(email, password, displayName, dateOfBirth, available, enabled, placeOfLiving, aboutMe, qualification) { const person = { email: email.toLowerCase(), password, @@ -45,7 +45,7 @@ function createPerson (email, password, displayName, dateOfBirth, available, ena * @param {*} email email to look the Person for * @returns the Person object */ -async function getPersonByEmail (email) { +async function getPersonByEmail(email) { return await knex('Person') .where('email', email.toLowerCase()) .first(); @@ -56,10 +56,12 @@ async function getPersonByEmail (email) { * @param {*} id - The id to look the person for * @returns */ -async function getPersonById (id) { +async function getPersonById(id) { return await knex('Person') .select('*') - .where({ id }) + .where({ + id + }) .first(); } @@ -69,7 +71,7 @@ async function getPersonById (id) { * @param {*} person A Person object * @param {*} activationLink the activationLink identifier */ -async function registerPerson (person, activationLink) { +async function registerPerson(person, activationLink) { // We need to insert either both in the "Person" table // and in the "ActivationLink" one, or in neither await knex.transaction(async (tr) => { @@ -91,7 +93,7 @@ async function registerPerson (person, activationLink) { * @param {*} password * @returns */ -async function getPersonByEmailAndPassword (email, password) { +async function getPersonByEmailAndPassword(email, password) { const person = await knex('Person') .where('email', email.toLowerCase()) .where('enabled', true) @@ -112,7 +114,7 @@ async function getPersonByEmailAndPassword (email, password) { * @param {*} person The Person to update * @param {*} person_id The database id of the Person to update */ -async function updatePerson (person, person_id) { +async function updatePerson(person, person_id) { await knex('Person') .where('id', person_id) .update(person); @@ -122,21 +124,25 @@ async function updatePerson (person, person_id) { * Deletes a Person specified by its database id. * @param {*} person_id */ -async function deletePerson (personId) { +async function deletePerson(personId) { await knex('Person') - .where({ id: personId }) + .where({ + id: personId + }) .del(); } -async function confirmActivation (personId) { +async function confirmActivation(personId) { await knex.transaction(async (tr) => { await knex('Person') - .where('id', personId) - .update({enabled: true}); + .where('id', personId) + .update({ + enabled: true + }); - await tr('ActivationLink') - .where('person_id', personId) - .del(); + await tr('ActivationLink') + .where('person_id', personId) + .del(); }); } @@ -153,4 +159,4 @@ module.exports = { updatePerson, deletePerson, confirmActivation -}; +}; \ No newline at end of file diff --git a/backend/apis/nodejs/src/routes/organization_admin_routes.js b/backend/apis/nodejs/src/routes/organization_admin_routes.js index 2c4d1c0..039c4b2 100644 --- a/backend/apis/nodejs/src/routes/organization_admin_routes.js +++ b/backend/apis/nodejs/src/routes/organization_admin_routes.js @@ -23,45 +23,59 @@ const jwtUtils = require('../utils/middleware_utils'); * * Required field(s): organization_id, person_id */ -async function addOrganizationAdmin (req, res) { +async function addOrganizationAdmin(req, res) { // Ensure that the required fields are present before proceeding if (!req.body.organization_id || !req.body.person_id) { - return res.status(400).json({ error: 'Invalid request' }); + return res.status(400).json({ + error: 'Invalid request' + }); } try { const success = await organizationAdminModel.addOrganizationAdministrator(req.body.person_id, req.body.organization_id, req.jwt.person_id); - if(success){ - return res.status(200).json({ success: true }); + if (success) { + return res.status(200).json({ + success: true + }); } - return res.status(403).json({ error: 'Forbidden' }); + return res.status(403).json({ + error: 'Forbidden' + }); } catch (error) { console.error(`Error in function ${addOrganizationAdmin.name}: ${error}`); - res.status(500).json({ error: 'Internal server error' }); + res.status(500).json({ + error: 'Internal server error' + }); } } /** - * DELETE Request - * - * Deletes a Person from the list of Administrators of an Organization. - * The logged user can only remove themselves. If no more Administrators - * are left, the Organization is removed. - * - * Required field(s): organization_id - */ -async function removeOrganizationAdmin (req, res) { + * DELETE Request + * + * Deletes a Person from the list of Administrators of an Organization. + * The logged user can only remove themselves. If no more Administrators + * are left, the Organization is removed. + * + * Required field(s): organization_id + */ +async function removeOrganizationAdmin(req, res) { // Ensure that the required fields are present before proceeding if (!req.body.organization_id) { - return res.status(400).json({ error: 'Invalid request' }); + return res.status(400).json({ + error: 'Invalid request' + }); } try { await organizationAdminModel.removeOrganizationAdmin(req.jwt.person_id, req.body.organization_id); - return res.status(200).json({ success: true }); + return res.status(200).json({ + success: true + }); } catch (error) { console.error(`Error in function ${removeOrganizationAdmin.name}: ${error}`); - return res.status(500).json({ error: 'Internal server error' }); + return res.status(500).json({ + error: 'Internal server error' + }); } } @@ -72,4 +86,4 @@ protectedRoutes.delete('/organization/admin', removeOrganizationAdmin); module.exports = { protectedRoutes -}; +}; \ No newline at end of file diff --git a/backend/apis/nodejs/src/routes/organization_post_routes.js b/backend/apis/nodejs/src/routes/organization_post_routes.js index 465e5c7..cf68ada 100644 --- a/backend/apis/nodejs/src/routes/organization_post_routes.js +++ b/backend/apis/nodejs/src/routes/organization_post_routes.js @@ -16,17 +16,19 @@ const express = require('express'); const jwtUtils = require('../utils/middleware_utils'); /** - * POST Request - * - * Creates a Post belonging to an organization - * - * Required field(s): organization_id, content - * @returns the inserted Post - */ -async function createOrganizationPost (req, res) { + * POST Request + * + * Creates a Post belonging to an organization + * + * Required field(s): organization_id, content + * @returns the inserted Post + */ +async function createOrganizationPost(req, res) { // Ensure that the required fields are present before proceeding if (!req.body.organization_id || !req.body.content) { - return res.status(400).json({ error: 'Invalid request' }); + return res.status(400).json({ + error: 'Invalid request' + }); } const organization = organizationPostModel.createOrganizationPost( @@ -39,7 +41,9 @@ async function createOrganizationPost (req, res) { return res.status(200).json(insertedOrganization); } catch (error) { console.error(`Error in function ${createOrganizationPost.name}: ${error}`); - return res.status(500).json({ error: 'Internal server error' }); + return res.status(500).json({ + error: 'Internal server error' + }); } } @@ -51,18 +55,24 @@ async function createOrganizationPost (req, res) { * * Required field(s): none. */ -async function deleteOrganizationPost (req, res) { +async function deleteOrganizationPost(req, res) { try { - const success = await organizationPostModel.deleteOrganizationPost(req.params.id, req.jwt.person_id); + const success = await organizationPostModel.deleteOrganizationPost(req.params.id, req.jwt.person_id); + + if (success) { + return res.status(200).json({ + success: true + }); + } + return res.status(401).json({ + error: 'Forbidden' + }); - if(success){ - return res.status(200).json({ success: true }); - } - return res.status(401).json({ error: 'Forbidden' }); - } catch (error) { console.error(`Error in function ${deleteOrganizationPost.name}: ${error}`); - res.status(500).json({ error: 'Internal server error' }); + res.status(500).json({ + error: 'Internal server error' + }); } } @@ -76,4 +86,4 @@ protectedRoutes.delete('/organization/post/:id', deleteOrganizationPost); // module available for use in another module. module.exports = { protectedRoutes -}; +}; \ No newline at end of file diff --git a/backend/apis/nodejs/src/routes/organization_routes.js b/backend/apis/nodejs/src/routes/organization_routes.js index 29f35cb..7c08356 100644 --- a/backend/apis/nodejs/src/routes/organization_routes.js +++ b/backend/apis/nodejs/src/routes/organization_routes.js @@ -24,10 +24,12 @@ const jwtUtils = require('../utils/middleware_utils'); * * @returns the inserted organization */ -async function createOrganization (req, res) { +async function createOrganization(req, res) { // Ensure that the required fields are present before proceeding if (!req.body.name) { - return res.status(400).json({ error: 'Invalid request' }); + return res.status(400).json({ + error: 'Invalid request' + }); } try { @@ -36,7 +38,9 @@ async function createOrganization (req, res) { return res.status(200).json(insertedOrganization); } catch (error) { console.error(`Error in function ${createOrganization.name}: ${error}`); - res.status(500).json({ error: 'Internal server error' }); + res.status(500).json({ + error: 'Internal server error' + }); } } @@ -46,7 +50,7 @@ async function createOrganization (req, res) { * * Required field(s): none. */ -async function updateOrganization (req, res) { +async function updateOrganization(req, res) { const updateOrganization = {}; if (req.body.name) { @@ -66,19 +70,27 @@ async function updateOrganization (req, res) { } if (Object.keys(updateOrganization).length === 0) { - return res.status(400).json({ error: 'Bad request. No data to update' }); + return res.status(400).json({ + error: 'Bad request. No data to update' + }); } try { const isUpdateSuccessful = organizationModel.updateOrganization(updateOrganization, req.params.id, req.jwt.person_id); if (isUpdateSuccessful) { - return res.status(200).json({ success: 'true' }); + return res.status(200).json({ + success: 'true' + }); } else { - return res.status(404).json({ error: 'Organization either not found or insufficient permissions' }); + return res.status(404).json({ + error: 'Organization either not found or insufficient permissions' + }); } } catch (error) { console.error(`Error in function ${updateOrganization.name}: ${error}`); - return res.status(500).json({ error: 'Internal server error' }); + return res.status(500).json({ + error: 'Internal server error' + }); } } @@ -88,16 +100,22 @@ async function updateOrganization (req, res) { * Deletes the specified organization if the logged user is * one of its administrator */ -async function deleteOrganization (req, res) { +async function deleteOrganization(req, res) { try { const isDeleteSuccessful = await organizationModel.deleteOrganization(req.params.id, req.jwt.person_id); if (isDeleteSuccessful) { - return res.status(200).json({ success: true }); + return res.status(200).json({ + success: true + }); } - return res.status(403).json({ error: 'Forbidden' }); + return res.status(403).json({ + error: 'Forbidden' + }); } catch (error) { console.error(`Error in function ${deleteOrganization.name}: ${error}`); - return res.status(500).json({ error: 'Internal server error' }); + return res.status(500).json({ + error: 'Internal server error' + }); } } @@ -110,17 +128,21 @@ async function deleteOrganization (req, res) { * * @returns the organization. */ -async function getOrganization (req, res) { +async function getOrganization(req, res) { try { const organization = await organizationModel.getOrganizationById(req.params.id); if (organization) { return res.status(200).json(organization); } else { - return res.status(404).json({ error: 'Not found' }); + return res.status(404).json({ + error: 'Not found' + }); } } catch (error) { console.error(`Error in function ${getOrganization.name}: ${error}`); - return res.status(500).json({ error: 'Internal server error' }); + return res.status(500).json({ + error: 'Internal server error' + }); } } @@ -136,4 +158,4 @@ protectedRoutes.delete('/organization/:id', deleteOrganization); module.exports = { publicRoutes, protectedRoutes -}; +}; \ No newline at end of file diff --git a/backend/apis/nodejs/src/routes/person_routes.js b/backend/apis/nodejs/src/routes/person_routes.js index 2416035..6cdc321 100644 --- a/backend/apis/nodejs/src/routes/person_routes.js +++ b/backend/apis/nodejs/src/routes/person_routes.js @@ -28,17 +28,23 @@ const express = require('express'); * * @returns The activationlink identifier */ -async function registerPerson (req, res) { +async function registerPerson(req, res) { // Does this server allow users to register? if (process.env.ALLOW_USER_REGISTRATION === 'false') { - return res.status(403).json({ error: 'Users cannot register on this server' }); + return res.status(403).json({ + error: 'Users cannot register on this server' + }); } // Ensure that the required fields are present before proceeding if (!req.body.display_name || !req.body.email || !req.body.password) { - return res.status(400).json({ error: 'Some or all required fields are missing' }); + return res.status(400).json({ + error: 'Some or all required fields are missing' + }); } if (!validator.validateEmail(req.body.email)) { - return res.status(400).json({ error: 'The email is not in a valid format' }); + return res.status(400).json({ + error: 'The email is not in a valid format' + }); } // Generate activation link token @@ -50,7 +56,9 @@ async function registerPerson (req, res) { // Check whether e-mail exists already (enforced by database constraints) const existingUser = await personModel.getPersonByEmail(req.body.email); if (existingUser) { - return res.status(409).json({ error: 'E-mail already in use' }); + return res.status(409).json({ + error: 'E-mail already in use' + }); } const personToInsert = personModel.createPerson( req.body.email, @@ -63,10 +71,14 @@ async function registerPerson (req, res) { req.body.about_me, req.body.qualification); await personModel.registerPerson(personToInsert, activationLink); - return res.status(200).json({ activationLink }); + return res.status(200).json({ + activationLink + }); } catch (error) { console.error(`Error in function ${registerPerson.name}: ${error}`); - res.status(500).json({ error: 'Internal server error' }); + res.status(500).json({ + error: 'Internal server error' + }); } } @@ -80,23 +92,31 @@ async function registerPerson (req, res) { * * @returns The token */ -async function login (req, res) { +async function login(req, res) { // Ensure that the required fields are present before proceeding if (!req.body.email || !req.body.password) { - return res.status(400).json({ error: 'Invalid request' }); + return res.status(400).json({ + error: 'Invalid request' + }); } try { const person = await personModel.getPersonByEmailAndPassword(req.body.email, req.body.password); if (person) { const token = jwtUtils.generateToken(person.id); - return res.status(200).json({ token }); + return res.status(200).json({ + token + }); } else { - return res.status(401).json({ error: 'Invalid credentials' }); + return res.status(401).json({ + error: 'Invalid credentials' + }); } } catch (error) { console.error(`Error in function ${login.name}: ${error}`); - return res.status(500).json({ error: 'Internal server error' }); + return res.status(500).json({ + error: 'Internal server error' + }); } } @@ -109,17 +129,21 @@ async function login (req, res) { * * @returns The Person */ -async function getPerson (req, res) { +async function getPerson(req, res) { try { const person = await personModel.getPersonById(req.params.id); if (person && person.enabled) { delete person.password; // remove password field for security reasons return res.status(200).send(person); } - return res.status(404).json({ error: 'Not found' }); + return res.status(404).json({ + error: 'Not found' + }); } catch (error) { console.error(`Error in function ${getPerson.name}: ${error}`); - return res.status(500).json({ error: 'Internal server error' }); + return res.status(500).json({ + error: 'Internal server error' + }); } } @@ -131,17 +155,21 @@ async function getPerson (req, res) { * * @returns Person's details */ -async function getMyself (req, res) { +async function getMyself(req, res) { try { const person = await personModel.getPersonById(req.jwt.person_id); if (person) { delete person.password; return res.status(200).send(person); } - return res.status(404).json({ error: 'Not found' }); + return res.status(404).json({ + error: 'Not found' + }); } catch (error) { console.error(`Error in function ${getMyself.name}: ${error}`); - return res.status(500).json({ error: 'Internal server error' }); + return res.status(500).json({ + error: 'Internal server error' + }); } } @@ -156,7 +184,7 @@ async function getMyself (req, res) { * new_password if updating the password. * */ -async function updatePerson (req, res) { +async function updatePerson(req, res) { const updatePerson = {}; if (req.body.display_name) { @@ -167,7 +195,9 @@ async function updatePerson (req, res) { if (validator.isPostgresDateFormatValid(req.body.date_of_birth)) { updatePerson.date_of_birth = req.body.date_of_birth; } else { - return res.status(400).json({ error: 'Date of birth format not valid. Please specify a YYYY-MM-DD date' }); + return res.status(400).json({ + error: 'Date of birth format not valid. Please specify a YYYY-MM-DD date' + }); } } @@ -179,41 +209,53 @@ async function updatePerson (req, res) { updatePerson.place_of_living = req.body.place_of_living; } - if(req.body.about_me) { + if (req.body.about_me) { updatePerson.about_me = req.body.about_me; } - if(req.body.qualification) { + if (req.body.qualification) { updatePerson.qualification = req.body.qualification; } // If we are tying to change password, the old password must be provided if (req.body.old_password || req.body.new_password) { - if(!req.body.old_password){ - return res.status(401).json({ error: 'The old password must be specified' }); + if (!req.body.old_password) { + return res.status(401).json({ + error: 'The old password must be specified' + }); } - if(!req.body.new_password){ - return res.status(401).json({ error: 'The new password must be specified' }); + if (!req.body.new_password) { + return res.status(401).json({ + error: 'The new password must be specified' + }); } const user = await personModel.getPersonById(req.jwt.person_id); const passwordMatches = await bcrypt.compare(req.body.old_password, user.password); if (passwordMatches) { updatePerson.password = await bcrypt.hash(req.body.new_password, 10); } else { - return res.status(401).json({ error: 'Password verification failed' }); + return res.status(401).json({ + error: 'Password verification failed' + }); } } if (Object.keys(updatePerson).length === 0) { - return res.status(400).json({ error: 'Bad request. No data to update' }); + return res.status(400).json({ + error: 'Bad request. No data to update' + }); } try { await personModel.updatePerson(updatePerson, req.jwt.person_id); - return res.status(200).json({ success: 'true' }); + return res.status(200).json({ + success: 'true' + }); } catch (error) { console.error(`Error in function ${updatePerson.name}: ${error}`); - return res.status(500).json({ error: 'Internal server error' }); + return res.status(500).json({ + error: 'Internal server error' + }); } } @@ -226,14 +268,18 @@ async function updatePerson (req, res) { * Required field(s): none * */ -async function deletePerson (req, res) { +async function deletePerson(req, res) { // TODO: Delete Organization if this user was its only administrator try { await personModel.deletePerson(req.jwt.person_id); - return res.status(200).json({ success: true }); + return res.status(200).json({ + success: true + }); } catch (error) { console.error(`Error in function ${deletePerson.name}: ${error}`); - return res.status(500).json({ error: 'Internal server error' }); + return res.status(500).json({ + error: 'Internal server error' + }); } } @@ -245,17 +291,23 @@ async function deletePerson (req, res) { * * Required field(s): identifier */ -async function confirmActivation(req, res){ +async function confirmActivation(req, res) { try { const personId = await activationModel.getPersonIdByIdentifier(req.query.q); - if(!personId){ - return res.status(401).json({error: 'Activation Link either not valid or expired'}); + if (!personId) { + return res.status(401).json({ + error: 'Activation Link either not valid or expired' + }); } await personModel.confirmActivation(personId); - return res.status(200).json({ success: true }); + return res.status(200).json({ + success: true + }); } catch (error) { console.error(`Error in function ${confirmActivation.name}: ${error}`); - return res.status(500).json({ error: 'Internal server error' }); + return res.status(500).json({ + error: 'Internal server error' + }); } } @@ -277,4 +329,4 @@ protectedRoutes.delete('/person/delete', deletePerson); module.exports = { publicRoutes, protectedRoutes -}; +}; \ No newline at end of file diff --git a/backend/apis/nodejs/src/utils/knex_config.js b/backend/apis/nodejs/src/utils/knex_config.js index b851d90..13b7a2b 100644 --- a/backend/apis/nodejs/src/utils/knex_config.js +++ b/backend/apis/nodejs/src/utils/knex_config.js @@ -22,4 +22,4 @@ const knexInstance = require('knex')({ } }); -module.exports = knexInstance; +module.exports = knexInstance; \ No newline at end of file diff --git a/backend/apis/nodejs/src/utils/middleware_utils.js b/backend/apis/nodejs/src/utils/middleware_utils.js index 8c685b8..071905d 100644 --- a/backend/apis/nodejs/src/utils/middleware_utils.js +++ b/backend/apis/nodejs/src/utils/middleware_utils.js @@ -13,7 +13,7 @@ const jwt = require('jsonwebtoken'); -function generateToken (person_id) { +function generateToken(person_id) { // The payload the JWT will carry within itself const payload = { person_id @@ -26,16 +26,20 @@ function generateToken (person_id) { } // Middlware -function verifyToken (req, res, next) { +function verifyToken(req, res, next) { const token = req.headers.authorization; if (!token) { - return res.status(401).send({ error: 'No token provided' }); + return res.status(401).send({ + error: 'No token provided' + }); } jwt.verify(token, process.env.JWT_SECRET_KEY, (err, decoded) => { if (err) { - return res.status(401).send({ error: 'Failed to authenticate token' }); + return res.status(401).send({ + error: 'Failed to authenticate token' + }); } // If the token is valid, store the decoded data in the request object @@ -48,4 +52,4 @@ function verifyToken (req, res, next) { module.exports = { generateToken, verifyToken -}; +}; \ No newline at end of file diff --git a/backend/apis/nodejs/src/utils/validation.js b/backend/apis/nodejs/src/utils/validation.js index 355ca1e..2468387 100644 --- a/backend/apis/nodejs/src/utils/validation.js +++ b/backend/apis/nodejs/src/utils/validation.js @@ -16,7 +16,7 @@ * @param {*} email email to validate * @returns true or false */ -function validateEmail (email) { +function validateEmail(email) { const regex = /^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$/; return regex.test(email); } @@ -27,7 +27,7 @@ function validateEmail (email) { * @param {*} dateString the date to validate * @returns true or false */ -function isPostgresDateFormatValid (dateString) { +function isPostgresDateFormatValid(dateString) { const regex = /^\d{4}-\d{2}-\d{2}$/; return regex.test(dateString); } @@ -35,4 +35,4 @@ function isPostgresDateFormatValid (dateString) { module.exports = { validateEmail, isPostgresDateFormatValid -}; +}; \ No newline at end of file diff --git a/frontend/vanilla/html/login.html b/frontend/vanilla/html/login.html index d1c8311..6e4cf17 100644 --- a/frontend/vanilla/html/login.html +++ b/frontend/vanilla/html/login.html @@ -1,65 +1,71 @@ - -
- -