mirror of
https://github.com/xfarrow/blink
synced 2025-06-27 09:03:02 +02:00
person ok
This commit is contained in:
@ -1,110 +0,0 @@
|
||||
/*
|
||||
This code is part of Blink
|
||||
licensed under GPLv3
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/******************************************************************************
|
||||
* ⚠ WARNING ⚠
|
||||
*
|
||||
*
|
||||
* Posts are now scheduled to be developed at a later stage in the development
|
||||
* process, with the possibility that it may not be developed at all.
|
||||
* I am unsure whether it is a good thing or it'll only be used to
|
||||
* flood timelines with low-effort content, like other competing platforms.
|
||||
*
|
||||
*
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
const knex = require('../utils/knex_config');
|
||||
|
||||
/**
|
||||
* Create OrganizationPost object
|
||||
* @param {*} organizationId
|
||||
* @param {*} content
|
||||
* @param {*} originalAuthor
|
||||
*/
|
||||
function createOrganizationPost(organizationId, content, originalAuthor) {
|
||||
const organizationPost = {
|
||||
organization_id: organizationId,
|
||||
content,
|
||||
original_author: originalAuthor
|
||||
};
|
||||
return organizationPost;
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert an OrganizationPost if and only if the author is
|
||||
* one of the Organization's administrators.
|
||||
* @param {*} organization
|
||||
* @returns the inserted OrganizationPost
|
||||
*/
|
||||
async function insertOrganizationPost(organization) {
|
||||
const isOrganizationAdmin = await knex('OrganizationAdministrator')
|
||||
.where('id_person', organization.original_author)
|
||||
.where('id_organization', organization.organization_id)
|
||||
.select('*')
|
||||
.first();
|
||||
|
||||
// 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 false;
|
||||
}
|
||||
|
||||
const organizationPost = await knex('OrganizationPost')
|
||||
.insert({
|
||||
organization_id: organization.organization_id,
|
||||
content: organization.content,
|
||||
original_author: organization.original_author
|
||||
})
|
||||
.returning('*');
|
||||
|
||||
return organizationPost[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the specified Person is an Organization Administrator
|
||||
* of the Organization the Post belongs to.
|
||||
* @param {*} postId
|
||||
* @param {*} personId
|
||||
* @returns true or false
|
||||
*/
|
||||
async function isPersonPostAdministrator(postId, personId) {
|
||||
return await knex('OrganizationPost')
|
||||
.join('OrganizationAdministrator', 'OrganizationPost.organization_id', 'OrganizationAdministrator.id_organization')
|
||||
.where('OrganizationPost.id', postId)
|
||||
.where('OrganizationAdministrator.id_person', personId)
|
||||
.select('*')
|
||||
.first();
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes the specified OrganizationPost if the requester is one
|
||||
* of the Administrators of the Organization the Post belongs to
|
||||
* @param {*} postId Id of the Post to delete
|
||||
* @param {*} requester Id of the Person requesting the deletion
|
||||
*/
|
||||
async function deleteOrganizationPost(postId, requester) {
|
||||
if (await isPersonPostAdministrator(postId, requester)) {
|
||||
return await knex('OrganizationPost')
|
||||
.where('id', postId)
|
||||
.del() == 1;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
createOrganizationPost,
|
||||
insertOrganizationPost,
|
||||
isPersonPostAdministrator,
|
||||
deleteOrganizationPost
|
||||
};
|
@ -25,17 +25,18 @@ const bcrypt = require('bcrypt');
|
||||
* @param {*} placeOfLiving
|
||||
* @returns
|
||||
*/
|
||||
function createPerson(email, password, displayName, dateOfBirth, available, enabled, placeOfLiving, aboutMe, qualification) {
|
||||
function createPerson(email, password, displayName, dateOfBirth, placeOfLiving, aboutMe, qualification, openToWork, enabled) {
|
||||
const person = {
|
||||
email: email.toLowerCase(),
|
||||
password,
|
||||
display_name: displayName,
|
||||
date_of_birth: dateOfBirth,
|
||||
available,
|
||||
enabled,
|
||||
open_to_work: openToWork,
|
||||
place_of_living: placeOfLiving,
|
||||
about_me: aboutMe,
|
||||
qualification
|
||||
qualification,
|
||||
enabled,
|
||||
visibility: "EVERYONE"
|
||||
};
|
||||
return person;
|
||||
}
|
||||
@ -80,12 +81,12 @@ async function insert(person, activationLink) {
|
||||
const insertedPerson = await tr('Person')
|
||||
.insert(person)
|
||||
.returning('*');
|
||||
if(activationLink != null){
|
||||
if (activationLink != null) {
|
||||
await tr('ActivationLink')
|
||||
.insert({
|
||||
person_id: insertedPerson[0].id,
|
||||
identifier: activationLink
|
||||
});
|
||||
.insert({
|
||||
person_id: insertedPerson[0].id,
|
||||
identifier: activationLink
|
||||
});
|
||||
}
|
||||
return insertedPerson[0];
|
||||
});
|
||||
|
@ -1,106 +0,0 @@
|
||||
/*
|
||||
This code is part of Blink
|
||||
licensed under GPLv3
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/******************************************************************************
|
||||
* ⚠ WARNING ⚠
|
||||
*
|
||||
*
|
||||
* Posts are now scheduled to be developed at a later stage in the development
|
||||
* process, with the possibility that it may not be developed at all.
|
||||
* I am unsure whether it is a good thing or it'll only be used to
|
||||
* flood timelines with low-effort content, like other competing platforms.
|
||||
*
|
||||
*
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
const organizationPostModel = require('../models/organization_post_model');
|
||||
const express = require('express');
|
||||
const jwtUtils = require('../utils/jwt_utils');
|
||||
|
||||
/**
|
||||
* POST Request
|
||||
*
|
||||
* Creates a Post belonging to an organization
|
||||
*
|
||||
* Required field(s): organization_id, content
|
||||
* @returns the inserted Post
|
||||
*/
|
||||
async function createOrganizationPost(req, res) {
|
||||
// Ensure that the required fields are present before proceeding
|
||||
if (!req.params.idOrganization || !req.body.content) {
|
||||
return res.status(400).json({
|
||||
error: 'Invalid request'
|
||||
});
|
||||
}
|
||||
|
||||
const organizationPost = organizationPostModel.createOrganizationPost(
|
||||
req.params.idOrganization,
|
||||
req.body.content,
|
||||
req.jwt.person_id);
|
||||
|
||||
try {
|
||||
const insertedOrganization = await organizationPostModel.insertOrganizationPost(organizationPost);
|
||||
if(!!insertedOrganization){
|
||||
return res.status(200).json(insertedOrganization);
|
||||
}
|
||||
return res.status(401).json({
|
||||
error: 'Forbidden'
|
||||
});
|
||||
} catch (error) {
|
||||
console.error(`Error in function ${createOrganizationPost.name}: ${error}`);
|
||||
return res.status(500).json({
|
||||
error: 'Internal server error'
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* DELETE Request
|
||||
*
|
||||
* Deletes a Post belonging to an Organization, only if
|
||||
* the logged user is an administrator of that Organization.
|
||||
*
|
||||
* Required field(s): none.
|
||||
*/
|
||||
async function deleteOrganizationPost(req, res) {
|
||||
try {
|
||||
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'
|
||||
});
|
||||
|
||||
} catch (error) {
|
||||
console.error(`Error in function ${deleteOrganizationPost.name}: ${error}`);
|
||||
res.status(500).json({
|
||||
error: 'Internal server error'
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const routes = express.Router();
|
||||
routes.post('/:idOrganization/posts', jwtUtils.extractToken, createOrganizationPost);
|
||||
routes.delete('/posts/:id', jwtUtils.extractToken, deleteOrganizationPost);
|
||||
|
||||
// Exporting a function
|
||||
// means making a JavaScript function defined in one
|
||||
// module available for use in another module.
|
||||
module.exports = {
|
||||
routes
|
||||
};
|
@ -16,7 +16,7 @@ const jwtUtils = require('../utils/jwt_utils');
|
||||
const bcrypt = require('bcrypt');
|
||||
const crypto = require('crypto');
|
||||
const Person = require('../models/person_model');
|
||||
const activationModel = require('../models/activation_model');
|
||||
const Activation = require('../models/activation_model');
|
||||
const express = require('express');
|
||||
const mailUtils = require('../utils/mail_utils');
|
||||
|
||||
@ -66,13 +66,14 @@ async function registerPerson(req, res) {
|
||||
const personToInsert = Person.createPerson(
|
||||
req.body.email,
|
||||
await hashPasswordPromise,
|
||||
req.body.display_name,
|
||||
req.body.date_of_birth,
|
||||
req.body.available,
|
||||
req.body.displayName,
|
||||
req.body.dateOfBirth,
|
||||
req.body.placeOfLiving,
|
||||
req.body.aboutMe,
|
||||
req.body.qualification,
|
||||
req.body.openToWork,
|
||||
isEnabled,
|
||||
req.body.place_of_living,
|
||||
req.body.about_me,
|
||||
req.body.qualification);
|
||||
);
|
||||
const insertedPerson = await Person.insert(personToInsert, activationCode);
|
||||
delete insertedPerson.password;
|
||||
|
||||
@ -190,8 +191,8 @@ async function getMyself(req, res) {
|
||||
* not present, they shall be ignored. An user can
|
||||
* only update themselves
|
||||
*
|
||||
* Required field(s): At least one. Both old_password and
|
||||
* new_password if updating the password.
|
||||
* Required field(s): At least one. Both oldPassword and
|
||||
* newPassword if updating the password.
|
||||
*
|
||||
*/
|
||||
async function updatePerson(req, res) {
|
||||
@ -205,46 +206,50 @@ async function updatePerson(req, res) {
|
||||
|
||||
const updatePerson = {};
|
||||
|
||||
if (req.body.display_name !== undefined) {
|
||||
updatePerson.display_name = req.body.display_name;
|
||||
if (req.body.displayName !== undefined) {
|
||||
updatePerson.display_name = req.body.displayName;
|
||||
}
|
||||
|
||||
if (req.body.date_of_birth !== undefined) {
|
||||
updatePerson.date_of_birth = req.body.date_of_birth;
|
||||
if (req.body.dateOfBirth !== undefined) {
|
||||
updatePerson.date_of_birth = req.body.dateOfBirth;
|
||||
}
|
||||
|
||||
if (req.body.available !== undefined) {
|
||||
updatePerson.available = req.body.available;
|
||||
if (req.body.openToWork !== undefined) {
|
||||
updatePerson.open_to_work = req.body.openToWork;
|
||||
}
|
||||
|
||||
if (req.body.place_of_living !== undefined) {
|
||||
updatePerson.place_of_living = req.body.place_of_living;
|
||||
if (req.body.placeOfLiving !== undefined) {
|
||||
updatePerson.place_of_living = req.body.placeOfLiving;
|
||||
}
|
||||
|
||||
if (req.body.about_me !== undefined) {
|
||||
updatePerson.about_me = req.body.about_me;
|
||||
if (req.body.aboutMe !== undefined) {
|
||||
updatePerson.about_me = req.body.aboutMe;
|
||||
}
|
||||
|
||||
if (req.body.qualification !== undefined) {
|
||||
updatePerson.qualification = req.body.qualification;
|
||||
}
|
||||
|
||||
if (req.body.visibility !== undefined) {
|
||||
updatePerson.visibility = req.body.visibility;
|
||||
}
|
||||
|
||||
// If we are tying to change password, the old password must be provided
|
||||
if (req.body.old_password !== undefined || req.body.new_password !== undefined) {
|
||||
if (req.body.old_password === undefined) {
|
||||
if (req.body.oldPassword !== undefined || req.body.newPassword !== undefined) {
|
||||
if (req.body.oldPassword === undefined) {
|
||||
return res.status(401).json({
|
||||
error: 'The old password must be specified'
|
||||
});
|
||||
}
|
||||
if (req.body.new_password === undefined) {
|
||||
if (req.body.newPassword === undefined) {
|
||||
return res.status(401).json({
|
||||
error: 'The new password must be specified'
|
||||
});
|
||||
}
|
||||
const user = await Person.findById(req.jwt.person_id);
|
||||
const passwordMatches = await bcrypt.compare(req.body.old_password, user.password);
|
||||
const passwordMatches = await bcrypt.compare(req.body.oldPassword, user.password);
|
||||
if (passwordMatches) {
|
||||
updatePerson.password = await bcrypt.hash(req.body.new_password, 10);
|
||||
updatePerson.password = await bcrypt.hash(req.body.newPassword, 10);
|
||||
} else {
|
||||
return res.status(401).json({
|
||||
error: 'Password verification failed'
|
||||
@ -306,7 +311,7 @@ async function confirmActivation(req, res) {
|
||||
errors: errors.array()
|
||||
});
|
||||
}
|
||||
const personId = await activationModel.getPersonIdByIdentifier(req.body.code);
|
||||
const personId = await Activation.getPersonIdByIdentifier(req.body.code);
|
||||
if (!personId) {
|
||||
return res.status(401).json({
|
||||
error: 'Activation Link either not valid or expired'
|
||||
|
@ -17,7 +17,7 @@ const {
|
||||
} = require("express-validator"); // This is the destructuring part. It specifies which properties of the imported object (express-validator) you want to extract.
|
||||
|
||||
const registerValidator = [
|
||||
check('display_name').trim().notEmpty().escape().isLength({
|
||||
check('displayName').trim().notEmpty().escape().isLength({
|
||||
max: 128
|
||||
}),
|
||||
check('email').isEmail().normalizeEmail().escape().isLength({
|
||||
@ -26,12 +26,12 @@ const registerValidator = [
|
||||
check('password').isLength({
|
||||
min: 5
|
||||
}).trim().escape().withMessage('Password must be at least 5 characters'),
|
||||
check('date_of_birth').optional().isDate().withMessage('Invalid date format. Date must be YYYY-MM-DD'),
|
||||
check('available').optional().isBoolean(),
|
||||
check('place_of_living').isLength({
|
||||
check('dateOfBirth').optional().isDate().withMessage('Invalid date format. Date must be YYYY-MM-DD'),
|
||||
check('openToWork').optional().isBoolean(),
|
||||
check('placeOfLiving').isLength({
|
||||
max: 128
|
||||
}).escape(),
|
||||
check('about_me').isLength({
|
||||
check('aboutMe').isLength({
|
||||
max: 4096
|
||||
}).escape(),
|
||||
check('qualification').isLength({
|
||||
@ -45,15 +45,15 @@ const getTokenValidator = [
|
||||
];
|
||||
|
||||
const updatePersonValidator = [
|
||||
check('display_name').trim().escape().isLength({
|
||||
check('displayName').trim().escape().isLength({
|
||||
max: 128
|
||||
}),
|
||||
check('date_of_birth').optional().isDate().withMessage('Invalid date format. Date must be YYYY-MM-DD'),
|
||||
check('available').optional().isBoolean(),
|
||||
check('place_of_living').isLength({
|
||||
check('dateOfBirth').optional().isDate().withMessage('Invalid date format. Date must be YYYY-MM-DD'),
|
||||
check('openToWork').optional().isBoolean(),
|
||||
check('placeOfLiving').isLength({
|
||||
max: 128
|
||||
}).escape(),
|
||||
check('about_me').isLength({
|
||||
check('aboutMe').isLength({
|
||||
max: 4096
|
||||
}).escape(),
|
||||
check('qualification').isLength({
|
||||
|
Reference in New Issue
Block a user