mirror of
https://github.com/xfarrow/blink
synced 2025-02-16 08:00:35 +01:00
beautified
This commit is contained in:
parent
3ea41c82d4
commit
d9c3f6f55a
@ -38,7 +38,9 @@ app.use(cors()); // Enable CORS for all routes
|
|||||||
app.use(rateLimit({
|
app.use(rateLimit({
|
||||||
windowMs: process.env.LIMITER_WINDOW,
|
windowMs: process.env.LIMITER_WINDOW,
|
||||||
max: process.env.LIMITER_MAXIMUM_PER_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
|
})); // Apply the rate limiter middleware to all routes
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -72,4 +74,4 @@ if (process.argv[2] != 'testing') {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Export the app for testing purposes
|
// Export the app for testing purposes
|
||||||
module.exports = app;
|
module.exports = app;
|
@ -19,11 +19,11 @@ const knex = require('../utils/knex_config');
|
|||||||
* @returns The Person's ID associated with the identifier if present,
|
* @returns The Person's ID associated with the identifier if present,
|
||||||
* null otherwise
|
* null otherwise
|
||||||
*/
|
*/
|
||||||
async function getPersonIdByIdentifier (identifier){
|
async function getPersonIdByIdentifier(identifier) {
|
||||||
const tuple = await knex('ActivationLink')
|
const tuple = await knex('ActivationLink')
|
||||||
.where('identifier', identifier)
|
.where('identifier', identifier)
|
||||||
.first();
|
.first();
|
||||||
if(tuple){
|
if (tuple) {
|
||||||
return tuple.person_id;
|
return tuple.person_id;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
@ -20,7 +20,7 @@ const knex = require('../utils/knex_config');
|
|||||||
* @param {*} organizationId
|
* @param {*} organizationId
|
||||||
* @returns true if administrator, false otherwise
|
* @returns true if administrator, false otherwise
|
||||||
*/
|
*/
|
||||||
async function isPersonOrganizationAdministrator (personId, organizationId) {
|
async function isPersonOrganizationAdministrator(personId, organizationId) {
|
||||||
const isPersonAdmin = await knex('OrganizationAdministrator')
|
const isPersonAdmin = await knex('OrganizationAdministrator')
|
||||||
.where('id_person', personId)
|
.where('id_person', personId)
|
||||||
.where('id_organization', organizationId)
|
.where('id_organization', organizationId)
|
||||||
@ -36,15 +36,15 @@ async function isPersonOrganizationAdministrator (personId, organizationId) {
|
|||||||
* @param {*} organizationId
|
* @param {*} organizationId
|
||||||
* @param {*} requester Id of the person requesting the addition
|
* @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);
|
const isPersonAdmin = await organization_admin_model.isPersonAdmin(requester, organizationId);
|
||||||
if(isPersonAdmin){
|
if (isPersonAdmin) {
|
||||||
await knex('OrganizationAdministrator')
|
await knex('OrganizationAdministrator')
|
||||||
.insert({
|
.insert({
|
||||||
id_person: personId,
|
id_person: personId,
|
||||||
id_organization: organizationId
|
id_organization: organizationId
|
||||||
});
|
});
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@ -56,7 +56,7 @@ async function addOrganizationAdministrator (personId, organizationId, requester
|
|||||||
* @param {*} personId
|
* @param {*} personId
|
||||||
* @param {*} organizationId
|
* @param {*} organizationId
|
||||||
*/
|
*/
|
||||||
async function removeOrganizationAdmin (personId, organizationId) {
|
async function removeOrganizationAdmin(personId, organizationId) {
|
||||||
const transaction = await knex.transaction();
|
const transaction = await knex.transaction();
|
||||||
|
|
||||||
// We lock the table to ensure that we won't have concurrency issues
|
// 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)
|
// TODO: If the user instead deletes their entire profile, the organization will not be deleted. Fix. (database schema)
|
||||||
const remainingAdministrators = await transaction('OrganizationAdministrator')
|
const remainingAdministrators = await transaction('OrganizationAdministrator')
|
||||||
.where({ id_organization: organizationId });
|
.where({
|
||||||
|
id_organization: organizationId
|
||||||
|
});
|
||||||
|
|
||||||
if (remainingAdministrators.length === 0) {
|
if (remainingAdministrators.length === 0) {
|
||||||
// If no more users, delete the organization
|
// If no more users, delete the organization
|
||||||
@ -87,4 +89,4 @@ module.exports = {
|
|||||||
isPersonOrganizationAdministrator,
|
isPersonOrganizationAdministrator,
|
||||||
addOrganizationAdministrator,
|
addOrganizationAdministrator,
|
||||||
removeOrganizationAdmin
|
removeOrganizationAdmin
|
||||||
};
|
};
|
@ -21,7 +21,7 @@ const knex = require('../utils/knex_config');
|
|||||||
* @param {*} isHiring
|
* @param {*} isHiring
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
function createOrganization (name, location, description, isHiring) {
|
function createOrganization(name, location, description, isHiring) {
|
||||||
const organization = {
|
const organization = {
|
||||||
name: name,
|
name: name,
|
||||||
location: location,
|
location: location,
|
||||||
@ -36,7 +36,7 @@ function createOrganization (name, location, description, isHiring) {
|
|||||||
* @param {*} id
|
* @param {*} id
|
||||||
* @returns the Organization
|
* @returns the Organization
|
||||||
*/
|
*/
|
||||||
async function getOrganizationById (id) {
|
async function getOrganizationById(id) {
|
||||||
const organization = await knex('Organization')
|
const organization = await knex('Organization')
|
||||||
.where('id', id)
|
.where('id', id)
|
||||||
.select('*')
|
.select('*')
|
||||||
@ -50,7 +50,7 @@ async function getOrganizationById (id) {
|
|||||||
*
|
*
|
||||||
* @returns The inserted Organization
|
* @returns The inserted Organization
|
||||||
*/
|
*/
|
||||||
async function insertOrganization (organization, organizationAdministratorId) {
|
async function insertOrganization(organization, organizationAdministratorId) {
|
||||||
return await knex.transaction(async (trx) => {
|
return await knex.transaction(async (trx) => {
|
||||||
// We have to insert either both in Organization and in OrganizationAdministrator
|
// We have to insert either both in Organization and in OrganizationAdministrator
|
||||||
// or in neither
|
// or in neither
|
||||||
@ -76,7 +76,7 @@ async function insertOrganization (organization, organizationAdministratorId) {
|
|||||||
* @param {*} requester
|
* @param {*} requester
|
||||||
* @returns true if the row was updated, false otherwise
|
* @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')
|
const numberOfUpdatedRows = await knex('Organization')
|
||||||
.where('id', organizationId)
|
.where('id', organizationId)
|
||||||
.whereExists(function () {
|
.whereExists(function () {
|
||||||
@ -96,9 +96,11 @@ async function updateOrganization (organization, organizationId, requester) {
|
|||||||
* @param {*} requester PersonId of the supposedly administrator
|
* @param {*} requester PersonId of the supposedly administrator
|
||||||
* @returns true if the Organization was successfully deleted, false otherwise
|
* @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')
|
const numberOfDeletedRows = await knex('Organization')
|
||||||
.where({ id: organizationId })
|
.where({
|
||||||
|
id: organizationId
|
||||||
|
})
|
||||||
.whereExists(function () {
|
.whereExists(function () {
|
||||||
this.select('*')
|
this.select('*')
|
||||||
.from('OrganizationAdministrator')
|
.from('OrganizationAdministrator')
|
||||||
@ -118,4 +120,4 @@ module.exports = {
|
|||||||
insertOrganization,
|
insertOrganization,
|
||||||
updateOrganization,
|
updateOrganization,
|
||||||
deleteOrganization
|
deleteOrganization
|
||||||
};
|
};
|
@ -19,7 +19,7 @@ const knex = require('../utils/knex_config');
|
|||||||
* @param {*} content
|
* @param {*} content
|
||||||
* @param {*} originalAuthor
|
* @param {*} originalAuthor
|
||||||
*/
|
*/
|
||||||
function createOrganizationPost (organizationId, content, originalAuthor) {
|
function createOrganizationPost(organizationId, content, originalAuthor) {
|
||||||
const organizationPost = {
|
const organizationPost = {
|
||||||
organization_id: organizationId,
|
organization_id: organizationId,
|
||||||
content,
|
content,
|
||||||
@ -34,7 +34,7 @@ function createOrganizationPost (organizationId, content, originalAuthor) {
|
|||||||
* @param {*} organization
|
* @param {*} organization
|
||||||
* @returns the inserted OrganizationPost
|
* @returns the inserted OrganizationPost
|
||||||
*/
|
*/
|
||||||
async function insertOrganizationPost (organization) {
|
async function insertOrganizationPost(organization) {
|
||||||
const isOrganizationAdmin = await knex('OrganizationAdministrator')
|
const isOrganizationAdmin = await knex('OrganizationAdministrator')
|
||||||
.where('id_person', organization.original_author)
|
.where('id_person', organization.original_author)
|
||||||
.where('id_organization', organization.organization_id)
|
.where('id_organization', organization.organization_id)
|
||||||
@ -65,7 +65,7 @@ async function insertOrganizationPost (organization) {
|
|||||||
* @param {*} personId
|
* @param {*} personId
|
||||||
* @returns true or false
|
* @returns true or false
|
||||||
*/
|
*/
|
||||||
async function isPersonPostAdministrator (postId, personId) {
|
async function isPersonPostAdministrator(postId, personId) {
|
||||||
return await knex('OrganizationPost')
|
return await knex('OrganizationPost')
|
||||||
.join('OrganizationAdministrator', 'OrganizationPost.organization_id', 'OrganizationAdministrator.id_organization')
|
.join('OrganizationAdministrator', 'OrganizationPost.organization_id', 'OrganizationAdministrator.id_organization')
|
||||||
.where('OrganizationPost.id', postId)
|
.where('OrganizationPost.id', postId)
|
||||||
@ -80,11 +80,11 @@ async function isPersonPostAdministrator (postId, personId) {
|
|||||||
* @param {*} postId Id of the Post to delete
|
* @param {*} postId Id of the Post to delete
|
||||||
* @param {*} requester Id of the Person requesting the deletion
|
* @param {*} requester Id of the Person requesting the deletion
|
||||||
*/
|
*/
|
||||||
async function deleteOrganizationPost (postId, requester) {
|
async function deleteOrganizationPost(postId, requester) {
|
||||||
if(await isPersonPostAdministrator(postId, requester)){
|
if (await isPersonPostAdministrator(postId, requester)) {
|
||||||
return await knex('OrganizationPost')
|
return await knex('OrganizationPost')
|
||||||
.where('id', postId)
|
.where('id', postId)
|
||||||
.del() == 1;
|
.del() == 1;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -94,4 +94,4 @@ module.exports = {
|
|||||||
insertOrganizationPost,
|
insertOrganizationPost,
|
||||||
isPersonPostAdministrator,
|
isPersonPostAdministrator,
|
||||||
deleteOrganizationPost
|
deleteOrganizationPost
|
||||||
};
|
};
|
@ -25,7 +25,7 @@ const bcrypt = require('bcrypt');
|
|||||||
* @param {*} placeOfLiving
|
* @param {*} placeOfLiving
|
||||||
* @returns
|
* @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 = {
|
const person = {
|
||||||
email: email.toLowerCase(),
|
email: email.toLowerCase(),
|
||||||
password,
|
password,
|
||||||
@ -45,7 +45,7 @@ function createPerson (email, password, displayName, dateOfBirth, available, ena
|
|||||||
* @param {*} email email to look the Person for
|
* @param {*} email email to look the Person for
|
||||||
* @returns the Person object
|
* @returns the Person object
|
||||||
*/
|
*/
|
||||||
async function getPersonByEmail (email) {
|
async function getPersonByEmail(email) {
|
||||||
return await knex('Person')
|
return await knex('Person')
|
||||||
.where('email', email.toLowerCase())
|
.where('email', email.toLowerCase())
|
||||||
.first();
|
.first();
|
||||||
@ -56,10 +56,12 @@ async function getPersonByEmail (email) {
|
|||||||
* @param {*} id - The id to look the person for
|
* @param {*} id - The id to look the person for
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
async function getPersonById (id) {
|
async function getPersonById(id) {
|
||||||
return await knex('Person')
|
return await knex('Person')
|
||||||
.select('*')
|
.select('*')
|
||||||
.where({ id })
|
.where({
|
||||||
|
id
|
||||||
|
})
|
||||||
.first();
|
.first();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -69,7 +71,7 @@ async function getPersonById (id) {
|
|||||||
* @param {*} person A Person object
|
* @param {*} person A Person object
|
||||||
* @param {*} activationLink the activationLink identifier
|
* @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
|
// We need to insert either both in the "Person" table
|
||||||
// and in the "ActivationLink" one, or in neither
|
// and in the "ActivationLink" one, or in neither
|
||||||
await knex.transaction(async (tr) => {
|
await knex.transaction(async (tr) => {
|
||||||
@ -91,7 +93,7 @@ async function registerPerson (person, activationLink) {
|
|||||||
* @param {*} password
|
* @param {*} password
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
async function getPersonByEmailAndPassword (email, password) {
|
async function getPersonByEmailAndPassword(email, password) {
|
||||||
const person = await knex('Person')
|
const person = await knex('Person')
|
||||||
.where('email', email.toLowerCase())
|
.where('email', email.toLowerCase())
|
||||||
.where('enabled', true)
|
.where('enabled', true)
|
||||||
@ -112,7 +114,7 @@ async function getPersonByEmailAndPassword (email, password) {
|
|||||||
* @param {*} person The Person to update
|
* @param {*} person The Person to update
|
||||||
* @param {*} person_id The database id of 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')
|
await knex('Person')
|
||||||
.where('id', person_id)
|
.where('id', person_id)
|
||||||
.update(person);
|
.update(person);
|
||||||
@ -122,21 +124,25 @@ async function updatePerson (person, person_id) {
|
|||||||
* Deletes a Person specified by its database id.
|
* Deletes a Person specified by its database id.
|
||||||
* @param {*} person_id
|
* @param {*} person_id
|
||||||
*/
|
*/
|
||||||
async function deletePerson (personId) {
|
async function deletePerson(personId) {
|
||||||
await knex('Person')
|
await knex('Person')
|
||||||
.where({ id: personId })
|
.where({
|
||||||
|
id: personId
|
||||||
|
})
|
||||||
.del();
|
.del();
|
||||||
}
|
}
|
||||||
|
|
||||||
async function confirmActivation (personId) {
|
async function confirmActivation(personId) {
|
||||||
await knex.transaction(async (tr) => {
|
await knex.transaction(async (tr) => {
|
||||||
await knex('Person')
|
await knex('Person')
|
||||||
.where('id', personId)
|
.where('id', personId)
|
||||||
.update({enabled: true});
|
.update({
|
||||||
|
enabled: true
|
||||||
|
});
|
||||||
|
|
||||||
await tr('ActivationLink')
|
await tr('ActivationLink')
|
||||||
.where('person_id', personId)
|
.where('person_id', personId)
|
||||||
.del();
|
.del();
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -153,4 +159,4 @@ module.exports = {
|
|||||||
updatePerson,
|
updatePerson,
|
||||||
deletePerson,
|
deletePerson,
|
||||||
confirmActivation
|
confirmActivation
|
||||||
};
|
};
|
@ -23,45 +23,59 @@ const jwtUtils = require('../utils/middleware_utils');
|
|||||||
*
|
*
|
||||||
* Required field(s): organization_id, person_id
|
* 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
|
// Ensure that the required fields are present before proceeding
|
||||||
if (!req.body.organization_id || !req.body.person_id) {
|
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 {
|
try {
|
||||||
const success = await organizationAdminModel.addOrganizationAdministrator(req.body.person_id, req.body.organization_id, req.jwt.person_id);
|
const success = await organizationAdminModel.addOrganizationAdministrator(req.body.person_id, req.body.organization_id, req.jwt.person_id);
|
||||||
if(success){
|
if (success) {
|
||||||
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) {
|
} catch (error) {
|
||||||
console.error(`Error in function ${addOrganizationAdmin.name}: ${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
|
* DELETE Request
|
||||||
*
|
*
|
||||||
* Deletes a Person from the list of Administrators of an Organization.
|
* Deletes a Person from the list of Administrators of an Organization.
|
||||||
* The logged user can only remove themselves. If no more Administrators
|
* The logged user can only remove themselves. If no more Administrators
|
||||||
* are left, the Organization is removed.
|
* are left, the Organization is removed.
|
||||||
*
|
*
|
||||||
* Required field(s): organization_id
|
* Required field(s): organization_id
|
||||||
*/
|
*/
|
||||||
async function removeOrganizationAdmin (req, res) {
|
async function removeOrganizationAdmin(req, res) {
|
||||||
// Ensure that the required fields are present before proceeding
|
// Ensure that the required fields are present before proceeding
|
||||||
if (!req.body.organization_id) {
|
if (!req.body.organization_id) {
|
||||||
return res.status(400).json({ error: 'Invalid request' });
|
return res.status(400).json({
|
||||||
|
error: 'Invalid request'
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await organizationAdminModel.removeOrganizationAdmin(req.jwt.person_id, req.body.organization_id);
|
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) {
|
} catch (error) {
|
||||||
console.error(`Error in function ${removeOrganizationAdmin.name}: ${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 = {
|
module.exports = {
|
||||||
protectedRoutes
|
protectedRoutes
|
||||||
};
|
};
|
@ -16,17 +16,19 @@ const express = require('express');
|
|||||||
const jwtUtils = require('../utils/middleware_utils');
|
const jwtUtils = require('../utils/middleware_utils');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* POST Request
|
* POST Request
|
||||||
*
|
*
|
||||||
* Creates a Post belonging to an organization
|
* Creates a Post belonging to an organization
|
||||||
*
|
*
|
||||||
* Required field(s): organization_id, content
|
* Required field(s): organization_id, content
|
||||||
* @returns the inserted Post
|
* @returns the inserted Post
|
||||||
*/
|
*/
|
||||||
async function createOrganizationPost (req, res) {
|
async function createOrganizationPost(req, res) {
|
||||||
// Ensure that the required fields are present before proceeding
|
// Ensure that the required fields are present before proceeding
|
||||||
if (!req.body.organization_id || !req.body.content) {
|
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(
|
const organization = organizationPostModel.createOrganizationPost(
|
||||||
@ -39,7 +41,9 @@ async function createOrganizationPost (req, res) {
|
|||||||
return res.status(200).json(insertedOrganization);
|
return res.status(200).json(insertedOrganization);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(`Error in function ${createOrganizationPost.name}: ${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.
|
* Required field(s): none.
|
||||||
*/
|
*/
|
||||||
async function deleteOrganizationPost (req, res) {
|
async function deleteOrganizationPost(req, res) {
|
||||||
try {
|
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) {
|
} catch (error) {
|
||||||
console.error(`Error in function ${deleteOrganizationPost.name}: ${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 available for use in another module.
|
||||||
module.exports = {
|
module.exports = {
|
||||||
protectedRoutes
|
protectedRoutes
|
||||||
};
|
};
|
@ -24,10 +24,12 @@ const jwtUtils = require('../utils/middleware_utils');
|
|||||||
*
|
*
|
||||||
* @returns the inserted organization
|
* @returns the inserted organization
|
||||||
*/
|
*/
|
||||||
async function createOrganization (req, res) {
|
async function createOrganization(req, res) {
|
||||||
// Ensure that the required fields are present before proceeding
|
// Ensure that the required fields are present before proceeding
|
||||||
if (!req.body.name) {
|
if (!req.body.name) {
|
||||||
return res.status(400).json({ error: 'Invalid request' });
|
return res.status(400).json({
|
||||||
|
error: 'Invalid request'
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -36,7 +38,9 @@ async function createOrganization (req, res) {
|
|||||||
return res.status(200).json(insertedOrganization);
|
return res.status(200).json(insertedOrganization);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(`Error in function ${createOrganization.name}: ${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.
|
* Required field(s): none.
|
||||||
*/
|
*/
|
||||||
async function updateOrganization (req, res) {
|
async function updateOrganization(req, res) {
|
||||||
const updateOrganization = {};
|
const updateOrganization = {};
|
||||||
|
|
||||||
if (req.body.name) {
|
if (req.body.name) {
|
||||||
@ -66,19 +70,27 @@ async function updateOrganization (req, res) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (Object.keys(updateOrganization).length === 0) {
|
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 {
|
try {
|
||||||
const isUpdateSuccessful = organizationModel.updateOrganization(updateOrganization, req.params.id, req.jwt.person_id);
|
const isUpdateSuccessful = organizationModel.updateOrganization(updateOrganization, req.params.id, req.jwt.person_id);
|
||||||
if (isUpdateSuccessful) {
|
if (isUpdateSuccessful) {
|
||||||
return res.status(200).json({ success: 'true' });
|
return res.status(200).json({
|
||||||
|
success: 'true'
|
||||||
|
});
|
||||||
} else {
|
} 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) {
|
} catch (error) {
|
||||||
console.error(`Error in function ${updateOrganization.name}: ${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
|
* Deletes the specified organization if the logged user is
|
||||||
* one of its administrator
|
* one of its administrator
|
||||||
*/
|
*/
|
||||||
async function deleteOrganization (req, res) {
|
async function deleteOrganization(req, res) {
|
||||||
try {
|
try {
|
||||||
const isDeleteSuccessful = await organizationModel.deleteOrganization(req.params.id, req.jwt.person_id);
|
const isDeleteSuccessful = await organizationModel.deleteOrganization(req.params.id, req.jwt.person_id);
|
||||||
if (isDeleteSuccessful) {
|
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) {
|
} catch (error) {
|
||||||
console.error(`Error in function ${deleteOrganization.name}: ${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.
|
* @returns the organization.
|
||||||
*/
|
*/
|
||||||
async function getOrganization (req, res) {
|
async function getOrganization(req, res) {
|
||||||
try {
|
try {
|
||||||
const organization = await organizationModel.getOrganizationById(req.params.id);
|
const organization = await organizationModel.getOrganizationById(req.params.id);
|
||||||
if (organization) {
|
if (organization) {
|
||||||
return res.status(200).json(organization);
|
return res.status(200).json(organization);
|
||||||
} else {
|
} else {
|
||||||
return res.status(404).json({ error: 'Not found' });
|
return res.status(404).json({
|
||||||
|
error: 'Not found'
|
||||||
|
});
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(`Error in function ${getOrganization.name}: ${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 = {
|
module.exports = {
|
||||||
publicRoutes,
|
publicRoutes,
|
||||||
protectedRoutes
|
protectedRoutes
|
||||||
};
|
};
|
@ -28,17 +28,23 @@ const express = require('express');
|
|||||||
*
|
*
|
||||||
* @returns The activationlink identifier
|
* @returns The activationlink identifier
|
||||||
*/
|
*/
|
||||||
async function registerPerson (req, res) {
|
async function registerPerson(req, res) {
|
||||||
// Does this server allow users to register?
|
// Does this server allow users to register?
|
||||||
if (process.env.ALLOW_USER_REGISTRATION === 'false') {
|
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
|
// Ensure that the required fields are present before proceeding
|
||||||
if (!req.body.display_name || !req.body.email || !req.body.password) {
|
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)) {
|
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
|
// Generate activation link token
|
||||||
@ -50,7 +56,9 @@ async function registerPerson (req, res) {
|
|||||||
// Check whether e-mail exists already (enforced by database constraints)
|
// Check whether e-mail exists already (enforced by database constraints)
|
||||||
const existingUser = await personModel.getPersonByEmail(req.body.email);
|
const existingUser = await personModel.getPersonByEmail(req.body.email);
|
||||||
if (existingUser) {
|
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(
|
const personToInsert = personModel.createPerson(
|
||||||
req.body.email,
|
req.body.email,
|
||||||
@ -63,10 +71,14 @@ async function registerPerson (req, res) {
|
|||||||
req.body.about_me,
|
req.body.about_me,
|
||||||
req.body.qualification);
|
req.body.qualification);
|
||||||
await personModel.registerPerson(personToInsert, activationLink);
|
await personModel.registerPerson(personToInsert, activationLink);
|
||||||
return res.status(200).json({ activationLink });
|
return res.status(200).json({
|
||||||
|
activationLink
|
||||||
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(`Error in function ${registerPerson.name}: ${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
|
* @returns The token
|
||||||
*/
|
*/
|
||||||
async function login (req, res) {
|
async function login(req, res) {
|
||||||
// Ensure that the required fields are present before proceeding
|
// Ensure that the required fields are present before proceeding
|
||||||
if (!req.body.email || !req.body.password) {
|
if (!req.body.email || !req.body.password) {
|
||||||
return res.status(400).json({ error: 'Invalid request' });
|
return res.status(400).json({
|
||||||
|
error: 'Invalid request'
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const person = await personModel.getPersonByEmailAndPassword(req.body.email, req.body.password);
|
const person = await personModel.getPersonByEmailAndPassword(req.body.email, req.body.password);
|
||||||
if (person) {
|
if (person) {
|
||||||
const token = jwtUtils.generateToken(person.id);
|
const token = jwtUtils.generateToken(person.id);
|
||||||
return res.status(200).json({ token });
|
return res.status(200).json({
|
||||||
|
token
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
return res.status(401).json({ error: 'Invalid credentials' });
|
return res.status(401).json({
|
||||||
|
error: 'Invalid credentials'
|
||||||
|
});
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(`Error in function ${login.name}: ${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
|
* @returns The Person
|
||||||
*/
|
*/
|
||||||
async function getPerson (req, res) {
|
async function getPerson(req, res) {
|
||||||
try {
|
try {
|
||||||
const person = await personModel.getPersonById(req.params.id);
|
const person = await personModel.getPersonById(req.params.id);
|
||||||
if (person && person.enabled) {
|
if (person && person.enabled) {
|
||||||
delete person.password; // remove password field for security reasons
|
delete person.password; // remove password field for security reasons
|
||||||
return res.status(200).send(person);
|
return res.status(200).send(person);
|
||||||
}
|
}
|
||||||
return res.status(404).json({ error: 'Not found' });
|
return res.status(404).json({
|
||||||
|
error: 'Not found'
|
||||||
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(`Error in function ${getPerson.name}: ${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
|
* @returns Person's details
|
||||||
*/
|
*/
|
||||||
async function getMyself (req, res) {
|
async function getMyself(req, res) {
|
||||||
try {
|
try {
|
||||||
const person = await personModel.getPersonById(req.jwt.person_id);
|
const person = await personModel.getPersonById(req.jwt.person_id);
|
||||||
if (person) {
|
if (person) {
|
||||||
delete person.password;
|
delete person.password;
|
||||||
return res.status(200).send(person);
|
return res.status(200).send(person);
|
||||||
}
|
}
|
||||||
return res.status(404).json({ error: 'Not found' });
|
return res.status(404).json({
|
||||||
|
error: 'Not found'
|
||||||
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(`Error in function ${getMyself.name}: ${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.
|
* new_password if updating the password.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
async function updatePerson (req, res) {
|
async function updatePerson(req, res) {
|
||||||
const updatePerson = {};
|
const updatePerson = {};
|
||||||
|
|
||||||
if (req.body.display_name) {
|
if (req.body.display_name) {
|
||||||
@ -167,7 +195,9 @@ async function updatePerson (req, res) {
|
|||||||
if (validator.isPostgresDateFormatValid(req.body.date_of_birth)) {
|
if (validator.isPostgresDateFormatValid(req.body.date_of_birth)) {
|
||||||
updatePerson.date_of_birth = req.body.date_of_birth;
|
updatePerson.date_of_birth = req.body.date_of_birth;
|
||||||
} else {
|
} 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;
|
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;
|
updatePerson.about_me = req.body.about_me;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(req.body.qualification) {
|
if (req.body.qualification) {
|
||||||
updatePerson.qualification = req.body.qualification;
|
updatePerson.qualification = req.body.qualification;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we are tying to change password, the old password must be provided
|
// 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 || req.body.new_password) {
|
||||||
if(!req.body.old_password){
|
if (!req.body.old_password) {
|
||||||
return res.status(401).json({ error: 'The old password must be specified' });
|
return res.status(401).json({
|
||||||
|
error: 'The old password must be specified'
|
||||||
|
});
|
||||||
}
|
}
|
||||||
if(!req.body.new_password){
|
if (!req.body.new_password) {
|
||||||
return res.status(401).json({ error: 'The new password must be specified' });
|
return res.status(401).json({
|
||||||
|
error: 'The new password must be specified'
|
||||||
|
});
|
||||||
}
|
}
|
||||||
const user = await personModel.getPersonById(req.jwt.person_id);
|
const user = await personModel.getPersonById(req.jwt.person_id);
|
||||||
const passwordMatches = await bcrypt.compare(req.body.old_password, user.password);
|
const passwordMatches = await bcrypt.compare(req.body.old_password, user.password);
|
||||||
if (passwordMatches) {
|
if (passwordMatches) {
|
||||||
updatePerson.password = await bcrypt.hash(req.body.new_password, 10);
|
updatePerson.password = await bcrypt.hash(req.body.new_password, 10);
|
||||||
} else {
|
} 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) {
|
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 {
|
try {
|
||||||
await personModel.updatePerson(updatePerson, req.jwt.person_id);
|
await personModel.updatePerson(updatePerson, req.jwt.person_id);
|
||||||
return res.status(200).json({ success: 'true' });
|
return res.status(200).json({
|
||||||
|
success: 'true'
|
||||||
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(`Error in function ${updatePerson.name}: ${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
|
* Required field(s): none
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
async function deletePerson (req, res) {
|
async function deletePerson(req, res) {
|
||||||
// TODO: Delete Organization if this user was its only administrator
|
// TODO: Delete Organization if this user was its only administrator
|
||||||
try {
|
try {
|
||||||
await personModel.deletePerson(req.jwt.person_id);
|
await personModel.deletePerson(req.jwt.person_id);
|
||||||
return res.status(200).json({ success: true });
|
return res.status(200).json({
|
||||||
|
success: true
|
||||||
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(`Error in function ${deletePerson.name}: ${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
|
* Required field(s): identifier
|
||||||
*/
|
*/
|
||||||
async function confirmActivation(req, res){
|
async function confirmActivation(req, res) {
|
||||||
try {
|
try {
|
||||||
const personId = await activationModel.getPersonIdByIdentifier(req.query.q);
|
const personId = await activationModel.getPersonIdByIdentifier(req.query.q);
|
||||||
if(!personId){
|
if (!personId) {
|
||||||
return res.status(401).json({error: 'Activation Link either not valid or expired'});
|
return res.status(401).json({
|
||||||
|
error: 'Activation Link either not valid or expired'
|
||||||
|
});
|
||||||
}
|
}
|
||||||
await personModel.confirmActivation(personId);
|
await personModel.confirmActivation(personId);
|
||||||
return res.status(200).json({ success: true });
|
return res.status(200).json({
|
||||||
|
success: true
|
||||||
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(`Error in function ${confirmActivation.name}: ${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 = {
|
module.exports = {
|
||||||
publicRoutes,
|
publicRoutes,
|
||||||
protectedRoutes
|
protectedRoutes
|
||||||
};
|
};
|
@ -22,4 +22,4 @@ const knexInstance = require('knex')({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
module.exports = knexInstance;
|
module.exports = knexInstance;
|
@ -13,7 +13,7 @@
|
|||||||
|
|
||||||
const jwt = require('jsonwebtoken');
|
const jwt = require('jsonwebtoken');
|
||||||
|
|
||||||
function generateToken (person_id) {
|
function generateToken(person_id) {
|
||||||
// The payload the JWT will carry within itself
|
// The payload the JWT will carry within itself
|
||||||
const payload = {
|
const payload = {
|
||||||
person_id
|
person_id
|
||||||
@ -26,16 +26,20 @@ function generateToken (person_id) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Middlware
|
// Middlware
|
||||||
function verifyToken (req, res, next) {
|
function verifyToken(req, res, next) {
|
||||||
const token = req.headers.authorization;
|
const token = req.headers.authorization;
|
||||||
|
|
||||||
if (!token) {
|
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) => {
|
jwt.verify(token, process.env.JWT_SECRET_KEY, (err, decoded) => {
|
||||||
if (err) {
|
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
|
// If the token is valid, store the decoded data in the request object
|
||||||
@ -48,4 +52,4 @@ function verifyToken (req, res, next) {
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
generateToken,
|
generateToken,
|
||||||
verifyToken
|
verifyToken
|
||||||
};
|
};
|
@ -16,7 +16,7 @@
|
|||||||
* @param {*} email email to validate
|
* @param {*} email email to validate
|
||||||
* @returns true or false
|
* @returns true or false
|
||||||
*/
|
*/
|
||||||
function validateEmail (email) {
|
function validateEmail(email) {
|
||||||
const regex = /^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$/;
|
const regex = /^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$/;
|
||||||
return regex.test(email);
|
return regex.test(email);
|
||||||
}
|
}
|
||||||
@ -27,7 +27,7 @@ function validateEmail (email) {
|
|||||||
* @param {*} dateString the date to validate
|
* @param {*} dateString the date to validate
|
||||||
* @returns true or false
|
* @returns true or false
|
||||||
*/
|
*/
|
||||||
function isPostgresDateFormatValid (dateString) {
|
function isPostgresDateFormatValid(dateString) {
|
||||||
const regex = /^\d{4}-\d{2}-\d{2}$/;
|
const regex = /^\d{4}-\d{2}-\d{2}$/;
|
||||||
return regex.test(dateString);
|
return regex.test(dateString);
|
||||||
}
|
}
|
||||||
@ -35,4 +35,4 @@ function isPostgresDateFormatValid (dateString) {
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
validateEmail,
|
validateEmail,
|
||||||
isPostgresDateFormatValid
|
isPostgresDateFormatValid
|
||||||
};
|
};
|
@ -1,65 +1,71 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en" >
|
<html lang="en">
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<title>Log in - Blink</title>
|
|
||||||
<link rel="stylesheet" href="../css/login-register.css">
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<!-- partial:index.partial.html -->
|
|
||||||
<div id="login-form-wrap">
|
|
||||||
<h2>Login</h2>
|
|
||||||
<form id="login-form" method="POST">
|
|
||||||
|
|
||||||
<p>
|
<head>
|
||||||
<input type="email" id="email" name="email" placeholder="Email Address" required><i class="validation"><span></span><span></span></i>
|
<meta charset="UTF-8">
|
||||||
</p>
|
<title>Log in - Blink</title>
|
||||||
|
<link rel="stylesheet" href="../css/login-register.css">
|
||||||
|
</head>
|
||||||
|
|
||||||
<p>
|
<body>
|
||||||
<input type="password" id="password" name="password" placeholder="Password" required><i class="validation"><span></span><span></span></i>
|
<!-- partial:index.partial.html -->
|
||||||
</p>
|
<div id="login-form-wrap">
|
||||||
|
<h2>Login</h2>
|
||||||
|
<form id="login-form" method="POST">
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<input type="email" id="email" name="email" placeholder="Email Address" required><i
|
||||||
|
class="validation"><span></span><span></span></i>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<input type="password" id="password" name="password" placeholder="Password" required><i
|
||||||
|
class="validation"><span></span><span></span></i>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<button type="button" onclick="login()">Login</button>
|
||||||
|
</p>
|
||||||
|
</form>
|
||||||
|
<div id="create-account-wrap">
|
||||||
|
<p>Not a member? <a href="./register.html">Create Account</a>
|
||||||
<p>
|
<p>
|
||||||
<button type="button" onclick="login()">Login</button>
|
|
||||||
</p>
|
|
||||||
</form>
|
|
||||||
<div id="create-account-wrap">
|
|
||||||
<p>Not a member? <a href="./register.html">Create Account</a><p>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<script src="../js/constants.js"></script>
|
<script src="../js/constants.js"></script>
|
||||||
<script>
|
<script>
|
||||||
async function login() {
|
async function login() {
|
||||||
const email = document.getElementById("email").value;
|
const email = document.getElementById("email").value;
|
||||||
const password = document.getElementById("password").value;
|
const password = document.getElementById("password").value;
|
||||||
|
|
||||||
if(!email || !password){
|
if (!email || !password) {
|
||||||
alert('Please fill in all fields');
|
alert('Please fill in all fields');
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
const response = await fetch(`${API_URL}/login`, {
|
|
||||||
method: "POST",
|
|
||||||
body: JSON.stringify({
|
|
||||||
email: email,
|
|
||||||
password: password }),
|
|
||||||
headers: {
|
|
||||||
"Content-type": "application/json; charset=UTF-8"
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const data = await response.json();
|
|
||||||
|
|
||||||
if(response.ok){
|
|
||||||
console.log(`Login was successful. Token is ${data.token}`);
|
|
||||||
document.cookie = `token=${data.token};`;
|
|
||||||
window.location.href = 'userprofile.html?id=myself';
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
alert(data.error);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
</script>
|
const response = await fetch(`${API_URL}/login`, {
|
||||||
|
method: "POST",
|
||||||
|
body: JSON.stringify({
|
||||||
|
email: email,
|
||||||
|
password: password
|
||||||
|
}),
|
||||||
|
headers: {
|
||||||
|
"Content-type": "application/json; charset=UTF-8"
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const data = await response.json();
|
||||||
|
|
||||||
|
if (response.ok) {
|
||||||
|
console.log(`Login was successful. Token is ${data.token}`);
|
||||||
|
document.cookie = `token=${data.token};`;
|
||||||
|
window.location.href = 'userprofile.html?id=myself';
|
||||||
|
} else {
|
||||||
|
alert(data.error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
|
||||||
</body>
|
|
||||||
</html>
|
</html>
|
@ -1,11 +1,13 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title>Title</title>
|
<title>Title</title>
|
||||||
<link rel="stylesheet" href="../css/organization.css">
|
<link rel="stylesheet" href="../css/organization.css">
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body style="display: none;">
|
<body style="display: none;">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="hiring-badge" style="display: none;" id="isHiringBadge">Now Hiring</div>
|
<div class="hiring-badge" style="display: none;" id="isHiringBadge">Now Hiring</div>
|
||||||
@ -26,50 +28,47 @@
|
|||||||
<script src="../js/utils.js"></script>
|
<script src="../js/utils.js"></script>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
window.addEventListener("load", async function() {
|
window.addEventListener("load", async function () {
|
||||||
loadOrganization();
|
loadOrganization();
|
||||||
});
|
});
|
||||||
|
|
||||||
async function loadOrganization (){
|
async function loadOrganization() {
|
||||||
const idToDisplay = new URLSearchParams(window.location.search).get('id');
|
const idToDisplay = new URLSearchParams(window.location.search).get('id');
|
||||||
if(!idToDisplay){
|
if (!idToDisplay) {
|
||||||
alert("Invalid URL.");
|
alert("Invalid URL.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const response = await fetch(`${API_URL}/organization/${idToDisplay}`, {
|
const response = await fetch(`${API_URL}/organization/${idToDisplay}`, {
|
||||||
headers: {
|
headers: {
|
||||||
"Content-type": "application/json; charset=UTF-8",
|
"Content-type": "application/json; charset=UTF-8",
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
const data = await response.json();
|
const data = await response.json();
|
||||||
if(response.ok) {
|
if (response.ok) {
|
||||||
populateFields(data.name, data.location, data.description, data.is_hiring);
|
populateFields(data.name, data.location, data.description, data.is_hiring);
|
||||||
document.body.style.display = "block"; // Show page
|
document.body.style.display = "block"; // Show page
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
alert(data.error);
|
alert(data.error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function populateFields (name, location, description, isHiring) {
|
function populateFields(name, location, description, isHiring) {
|
||||||
document.getElementById('organizationName').textContent = name;
|
document.getElementById('organizationName').textContent = name;
|
||||||
document.title = `${name} - Blink`
|
document.title = `${name} - Blink`
|
||||||
document.getElementById('location').textContent = location;
|
document.getElementById('location').textContent = location;
|
||||||
document.getElementById('description').textContent = description;
|
document.getElementById('description').textContent = description;
|
||||||
if(isHiring === true) {
|
if (isHiring === true) {
|
||||||
document.getElementById('isHiring').textContent = 'Yes';
|
document.getElementById('isHiring').textContent = 'Yes';
|
||||||
document.getElementById('isHiringBadge').style.display = 'block';
|
document.getElementById('isHiringBadge').style.display = 'block';
|
||||||
}
|
} else if (isHiring === false) {
|
||||||
else if (isHiring === false) {
|
|
||||||
document.getElementById('isHiring').textContent = 'No';
|
document.getElementById('isHiring').textContent = 'No';
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
document.getElementById('isHiring').textContent = 'Not specified';
|
document.getElementById('isHiring').textContent = 'Not specified';
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
|
||||||
|
</html>
|
@ -1,76 +1,86 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en" >
|
<html lang="en">
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<title>Sign Up to Blink</title>
|
|
||||||
<link rel="stylesheet" href="../css/login-register.css">
|
|
||||||
<script src=""></script>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<!-- partial:index.partial.html -->
|
|
||||||
<div id="login-form-wrap">
|
|
||||||
<h2>Sign Up</h2>
|
|
||||||
<form id="login-form">
|
|
||||||
|
|
||||||
<p>
|
<head>
|
||||||
<input type="text" id="displayname" name="displayname" placeholder="Your name" required><i class="validation"><span></span><span></span></i>
|
<meta charset="UTF-8">
|
||||||
</p>
|
<title>Sign Up to Blink</title>
|
||||||
|
<link rel="stylesheet" href="../css/login-register.css">
|
||||||
|
<script src=""></script>
|
||||||
|
</head>
|
||||||
|
|
||||||
<p>
|
<body>
|
||||||
<input type="email" id="email" name="email" placeholder="Email Address" required><i class="validation"><span></span><span></span></i>
|
<!-- partial:index.partial.html -->
|
||||||
</p>
|
<div id="login-form-wrap">
|
||||||
|
<h2>Sign Up</h2>
|
||||||
|
<form id="login-form">
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
<input type="password" id="password" name="password" placeholder="Password" required><i class="validation"><span></span><span></span></i>
|
<input type="text" id="displayname" name="displayname" placeholder="Your name" required><i
|
||||||
</p>
|
class="validation"><span></span><span></span></i>
|
||||||
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
<button type="button" onclick="register()">Register</button>
|
<input type="email" id="email" name="email" placeholder="Email Address" required><i
|
||||||
</p>
|
class="validation"><span></span><span></span></i>
|
||||||
</form>
|
</p>
|
||||||
<div id="create-account-wrap">
|
|
||||||
<p>Already a member? <a href="./login.html">Login</a><p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<script src="../js/constants.js"></script>
|
<p>
|
||||||
<script src="../js/utils.js"></script>
|
<input type="password" id="password" name="password" placeholder="Password" required><i
|
||||||
|
class="validation"><span></span><span></span></i>
|
||||||
|
</p>
|
||||||
|
|
||||||
<script>
|
<p>
|
||||||
|
<button type="button" onclick="register()">Register</button>
|
||||||
|
</p>
|
||||||
|
</form>
|
||||||
|
<div id="create-account-wrap">
|
||||||
|
<p>Already a member? <a href="./login.html">Login</a>
|
||||||
|
<p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
function register(){
|
<script src="../js/constants.js"></script>
|
||||||
const display_name = document.getElementById('displayname').value;
|
<script src="../js/utils.js"></script>
|
||||||
const email = document.getElementById('email').value;
|
|
||||||
const password = document.getElementById('password').value;
|
<script>
|
||||||
|
function register() {
|
||||||
if(!display_name || !email || !password){
|
const display_name = document.getElementById('displayname').value;
|
||||||
alert('Please fill in all fields');
|
const email = document.getElementById('email').value;
|
||||||
return;
|
const password = document.getElementById('password').value;
|
||||||
|
|
||||||
|
if (!display_name || !email || !password) {
|
||||||
|
alert('Please fill in all fields');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const options = {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
display_name,
|
||||||
|
email,
|
||||||
|
password
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
|
||||||
|
fetch(`${API_URL}/register`, options)
|
||||||
|
.then(response => {
|
||||||
|
if (response.ok) {
|
||||||
|
alert("Congratulations! You've successfully registered to Blink." +
|
||||||
|
" Please click on the e-mail we sent you to confirm your account");
|
||||||
|
|
||||||
|
window.location.href = '/login.html';
|
||||||
}
|
}
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
alert("An error has occurred :-( please try again later")
|
||||||
|
console.error(err);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
const options = {
|
</body>
|
||||||
method: 'POST',
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json'
|
|
||||||
},
|
|
||||||
body: JSON.stringify({ display_name, email, password }),
|
|
||||||
};
|
|
||||||
|
|
||||||
fetch(`${API_URL}/register`, options)
|
</html>
|
||||||
.then(response => {
|
|
||||||
if (response.ok) {
|
|
||||||
alert("Congratulations! You've successfully registered to Blink." +
|
|
||||||
" Please click on the e-mail we sent you to confirm your account");
|
|
||||||
|
|
||||||
window.location.href = '/login.html';
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(err => {
|
|
||||||
alert("An error has occurred :-( please try again later")
|
|
||||||
console.error(err);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
</body>
|
|
||||||
</html>
|
|
@ -1,11 +1,13 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title>Page Title</title>
|
<title>Page Title</title>
|
||||||
<link rel="stylesheet" href="../css/profile.css">
|
<link rel="stylesheet" href="../css/profile.css">
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body style="display: none;">
|
<body style="display: none;">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="edit-badge" style="display: none;" id="editBadge" onclick="editProfile()">Edit</div>
|
<div class="edit-badge" style="display: none;" id="editBadge" onclick="editProfile()">Edit</div>
|
||||||
@ -46,21 +48,21 @@
|
|||||||
<script src="../js/utils.js"></script>
|
<script src="../js/utils.js"></script>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
window.addEventListener("load", async function() {
|
window.addEventListener("load", async function () {
|
||||||
loadProfile();
|
loadProfile();
|
||||||
});
|
});
|
||||||
|
|
||||||
async function loadProfile (){
|
async function loadProfile() {
|
||||||
|
|
||||||
const idToDisplay = new URLSearchParams(window.location.search).get('id');
|
const idToDisplay = new URLSearchParams(window.location.search).get('id');
|
||||||
let response;
|
let response;
|
||||||
|
|
||||||
// Retrieving the logged in user's profile
|
// Retrieving the logged in user's profile
|
||||||
if(!idToDisplay || idToDisplay === 'myself'){
|
if (!idToDisplay || idToDisplay === 'myself') {
|
||||||
document.getElementById('editBadge').style.display = 'block'; // show edit button
|
document.getElementById('editBadge').style.display = 'block'; // show edit button
|
||||||
const token = getCookie('token');
|
const token = getCookie('token');
|
||||||
// Check whether the token exists
|
// Check whether the token exists
|
||||||
if(!token){
|
if (!token) {
|
||||||
window.location.href = 'login.html';
|
window.location.href = 'login.html';
|
||||||
}
|
}
|
||||||
response = await fetch(`${API_URL}/person/myself`, {
|
response = await fetch(`${API_URL}/person/myself`, {
|
||||||
@ -69,8 +71,7 @@
|
|||||||
"authorization": token
|
"authorization": token
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
response = await fetch(`${API_URL}/person/${idToDisplay}/details`, {
|
response = await fetch(`${API_URL}/person/${idToDisplay}/details`, {
|
||||||
headers: {
|
headers: {
|
||||||
"Content-type": "application/json; charset=UTF-8",
|
"Content-type": "application/json; charset=UTF-8",
|
||||||
@ -79,19 +80,17 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
const data = await response.json();
|
const data = await response.json();
|
||||||
if (response.ok){
|
if (response.ok) {
|
||||||
populateFields(data.display_name, data.email, data.about_me, data.qualification);
|
populateFields(data.display_name, data.email, data.about_me, data.qualification);
|
||||||
document.body.style.display = 'block'; // Show page
|
document.body.style.display = 'block'; // Show page
|
||||||
}
|
} else if (response.status == 401) {
|
||||||
else if (response.status == 401){
|
|
||||||
window.location.href = 'login.html';
|
window.location.href = 'login.html';
|
||||||
}
|
} else {
|
||||||
else{
|
|
||||||
alert(`Unable to load profile. Error: ${data.error}`);
|
alert(`Unable to load profile. Error: ${data.error}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function populateFields (displayName, email, aboutMe, qualification) {
|
function populateFields(displayName, email, aboutMe, qualification) {
|
||||||
document.getElementById('displayName').textContent = displayName;
|
document.getElementById('displayName').textContent = displayName;
|
||||||
document.title = `${displayName} - Blink`
|
document.title = `${displayName} - Blink`
|
||||||
document.getElementById('email').textContent = email;
|
document.getElementById('email').textContent = email;
|
||||||
@ -99,12 +98,11 @@
|
|||||||
document.getElementById('qualification').textContent = qualification;
|
document.getElementById('qualification').textContent = qualification;
|
||||||
}
|
}
|
||||||
|
|
||||||
function editProfile () {
|
function editProfile() {
|
||||||
alert('Editing');
|
alert('Editing');
|
||||||
}
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
|
||||||
|
|
||||||
|
</html>
|
@ -1 +1 @@
|
|||||||
const API_URL = 'http://localhost:3000/api';
|
const API_URL = 'http://localhost:3000/api';
|
Loading…
x
Reference in New Issue
Block a user