mirror of
https://github.com/xfarrow/blink
synced 2025-04-23 18:17:22 +02:00
Create person_model.js
This commit is contained in:
parent
bcf54f23be
commit
cfdac4872e
@ -0,0 +1,144 @@
|
|||||||
|
/*
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
const knex = require('../utils/knex_config');
|
||||||
|
const bcrypt = require('bcrypt');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates Person object by the specified fields
|
||||||
|
* @param {*} email
|
||||||
|
* @param {*} password
|
||||||
|
* @param {*} display_name
|
||||||
|
* @param {*} date_of_birth
|
||||||
|
* @param {*} available
|
||||||
|
* @param {*} enabled
|
||||||
|
* @param {*} place_of_living
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
function createPerson(email, password, display_name, date_of_birth, available, enabled, place_of_living) {
|
||||||
|
const person = {
|
||||||
|
email: email,
|
||||||
|
password: password,
|
||||||
|
display_name: display_name,
|
||||||
|
date_of_birth: date_of_birth,
|
||||||
|
available: available,
|
||||||
|
enabled: enabled,
|
||||||
|
place_of_living: place_of_living
|
||||||
|
};
|
||||||
|
return person;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the Person specified by their e-mail
|
||||||
|
* @param {*} email email to look the Person for
|
||||||
|
* @returns the Person object
|
||||||
|
*/
|
||||||
|
async function getPersonByEmail(email){
|
||||||
|
return await knex('Person')
|
||||||
|
.where('email', email)
|
||||||
|
.first();
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getPersonById(id){
|
||||||
|
return await knex('Person')
|
||||||
|
.select('*')
|
||||||
|
.where({ id: id })
|
||||||
|
.first();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers a Person by inserting in the database, in a transaction,
|
||||||
|
* both in the "Person" and in the "ActivationLink" tables.
|
||||||
|
* @param {*} person A Person object
|
||||||
|
* @param {*} activationLink the activationLink identifier
|
||||||
|
*/
|
||||||
|
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) => {
|
||||||
|
const personIdResult = await tr('Person')
|
||||||
|
.insert({
|
||||||
|
email: person.email,
|
||||||
|
password: person.password,
|
||||||
|
display_name: person.display_name,
|
||||||
|
date_of_birth: person.date_of_birth,
|
||||||
|
available: person.available,
|
||||||
|
enabled: person.enabled,
|
||||||
|
place_of_living: person.place_of_living
|
||||||
|
})
|
||||||
|
.returning("id");
|
||||||
|
await tr('ActivationLink')
|
||||||
|
.insert({
|
||||||
|
person_id: personIdResult[0].id,
|
||||||
|
identifier: activationLink
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a Person by specifying email and password.
|
||||||
|
* Used for log-in
|
||||||
|
* @param {*} email
|
||||||
|
* @param {*} password
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
async function getPersonByEmailAndPassword(email, password){
|
||||||
|
const person = await knex('Person')
|
||||||
|
.where('email', email)
|
||||||
|
.where('enabled', true)
|
||||||
|
.select('*')
|
||||||
|
.first();
|
||||||
|
|
||||||
|
if(person){
|
||||||
|
const passwordMatches = await bcrypt.compare(password, person.password);
|
||||||
|
if (passwordMatches) {
|
||||||
|
return person;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update a Person
|
||||||
|
* @param {*} person The Person to update
|
||||||
|
* @param {*} person_id The database id of the Person to update
|
||||||
|
*/
|
||||||
|
async function updatePerson(person, person_id){
|
||||||
|
await knex('Person')
|
||||||
|
.where('id', person_id)
|
||||||
|
.update(person);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes a Person specified by its database id.
|
||||||
|
* @param {*} person_id
|
||||||
|
*/
|
||||||
|
async function deletePerson(person_id){
|
||||||
|
await knex('Person')
|
||||||
|
.where({id : person_id})
|
||||||
|
.del();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Exporting a function
|
||||||
|
// means making a JavaScript function defined in one
|
||||||
|
// module available for use in another module.
|
||||||
|
module.exports = {
|
||||||
|
createPerson,
|
||||||
|
getPersonByEmail,
|
||||||
|
getPersonById,
|
||||||
|
getPersonByEmailAndPassword,
|
||||||
|
registerPerson,
|
||||||
|
updatePerson,
|
||||||
|
deletePerson
|
||||||
|
};
|
@ -16,6 +16,7 @@ const knex = require('../utils/knex_config');
|
|||||||
const jwt_utils = require('../utils/jwt_utils');
|
const jwt_utils = require('../utils/jwt_utils');
|
||||||
const bcrypt = require('bcrypt');
|
const bcrypt = require('bcrypt');
|
||||||
const crypto = require('crypto');
|
const crypto = require('crypto');
|
||||||
|
const person_model = require('../models/person_model');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* POST Request
|
* POST Request
|
||||||
@ -28,58 +29,38 @@ const crypto = require('crypto');
|
|||||||
*/
|
*/
|
||||||
async function registerPerson(req, res){
|
async function registerPerson(req, res){
|
||||||
|
|
||||||
|
// 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
|
||||||
const activationLink = crypto.randomBytes(16).toString('hex');
|
const activationLink = crypto.randomBytes(16).toString('hex');
|
||||||
|
|
||||||
// Hash provided password
|
// Hash provided password
|
||||||
const hashPasswordPromise = bcrypt.hash(req.body.password, 10);
|
const hashPasswordPromise = bcrypt.hash(req.body.password, 10);
|
||||||
|
|
||||||
try{
|
try{
|
||||||
|
|
||||||
// Check whether e-mail exists already (enforced by database constraints)
|
// Check whether e-mail exists already (enforced by database constraints)
|
||||||
const existingUser = await knex('Person')
|
const existingUser = await person_model.getPersonByEmail(req.body.email);
|
||||||
.where('email', req.body.email)
|
|
||||||
.first();
|
|
||||||
|
|
||||||
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 = person_model.createPerson(
|
||||||
// We need to insert either both in the "Person" table
|
req.body.email,
|
||||||
// and in the "ActivationLink" one, or in neither
|
await hashPasswordPromise,
|
||||||
await knex.transaction(async (tr) => {
|
req.body.display_name,
|
||||||
|
req.body.date_of_birth,
|
||||||
const personIdResult = await tr('Person')
|
req.body.available,
|
||||||
.insert({
|
true,
|
||||||
email: req.body.email,
|
req.body.place_of_living);
|
||||||
password: await hashPasswordPromise,
|
await person_model.registerPerson(personToInsert, activationLink);
|
||||||
display_name: req.body.display_name,
|
|
||||||
date_of_birth: req.body.date_of_birth,
|
|
||||||
available: req.body.available,
|
|
||||||
enabled: true,
|
|
||||||
place_of_living: req.body.place_of_living
|
|
||||||
})
|
|
||||||
.returning("id");
|
|
||||||
|
|
||||||
await tr('ActivationLink')
|
|
||||||
.insert({
|
|
||||||
person_id: personIdResult[0].id,
|
|
||||||
identifier: activationLink
|
|
||||||
});
|
|
||||||
});
|
|
||||||
return res.status(200).json({ activationLink: activationLink });
|
return res.status(200).json({ activationLink: activationLink });
|
||||||
}
|
}
|
||||||
catch (error){
|
catch (error){
|
||||||
@ -105,8 +86,8 @@ async function login(req, res){
|
|||||||
return res.status(400).json({error : "Invalid request"});
|
return res.status(400).json({error : "Invalid request"});
|
||||||
}
|
}
|
||||||
|
|
||||||
const person = await checkUserCredentials(req.body.email, req.body.password);
|
try{
|
||||||
|
const person = await person_model.getPersonByEmailAndPassword(req.body.email, req.body.password);
|
||||||
if (person){
|
if (person){
|
||||||
const token = jwt_utils.generateToken(person.id);
|
const token = jwt_utils.generateToken(person.id);
|
||||||
res.status(200).json({token: token });
|
res.status(200).json({token: token });
|
||||||
@ -114,6 +95,10 @@ async function login(req, res){
|
|||||||
else{
|
else{
|
||||||
res.status(401).json({error : "Unauthorized"});
|
res.status(401).json({error : "Unauthorized"});
|
||||||
}
|
}
|
||||||
|
} catch(error){
|
||||||
|
console.error('Error logging in: ', error);
|
||||||
|
res.status(500).json({error : "Internal server error"});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -127,16 +112,12 @@ async function login(req, res){
|
|||||||
*/
|
*/
|
||||||
async function getPerson(req, res){
|
async function getPerson(req, res){
|
||||||
try {
|
try {
|
||||||
const user = await knex('Person')
|
const person = await person_model.getPersonById(req.params.id);
|
||||||
.select('*')
|
if(person){
|
||||||
.where({ id: req.params.id })
|
|
||||||
.first();
|
|
||||||
|
|
||||||
if(user){
|
|
||||||
// I am retrieving either myself or an enabled user
|
// I am retrieving either myself or an enabled user
|
||||||
if(user.id == req.jwt.person_id || user.enabled){
|
if(person.id == req.jwt.person_id || person.enabled){
|
||||||
delete user['password']; // remove password field for security reasons
|
delete person['password']; // remove password field for security reasons
|
||||||
return res.status(200).send(user);
|
return res.status(200).send(person);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return res.status(404).json({error: "Not found"});
|
return res.status(404).json({error: "Not found"});
|
||||||
@ -157,13 +138,7 @@ async function getPerson(req, res){
|
|||||||
*/
|
*/
|
||||||
async function getMyself(req, res){
|
async function getMyself(req, res){
|
||||||
try{
|
try{
|
||||||
const person = await knex('Person')
|
const person = await person_model.getPersonById(req.jwt.person_id);
|
||||||
.select('*')
|
|
||||||
.where({ id: req.jwt.person_id })
|
|
||||||
.first();
|
|
||||||
|
|
||||||
console.log(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);
|
||||||
@ -235,9 +210,7 @@ async function updatePerson(req, res){
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await knex('Person')
|
await person_model.updatePerson(updatePerson, req.params.id);
|
||||||
.where('id', req.params.id)
|
|
||||||
.update(updatePerson);
|
|
||||||
return res.status(200).json({ success : "true"});
|
return res.status(200).json({ success : "true"});
|
||||||
}
|
}
|
||||||
catch (error) {
|
catch (error) {
|
||||||
@ -256,13 +229,10 @@ async function updatePerson(req, res){
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
async function deletePerson(req, res) {
|
async function deletePerson(req, res) {
|
||||||
try {
|
|
||||||
await knex('Person')
|
|
||||||
.where({id : req.jwt.person_id})
|
|
||||||
.del();
|
|
||||||
return res.status(200).json({success: true});
|
|
||||||
|
|
||||||
// TODO: Delete Organization if this user was its only administrator
|
// 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) {
|
catch (error) {
|
||||||
console.log("Error deleting a Person: " + error);
|
console.log("Error deleting a Person: " + error);
|
||||||
@ -270,28 +240,6 @@ async function deletePerson(req, res) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function checkUserCredentials(email, password){
|
|
||||||
try {
|
|
||||||
const user = await knex('Person')
|
|
||||||
.where('email', email)
|
|
||||||
.where('enabled', true)
|
|
||||||
.select('*')
|
|
||||||
.first();
|
|
||||||
|
|
||||||
if(user){
|
|
||||||
const passwordMatches = await bcrypt.compare(password, user.password);
|
|
||||||
if (passwordMatches) {
|
|
||||||
return user;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
catch (error) {
|
|
||||||
console.log(error);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Exporting a function
|
// Exporting a function
|
||||||
// means making a JavaScript function defined in one
|
// means making a JavaScript function defined in one
|
||||||
// module available for use in another module.
|
// module available for use in another module.
|
||||||
|
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 27 KiB |
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 9.6 KiB After Width: | Height: | Size: 9.6 KiB |
Loading…
x
Reference in New Issue
Block a user