mirror of
https://github.com/xfarrow/blink
synced 2025-06-27 09:03:02 +02:00
npx eslint --fix
This commit is contained in:
@ -20,10 +20,9 @@ const rateLimit = require('express-rate-limit');
|
||||
const personRoutes = require('./routes/person_routes.js');
|
||||
const organizationRoutes = require('./routes/organization_routes.js');
|
||||
const organizationAdminRoutes = require('./routes/organization_admin_routes.js');
|
||||
const organizationPostRoutes = require('./routes/organization_post_routes.js')
|
||||
const organizationPostRoutes = require('./routes/organization_post_routes.js');
|
||||
const jwt_utils = require('./utils/jwt_utils.js');
|
||||
|
||||
|
||||
// Application configuration
|
||||
const app = express();
|
||||
app.use(express.json()); // Middleware which parses JSON for POST requests
|
||||
@ -31,7 +30,7 @@ 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
|
||||
|
||||
const publicRoutes = express.Router();
|
||||
|
@ -20,7 +20,7 @@ const knex = require('../utils/knex_config');
|
||||
* @param {*} organizationId
|
||||
* @returns true if administrator, false otherwise
|
||||
*/
|
||||
async function isPersonAdmin(personId, organizationId){
|
||||
async function isPersonAdmin (personId, organizationId) {
|
||||
const isPersonAdmin = await knex('OrganizationAdministrator')
|
||||
.where('id_person', personId)
|
||||
.where('id_organization', organizationId)
|
||||
@ -34,7 +34,7 @@ async function isPersonAdmin(personId, organizationId){
|
||||
* @param {*} personId
|
||||
* @param {*} organizationId
|
||||
*/
|
||||
async function addOrganizationAdministrator(personId, organizationId){
|
||||
async function addOrganizationAdministrator (personId, organizationId) {
|
||||
await knex('OrganizationAdministrator')
|
||||
.insert({
|
||||
id_person: personId,
|
||||
@ -48,7 +48,7 @@ async function addOrganizationAdministrator(personId, organizationId){
|
||||
* @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
|
||||
@ -79,4 +79,4 @@ module.exports = {
|
||||
isPersonAdmin,
|
||||
addOrganizationAdministrator,
|
||||
removeOrganizationAdmin
|
||||
};
|
||||
};
|
||||
|
@ -21,12 +21,12 @@ const knex = require('../utils/knex_config');
|
||||
* @param {*} is_hiring
|
||||
* @returns
|
||||
*/
|
||||
function organization(name, location, description, is_hiring){
|
||||
function organization (name, location, description, is_hiring) {
|
||||
const organization = {
|
||||
name: name,
|
||||
location: location,
|
||||
description: description,
|
||||
is_hiring: is_hiring
|
||||
name,
|
||||
location,
|
||||
description,
|
||||
is_hiring
|
||||
};
|
||||
return organization;
|
||||
}
|
||||
@ -36,7 +36,7 @@ function organization(name, location, description, is_hiring){
|
||||
* @param {*} id
|
||||
* @returns
|
||||
*/
|
||||
async function getOrganizationById(id){
|
||||
async function getOrganizationById (id) {
|
||||
const organization = await knex('Organization')
|
||||
.where('id', id)
|
||||
.select('*')
|
||||
@ -48,7 +48,7 @@ async function getOrganizationById(id){
|
||||
* Insert an Organization and its relative Administrator
|
||||
* @param {*} organization
|
||||
*/
|
||||
async function insertOrganization(organization, organizationAdministratorId){
|
||||
async function insertOrganization (organization, organizationAdministratorId) {
|
||||
await knex.transaction(async (trx) => {
|
||||
// We have to insert either both in Organization and in OrganizationAdministrator
|
||||
// or in neither
|
||||
@ -59,7 +59,7 @@ async function insertOrganization(organization, organizationAdministratorId){
|
||||
await trx('OrganizationAdministrator')
|
||||
.insert({
|
||||
id_person: organizationAdministratorId,
|
||||
id_organization: organizationResult[0].id,
|
||||
id_organization: organizationResult[0].id
|
||||
});
|
||||
});
|
||||
}
|
||||
@ -72,7 +72,7 @@ async function insertOrganization(organization, organizationAdministratorId){
|
||||
* @param {*} personId
|
||||
* @returns true if the row was updated, false otherwise
|
||||
*/
|
||||
async function updateOrganizationIfAdministrator(organization, organizationId, personId){
|
||||
async function updateOrganizationIfAdministrator (organization, organizationId, personId) {
|
||||
// // const isOrganizationAdmin = await knex('OrganizationAdministrator')
|
||||
// // .where('id_person', req.jwt.person_id)
|
||||
// // .where('id_organization', req.params.id)
|
||||
@ -104,11 +104,11 @@ async function updateOrganizationIfAdministrator(organization, organizationId, p
|
||||
|
||||
const numberOfUpdatedRows = await knex('Organization')
|
||||
.where('id', organizationId)
|
||||
.whereExists(function(){
|
||||
.whereExists(function () {
|
||||
this.select('*')
|
||||
.from('OrganizationAdministrator')
|
||||
.where('id_person', personId)
|
||||
.where('id_organization', organizationId)
|
||||
.where('id_organization', organizationId);
|
||||
})
|
||||
.update(organization);
|
||||
return numberOfUpdatedRows == 1;
|
||||
@ -121,14 +121,14 @@ async function updateOrganizationIfAdministrator(organization, organizationId, p
|
||||
* @param {*} personId PersonId of the supposedly administrator
|
||||
* @returns true if the Organization was successfully deleted, false otherwise
|
||||
*/
|
||||
async function deleteOrganizationIfAdmin(organizationId, personId){
|
||||
async function deleteOrganizationIfAdmin (organizationId, personId) {
|
||||
const numberOfDeletedRows = await knex('Organization')
|
||||
.where({ id: organizationId })
|
||||
.whereExists(function(){
|
||||
.whereExists(function () {
|
||||
this.select('*')
|
||||
.from('OrganizationAdministrator')
|
||||
.where('id_person', personId)
|
||||
.where('id_organization', organizationId)
|
||||
.where('id_organization', organizationId);
|
||||
})
|
||||
.del();
|
||||
return numberOfDeletedRows == 1;
|
||||
|
@ -25,15 +25,15 @@ const bcrypt = require('bcrypt');
|
||||
* @param {*} place_of_living
|
||||
* @returns
|
||||
*/
|
||||
function person(email, password, display_name, date_of_birth, available, enabled, place_of_living) {
|
||||
function person (email, password, display_name, date_of_birth, available, enabled, place_of_living) {
|
||||
const person = {
|
||||
email: email.toLowerCase(),
|
||||
password: password,
|
||||
display_name: display_name,
|
||||
date_of_birth: date_of_birth,
|
||||
available: available,
|
||||
enabled: enabled,
|
||||
place_of_living: place_of_living
|
||||
password,
|
||||
display_name,
|
||||
date_of_birth,
|
||||
available,
|
||||
enabled,
|
||||
place_of_living
|
||||
};
|
||||
return person;
|
||||
}
|
||||
@ -43,7 +43,7 @@ function person(email, password, display_name, date_of_birth, available, enabled
|
||||
* @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();
|
||||
@ -54,10 +54,10 @@ 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: id })
|
||||
.where({ id })
|
||||
.first();
|
||||
}
|
||||
|
||||
@ -67,7 +67,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) => {
|
||||
@ -81,7 +81,7 @@ async function registerPerson(person, activationLink){
|
||||
enabled: person.enabled,
|
||||
place_of_living: person.place_of_living
|
||||
})
|
||||
.returning("id");
|
||||
.returning('id');
|
||||
await tr('ActivationLink')
|
||||
.insert({
|
||||
person_id: personIdResult[0].id,
|
||||
@ -97,14 +97,14 @@ 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)
|
||||
.select('*')
|
||||
.first();
|
||||
|
||||
if(person){
|
||||
if (person) {
|
||||
const passwordMatches = await bcrypt.compare(password, person.password);
|
||||
if (passwordMatches) {
|
||||
return person;
|
||||
@ -118,7 +118,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);
|
||||
@ -128,13 +128,12 @@ async function updatePerson(person, person_id){
|
||||
* Deletes a Person specified by its database id.
|
||||
* @param {*} person_id
|
||||
*/
|
||||
async function deletePerson(person_id){
|
||||
async function deletePerson (person_id) {
|
||||
await knex('Person')
|
||||
.where({id : person_id})
|
||||
.where({ id: person_id })
|
||||
.del();
|
||||
}
|
||||
|
||||
|
||||
// Exporting a function
|
||||
// means making a JavaScript function defined in one
|
||||
// module available for use in another module.
|
||||
|
@ -22,29 +22,27 @@ const organization_admin_model = require('../models/organization_admin_model');
|
||||
*
|
||||
* 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 isPersonAdmin = await organization_admin_model.isPersonAdmin(req.jwt.person_id, req.body.organization_id);
|
||||
// TOC/TOU
|
||||
if(!isPersonAdmin){
|
||||
return res.status(401).json({error : "Forbidden"});
|
||||
if (!isPersonAdmin) {
|
||||
return res.status(401).json({ error: 'Forbidden' });
|
||||
}
|
||||
await organization_admin_model.addOrganizationAdministrator(req.body.person_id, req.body.organization_id);
|
||||
return res.status(200).json({success : true});
|
||||
}
|
||||
catch (error) {
|
||||
return res.status(200).json({ success: true });
|
||||
} catch (error) {
|
||||
console.error('Error while adding organization admin: ' + 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.
|
||||
@ -53,20 +51,18 @@ async function addOrganizationAdmin(req, res){
|
||||
*
|
||||
* Required field(s): organization_id
|
||||
*/
|
||||
async function removeOrganizationAdmin(req, res){
|
||||
|
||||
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{
|
||||
try {
|
||||
await organization_admin_model.removeOrganizationAdmin(req.jwt.person_id, req.body.organization_id);
|
||||
return res.status(200).json({success : true});
|
||||
}
|
||||
catch (error){
|
||||
return res.status(200).json({ success: true });
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
return res.status(500).json({ error: "Internal server error"});
|
||||
return res.status(500).json({ error: 'Internal server error' });
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -21,11 +21,10 @@ const knex = require('../utils/knex_config');
|
||||
* Required field(s): organization_id, content
|
||||
* @returns the inserted Post
|
||||
*/
|
||||
async function createOrganizationPost(req, res){
|
||||
|
||||
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' });
|
||||
}
|
||||
|
||||
try {
|
||||
@ -38,8 +37,8 @@ async function createOrganizationPost(req, res){
|
||||
|
||||
// Non-exploitable TOC/TOU weakness
|
||||
// For more information https://softwareengineering.stackexchange.com/questions/451038/when-should-i-be-worried-of-time-of-check-time-of-use-vulnerabilities-during-dat
|
||||
if(!isOrganizationAdmin){
|
||||
return res.status(403).json({error : "Forbidden"});
|
||||
if (!isOrganizationAdmin) {
|
||||
return res.status(403).json({ error: 'Forbidden' });
|
||||
}
|
||||
|
||||
const organizationPost = await knex('OrganizationPost')
|
||||
@ -50,12 +49,11 @@ async function createOrganizationPost(req, res){
|
||||
})
|
||||
.returning('*');
|
||||
return res.status(200).json(organizationPost[0]);
|
||||
} catch (error) {
|
||||
console.log('Error while creating Organization Post: ' + error);
|
||||
return res.status(500).json({ error: 'Internal server error' });
|
||||
}
|
||||
catch (error) {
|
||||
console.log("Error while creating Organization Post: " + error);
|
||||
return res.status(500).json({error : "Internal server error"});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* DELETE Request
|
||||
@ -65,11 +63,10 @@ async function createOrganizationPost(req, res){
|
||||
*
|
||||
* Required field(s): none.
|
||||
*/
|
||||
async function deleteOrganizationPost(req, res){
|
||||
|
||||
async function deleteOrganizationPost (req, res) {
|
||||
const organizationPostIdToDelete = req.params.id;
|
||||
|
||||
try{
|
||||
try {
|
||||
const isOrganizationAdmin = await knex('OrganizationPost')
|
||||
.join('OrganizationAdministrator', 'OrganizationPost.organization_id', 'OrganizationAdministrator.id_organization')
|
||||
.where('OrganizationPost.id', organizationPostIdToDelete)
|
||||
@ -78,19 +75,17 @@ async function deleteOrganizationPost(req, res){
|
||||
.first();
|
||||
|
||||
// Unexploitable TOC/TOU
|
||||
if(isOrganizationAdmin){
|
||||
if (isOrganizationAdmin) {
|
||||
await knex('OrganizationPost')
|
||||
.where('id', organizationPostIdToDelete)
|
||||
.del();
|
||||
return res.status(200).json({success : true});
|
||||
return res.status(200).json({ success: true });
|
||||
} else {
|
||||
return res.status(401).json({ error: 'Forbidden' });
|
||||
}
|
||||
else{
|
||||
return res.status(401).json({error : "Forbidden"});
|
||||
}
|
||||
}
|
||||
catch (error) {
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
res.status(500).json({error : "Internal server error"});
|
||||
res.status(500).json({ error: 'Internal server error' });
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -22,21 +22,19 @@ const organization_model = require('../models/organization_model');
|
||||
*
|
||||
* @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{
|
||||
try {
|
||||
const organization = organization_model.organization(req.body.name, req.body.location, req.body.description, req.body.is_hiring);
|
||||
await organization_model.insertOrganization(organization, req.jwt.person_id);
|
||||
return res.status(200).json({ Organization: organization });
|
||||
}
|
||||
catch (error){
|
||||
} catch (error) {
|
||||
console.error('Error creating Organization:', error);
|
||||
res.status(500).json({error : "Internal server error"});
|
||||
res.status(500).json({ error: 'Internal server error' });
|
||||
}
|
||||
}
|
||||
|
||||
@ -46,42 +44,39 @@ 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){
|
||||
if (req.body.name) {
|
||||
updateOrganization.name = req.body.name;
|
||||
}
|
||||
|
||||
if(req.body.location){
|
||||
if (req.body.location) {
|
||||
updateOrganization.location = req.body.location;
|
||||
}
|
||||
|
||||
if(req.body.description){
|
||||
if (req.body.description) {
|
||||
updateOrganization.description = req.body.description;
|
||||
}
|
||||
|
||||
if(req.body.is_hiring){
|
||||
if (req.body.is_hiring) {
|
||||
updateOrganization.is_hiring = req.body.is_hiring;
|
||||
}
|
||||
|
||||
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 = organization_model.updateOrganizationIfAdministrator(updateOrganization, req.params.id, req.jwt.person_id);
|
||||
if(isUpdateSuccessful){
|
||||
return res.status(200).json({ success : "true"});
|
||||
if (isUpdateSuccessful) {
|
||||
return res.status(200).json({ success: 'true' });
|
||||
} else {
|
||||
return res.status(404).json({ error: 'Organization either not found or insufficient permissions' });
|
||||
}
|
||||
else{
|
||||
return res.status(404).json({error : "Organization either not found or insufficient permissions"});
|
||||
}
|
||||
}
|
||||
catch (error) {
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
return res.status(500).json({error : "Internal server error"});
|
||||
return res.status(500).json({ error: 'Internal server error' });
|
||||
}
|
||||
}
|
||||
|
||||
@ -91,19 +86,17 @@ 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 = organization_model.deleteOrganizationIfAdmin(req.params.id, req.jwt.person_id);
|
||||
if(isDeleteSuccessful){
|
||||
return res.status(403).json({error: "Forbidden"});
|
||||
if (isDeleteSuccessful) {
|
||||
return res.status(403).json({ error: 'Forbidden' });
|
||||
} else {
|
||||
return res.status(200).json({ success: true });
|
||||
}
|
||||
else{
|
||||
return res.status(200).json({success: true});
|
||||
}
|
||||
}
|
||||
catch (error) {
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
return res.status(500).json({error : "Internal server error"});
|
||||
return res.status(500).json({ error: 'Internal server error' });
|
||||
}
|
||||
}
|
||||
|
||||
@ -116,19 +109,17 @@ async function deleteOrganization(req, res){
|
||||
*
|
||||
* @returns the organization.
|
||||
*/
|
||||
async function getOrganization(req, res){
|
||||
async function getOrganization (req, res) {
|
||||
try {
|
||||
const organization = await organization_model.getOrganizationById(req.params.id);
|
||||
if(organization) {
|
||||
if (organization) {
|
||||
return res.status(200).json(organization);
|
||||
} else {
|
||||
return res.status(404).json({ error: 'Not found' });
|
||||
}
|
||||
else{
|
||||
return res.status(404).json({error : "Not found"});
|
||||
}
|
||||
}
|
||||
catch (error) {
|
||||
console.error("Error retrieving an organization: " + error);
|
||||
return res.status(500).json({error : "Internal server error"});
|
||||
} catch (error) {
|
||||
console.error('Error retrieving an organization: ' + error);
|
||||
return res.status(500).json({ error: 'Internal server error' });
|
||||
}
|
||||
}
|
||||
|
||||
@ -138,4 +129,3 @@ module.exports = {
|
||||
updateOrganization,
|
||||
deleteOrganization
|
||||
};
|
||||
|
||||
|
@ -27,18 +27,17 @@ const person_model = require('../models/person_model');
|
||||
*
|
||||
* @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"});
|
||||
if (process.env.ALLOW_USER_REGISTRATION === 'false') {
|
||||
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"});
|
||||
if (!validator.validateEmail(req.body.email)) {
|
||||
return res.status(400).json({ error: 'The email is not in a valid format' });
|
||||
}
|
||||
|
||||
// Generate activation link token
|
||||
@ -46,11 +45,11 @@ async function registerPerson(req, res){
|
||||
// Hash provided password
|
||||
const hashPasswordPromise = bcrypt.hash(req.body.password, 10);
|
||||
|
||||
try{
|
||||
try {
|
||||
// Check whether e-mail exists already (enforced by database constraints)
|
||||
const existingUser = await person_model.getPersonByEmail(req.body.email);
|
||||
if(existingUser){
|
||||
return res.status(409).json({ error: "E-mail already in use" });
|
||||
if (existingUser) {
|
||||
return res.status(409).json({ error: 'E-mail already in use' });
|
||||
}
|
||||
const personToInsert = person_model.person(
|
||||
req.body.email,
|
||||
@ -61,11 +60,10 @@ async function registerPerson(req, res){
|
||||
true,
|
||||
req.body.place_of_living);
|
||||
await person_model.registerPerson(personToInsert, activationLink);
|
||||
return res.status(200).json({ activationLink: activationLink });
|
||||
}
|
||||
catch (error){
|
||||
return res.status(200).json({ activationLink });
|
||||
} catch (error) {
|
||||
console.error('Error registering person:', error);
|
||||
res.status(500).json({error : "Internal server error"});
|
||||
res.status(500).json({ error: 'Internal server error' });
|
||||
}
|
||||
}
|
||||
|
||||
@ -79,25 +77,23 @@ 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{
|
||||
try {
|
||||
const person = await person_model.getPersonByEmailAndPassword(req.body.email, req.body.password);
|
||||
if (person){
|
||||
if (person) {
|
||||
const token = jwt_utils.generateToken(person.id);
|
||||
res.status(200).json({token: token });
|
||||
res.status(200).json({ token });
|
||||
} else {
|
||||
res.status(401).json({ error: 'Unauthorized' });
|
||||
}
|
||||
else{
|
||||
res.status(401).json({error : "Unauthorized"});
|
||||
}
|
||||
} catch(error){
|
||||
} catch (error) {
|
||||
console.error('Error logging in: ', error);
|
||||
res.status(500).json({error : "Internal server error"});
|
||||
res.status(500).json({ error: 'Internal server error' });
|
||||
}
|
||||
}
|
||||
|
||||
@ -110,21 +106,20 @@ async function login(req, res){
|
||||
*
|
||||
* @returns The Person
|
||||
*/
|
||||
async function getPerson(req, res){
|
||||
async function getPerson (req, res) {
|
||||
try {
|
||||
const person = await person_model.getPersonById(req.params.id);
|
||||
if(person){
|
||||
if (person) {
|
||||
// I am retrieving either myself or an enabled user
|
||||
if(person.id == req.jwt.person_id || person.enabled){
|
||||
delete person['password']; // remove password field for security reasons
|
||||
if (person.id == req.jwt.person_id || 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"});
|
||||
}
|
||||
catch (error) {
|
||||
console.log("Error while getting person: " + error);
|
||||
return res.status(500).json({error : "Internal server error"});
|
||||
return res.status(404).json({ error: 'Not found' });
|
||||
} catch (error) {
|
||||
console.log('Error while getting person: ' + error);
|
||||
return res.status(500).json({ error: 'Internal server error' });
|
||||
}
|
||||
}
|
||||
|
||||
@ -136,18 +131,17 @@ async function getPerson(req, res){
|
||||
*
|
||||
* @returns Person's details
|
||||
*/
|
||||
async function getMyself(req, res){
|
||||
try{
|
||||
async function getMyself (req, res) {
|
||||
try {
|
||||
const person = await person_model.getPersonById(req.jwt.person_id);
|
||||
if(person){
|
||||
delete person['password'];
|
||||
if (person) {
|
||||
delete person.password;
|
||||
return res.status(200).send(person);
|
||||
}
|
||||
return res.status(404).json({error: "Not found"});
|
||||
}
|
||||
catch (error){
|
||||
console.log("Error while getting myself: " + error);
|
||||
return res.status(500).json({error : "Internal server error"});
|
||||
return res.status(404).json({ error: 'Not found' });
|
||||
} catch (error) {
|
||||
console.log('Error while getting myself: ' + error);
|
||||
return res.status(500).json({ error: 'Internal server error' });
|
||||
}
|
||||
}
|
||||
|
||||
@ -161,61 +155,57 @@ async function getMyself(req, res){
|
||||
* new_password if updating the password.
|
||||
*
|
||||
*/
|
||||
async function updatePerson(req, res){
|
||||
|
||||
if (req.jwt.person_id != req.params.id){
|
||||
return res.status(403).json({ error : "Forbidden"});
|
||||
async function updatePerson (req, res) {
|
||||
if (req.jwt.person_id != req.params.id) {
|
||||
return res.status(403).json({ error: 'Forbidden' });
|
||||
}
|
||||
|
||||
const updatePerson = {};
|
||||
|
||||
if(req.body.display_name){
|
||||
if (req.body.display_name) {
|
||||
updatePerson.display_name = req.body.display_name;
|
||||
}
|
||||
|
||||
if(req.body.date_of_birth){
|
||||
if(validator.isPostgresDateFormatValid(req.body.date_of_birth)){
|
||||
if (req.body.date_of_birth) {
|
||||
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"});
|
||||
} else {
|
||||
return res.status(400).json({ error: 'Date of birth format not valid. Please specify a YYYY-MM-DD date' });
|
||||
}
|
||||
}
|
||||
|
||||
if(req.body.available){
|
||||
if (req.body.available) {
|
||||
updatePerson.available = req.body.available;
|
||||
}
|
||||
|
||||
if(req.body.place_of_living){
|
||||
if (req.body.place_of_living) {
|
||||
updatePerson.place_of_living = req.body.place_of_living;
|
||||
}
|
||||
|
||||
// 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) {
|
||||
const user = await knex('Person')
|
||||
.select('password')
|
||||
.where({ id: req.jwt.person_id })
|
||||
.first();
|
||||
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);
|
||||
}
|
||||
else{
|
||||
return res.status(401).json({ error : "Password verification failed"});
|
||||
} else {
|
||||
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 person_model.updatePerson(updatePerson, req.params.id);
|
||||
return res.status(200).json({ success : "true"});
|
||||
}
|
||||
catch (error) {
|
||||
console.log("Error while updating a Person: " + error);
|
||||
return res.status(500).json({ error : "Internal server error"});
|
||||
return res.status(200).json({ success: 'true' });
|
||||
} catch (error) {
|
||||
console.log('Error while updating a Person: ' + error);
|
||||
return res.status(500).json({ error: 'Internal server error' });
|
||||
}
|
||||
}
|
||||
|
||||
@ -228,15 +218,14 @@ 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 person_model.deletePerson(req.jwt.person_id);
|
||||
return res.status(200).json({success: true});
|
||||
}
|
||||
catch (error) {
|
||||
console.log("Error deleting a Person: " + error);
|
||||
return res.status(500).json({error : "Internal server error"});
|
||||
return res.status(200).json({ success: true });
|
||||
} catch (error) {
|
||||
console.log('Error deleting a Person: ' + error);
|
||||
return res.status(500).json({ error: 'Internal server error' });
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -13,29 +13,29 @@
|
||||
|
||||
const jwt = require('jsonwebtoken');
|
||||
|
||||
function generateToken(person_id) {
|
||||
function generateToken (person_id) {
|
||||
// The payload the JWT will carry within itself
|
||||
const payload = {
|
||||
person_id: person_id
|
||||
person_id
|
||||
};
|
||||
|
||||
const token = jwt.sign(payload, process.env.JWT_SECRET_KEY, {
|
||||
expiresIn: '8h'
|
||||
});
|
||||
return token;
|
||||
}
|
||||
}
|
||||
|
||||
// Middlware
|
||||
function verifyToken(req, res, next) {
|
||||
// Middlware
|
||||
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
|
||||
@ -43,9 +43,9 @@ function generateToken(person_id) {
|
||||
req.jwt = decoded;
|
||||
next();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
module.exports = {
|
||||
generateToken,
|
||||
verifyToken
|
||||
};
|
@ -20,6 +20,6 @@ const knexInstance = require('knex')({
|
||||
port: process.env.POSTGRES_PORT,
|
||||
database: 'Blink'
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
module.exports = knexInstance;
|
||||
module.exports = knexInstance;
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -9,10 +9,10 @@ describe('Person Tests', () => {
|
||||
const response = await request(app)
|
||||
.post('/api/register')
|
||||
.send({
|
||||
email : "johntestdoe@mail.org",
|
||||
password : "password",
|
||||
display_name : "John Doe"
|
||||
})
|
||||
email: 'johntestdoe@mail.org',
|
||||
password: 'password',
|
||||
display_name: 'John Doe'
|
||||
});
|
||||
expect(response.status).toBe(200);
|
||||
expect(response.body).toEqual({ activationLink: expect.any(String) });
|
||||
});
|
||||
@ -21,10 +21,10 @@ describe('Person Tests', () => {
|
||||
const response = await request(app)
|
||||
.post('/api/register')
|
||||
.send({
|
||||
email : "this is not an email",
|
||||
password : "password",
|
||||
display_name : "John Doe"
|
||||
})
|
||||
email: 'this is not an email',
|
||||
password: 'password',
|
||||
display_name: 'John Doe'
|
||||
});
|
||||
expect(response.status).toBe(400);
|
||||
});
|
||||
});
|
||||
|
@ -1 +1 @@
|
||||
const apiUrl = "http://localhost:3000/blinkapi";
|
||||
const apiUrl = 'http://localhost:3000/blinkapi';
|
||||
|
@ -1,30 +1,27 @@
|
||||
// https://javascript.info/callbacks
|
||||
|
||||
function execute_action(param, callback){
|
||||
|
||||
if(param == "something"){
|
||||
console.log("Executing action: " + param);
|
||||
function execute_action (param, callback) {
|
||||
if (param == 'something') {
|
||||
console.log('Executing action: ' + param);
|
||||
callback(null, Date.now());
|
||||
}
|
||||
else{
|
||||
} else {
|
||||
// We can call callback with one argument even if
|
||||
// the signature states two parameters
|
||||
callback(new Error("Invalid parameter"))
|
||||
callback(new Error('Invalid parameter'));
|
||||
}
|
||||
}
|
||||
|
||||
function entryPoint(){
|
||||
function entryPoint () {
|
||||
/* ===== Begin Simple callback ===== */
|
||||
|
||||
execute_action("something", function (error, time_of_completion){
|
||||
if(error){
|
||||
console.log("Something happened");
|
||||
}
|
||||
else{
|
||||
console.log("Time of completion: " + new Date(time_of_completion).toDateString());
|
||||
execute_action('something', function (error, time_of_completion) {
|
||||
if (error) {
|
||||
console.log('Something happened');
|
||||
} else {
|
||||
console.log('Time of completion: ' + new Date(time_of_completion).toDateString());
|
||||
}
|
||||
});
|
||||
console.log("I started here!");
|
||||
console.log('I started here!');
|
||||
/*
|
||||
Ciò è utile se ad esempio execute_action fa operazioni lente (ad esempio
|
||||
scrittura su database, connessioni HTTP ecc..) ma abbiamo bisogno
|
||||
|
@ -10,24 +10,24 @@
|
||||
|
||||
Remember that Promises are not intrensically asyncronous
|
||||
*/
|
||||
let promise = new Promise(function(resolve, reject) {
|
||||
setTimeout(() => resolve("done"), 500);
|
||||
});
|
||||
const promise = new Promise(function (resolve, reject) {
|
||||
setTimeout(() => resolve('done'), 500);
|
||||
});
|
||||
|
||||
/*
|
||||
The first argument of .then is a function that runs when the promise is resolved and receives the result.
|
||||
The second argument of .then is a function that runs when the promise is rejected and receives the error.
|
||||
*/
|
||||
promise.then(
|
||||
result => console.log("The operation was successful. It returned " + result),
|
||||
error => console.log("The operation was not successful: " + error)
|
||||
result => console.log('The operation was successful. It returned ' + result),
|
||||
error => console.log('The operation was not successful: ' + error)
|
||||
);
|
||||
|
||||
/*
|
||||
Or we can pass only one argument if we're interested only in a positive result
|
||||
*/
|
||||
promise.then(
|
||||
result => console.log("The operation was successful. It returned " + result)
|
||||
result => console.log('The operation was successful. It returned ' + result)
|
||||
);
|
||||
|
||||
/*
|
||||
@ -44,5 +44,5 @@ promise.catch(
|
||||
finally gets always called
|
||||
*/
|
||||
promise.finally(
|
||||
() => console.log("The execution has terminated. Bye")
|
||||
() => console.log('The execution has terminated. Bye')
|
||||
);
|
@ -3,26 +3,18 @@
|
||||
// .then() returns a new Promise when you do "return",
|
||||
// internally calling resolve().
|
||||
|
||||
new Promise(function(resolve, reject) {
|
||||
|
||||
new Promise(function (resolve, reject) {
|
||||
setTimeout(() => resolve(1), 1);
|
||||
|
||||
}).then(function(result) {
|
||||
|
||||
}).then(function (result) {
|
||||
console.log(result);
|
||||
return result * 2;
|
||||
|
||||
}).then(function(result) {
|
||||
|
||||
}).then(function (result) {
|
||||
console.log(result);
|
||||
return result * 2;
|
||||
|
||||
}).then(function(result) {
|
||||
|
||||
}).then(function (result) {
|
||||
console.log(result);
|
||||
return result * 2;
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
/*
|
||||
It will print
|
||||
@ -45,12 +37,12 @@ new Promise(function(resolve, reject) {
|
||||
|
||||
fetch('http://www.fsf.org')
|
||||
// .then below runs when the remote server responds
|
||||
.then(function(response) {
|
||||
.then(function (response) {
|
||||
// response.text() returns a new promise that resolves with the full response text
|
||||
// when it loads
|
||||
return response.text();
|
||||
})
|
||||
.then(function(text) {
|
||||
.then(function (text) {
|
||||
// ...and here's the content of the remote file
|
||||
console.log(text);
|
||||
});
|
@ -3,63 +3,62 @@
|
||||
// A async function always returns a promise. Other values are wrapped in a resolved promise automatically.
|
||||
// Async e Await sono solo "sintassi zuccherina" per rendere l'utilizzo delle Promise più semplice
|
||||
|
||||
async function f1() {
|
||||
async function f1 () {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
f1().then(console.log); // 1
|
||||
f1().then(console.log); // 1
|
||||
|
||||
// The keyword await makes JavaScript wait until that promise settles and returns its result.
|
||||
// It can be used in async functions only
|
||||
// Let’s emphasize: await literally suspends the function execution until the promise settles,
|
||||
// and then resumes it with the promise result.
|
||||
async function f2() {
|
||||
|
||||
let promise = new Promise((resolve, reject) => {
|
||||
setTimeout(() => resolve("done!"), 1000)
|
||||
async function f2 () {
|
||||
const promise = new Promise((resolve, reject) => {
|
||||
setTimeout(() => resolve('done!'), 1000);
|
||||
});
|
||||
|
||||
let result = await promise; // wait until the promise resolves (*)
|
||||
const result = await promise; // wait until the promise resolves (*)
|
||||
|
||||
console.log(result); // "done!"
|
||||
}
|
||||
|
||||
f2();
|
||||
f2();
|
||||
|
||||
// Tutto il codice nella stessa funzione (o nello stesso blocco di codice)
|
||||
// dopo "await" è da considerarsi nel "then()" di una promessa. Pertanto dopo
|
||||
// await (ma prima del completamento della Promise),
|
||||
// il flusso di esecuzione va fuori a quel blocco di codice. Ad esempio considera
|
||||
// il seguente esempio:
|
||||
async function exampleAsyncFunction() {
|
||||
// Tutto il codice nella stessa funzione (o nello stesso blocco di codice)
|
||||
// dopo "await" è da considerarsi nel "then()" di una promessa. Pertanto dopo
|
||||
// await (ma prima del completamento della Promise),
|
||||
// il flusso di esecuzione va fuori a quel blocco di codice. Ad esempio considera
|
||||
// il seguente esempio:
|
||||
async function exampleAsyncFunction () {
|
||||
console.log('Before await');
|
||||
await new Promise(function(resolve, reject) {
|
||||
setTimeout(() => resolve("done"), 500);
|
||||
await new Promise(function (resolve, reject) {
|
||||
setTimeout(() => resolve('done'), 500);
|
||||
}); // Pauses execution here until the promise resolves.
|
||||
console.log('After await');
|
||||
}
|
||||
}
|
||||
|
||||
console.log('Start');
|
||||
exampleAsyncFunction();
|
||||
console.log('End');
|
||||
console.log('Start');
|
||||
exampleAsyncFunction();
|
||||
console.log('End');
|
||||
|
||||
// Il risultato sarà:
|
||||
// Start, Before Await, End, After await
|
||||
// Viene prima "End" e poi "After Await", perché
|
||||
// dopo await, il flusso di esecuzione ritorna al
|
||||
// chiamante
|
||||
// Il risultato sarà:
|
||||
// Start, Before Await, End, After await
|
||||
// Viene prima "End" e poi "After Await", perché
|
||||
// dopo await, il flusso di esecuzione ritorna al
|
||||
// chiamante
|
||||
|
||||
// Domande
|
||||
//
|
||||
// Why await only works in async function in javascript?
|
||||
// https://stackoverflow.com/questions/49640647/why-await-only-works-in-async-function-in-javascript
|
||||
//
|
||||
// Why using async-await
|
||||
// https://stackoverflow.com/questions/42624647/why-use-async-when-i-have-to-use-await
|
||||
//
|
||||
// Si faccia presente che non è possibile creare da zero una funzione asincrona (come
|
||||
// setInterval o fetch)
|
||||
// https://stackoverflow.com/questions/61857274/how-to-create-custom-asynchronous-function-in-javascript
|
||||
//
|
||||
// Altra domanda interessante
|
||||
// https://stackoverflow.com/questions/42624647/why-use-async-when-i-have-to-use-await
|
||||
// Domande
|
||||
//
|
||||
// Why await only works in async function in javascript?
|
||||
// https://stackoverflow.com/questions/49640647/why-await-only-works-in-async-function-in-javascript
|
||||
//
|
||||
// Why using async-await
|
||||
// https://stackoverflow.com/questions/42624647/why-use-async-when-i-have-to-use-await
|
||||
//
|
||||
// Si faccia presente che non è possibile creare da zero una funzione asincrona (come
|
||||
// setInterval o fetch)
|
||||
// https://stackoverflow.com/questions/61857274/how-to-create-custom-asynchronous-function-in-javascript
|
||||
//
|
||||
// Altra domanda interessante
|
||||
// https://stackoverflow.com/questions/42624647/why-use-async-when-i-have-to-use-await
|
||||
|
@ -3,10 +3,10 @@
|
||||
The function delay(ms) should return a promise. That promise should resolve after ms milliseconds, so that we can add .then to it, like this:
|
||||
*/
|
||||
|
||||
function delay(ms){
|
||||
function delay (ms) {
|
||||
return new Promise(resolve => {
|
||||
setTimeout(resolve, ms);
|
||||
});
|
||||
}
|
||||
|
||||
delay(1000).then(() => console.log("Hello world!"));
|
||||
delay(1000).then(() => console.log('Hello world!'));
|
||||
|
Reference in New Issue
Block a user