feat: Adding observers/public/account
This commit is contained in:
14
v1/README.md
14
v1/README.md
@@ -482,3 +482,17 @@ __This endpoint is only valid for carriers.__
|
|||||||
- `PATCH /:id` : Updates data from specific element.
|
- `PATCH /:id` : Updates data from specific element.
|
||||||
- `DELETE /:id` : Delete element from company. Returns the element data.
|
- `DELETE /:id` : Delete element from company. Returns the element data.
|
||||||
- `GET /:id` : Get data from specific element.
|
- `GET /:id` : Get data from specific element.
|
||||||
|
|
||||||
|
## Observers endpoints
|
||||||
|
|
||||||
|
### observers/public/account/
|
||||||
|
|
||||||
|
The full endpoint is `observers/public/account/`, and serves for the account credentials management, the same way it works for the common users at the endpoint `/public/account`, by the process of creating an OTP when requesting a new user or recovering the account password.
|
||||||
|
|
||||||
|
- `POST /client/authorize` or `POST /warehouse/authorize`: Authorize the access to the user identified by email:password.
|
||||||
|
- `GET /client/authorize/:session_token` or `GET /warehouse/authorize/:session_token`: Authorize the access to the user identified by the session token.
|
||||||
|
- `POST /client/signup` or `POST /warehouse/signup`: Requests an OTP to create a new account.
|
||||||
|
- `PATCH /client/signup` or `PATCH /warehouse/signup`: Confirms the account OTP.
|
||||||
|
- `POST /client/recover` or `POST /warehouse/recover`: Requests an OTP recover the account password.
|
||||||
|
- `PATCH /client/recover` or `PATCH /warehouse/recover`: Confirms the new password OTP.
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,9 @@ const app = express();
|
|||||||
|
|
||||||
const private = require('./private');
|
const private = require('./private');
|
||||||
const public = require('./public');
|
const public = require('./public');
|
||||||
|
const observers = require('./observers');
|
||||||
|
|
||||||
|
app.use( '/api/v1/observers/', observers );
|
||||||
app.use( '/api/v1/', public );
|
app.use( '/api/v1/', public );
|
||||||
app.use( '/api/v1/', private );
|
app.use( '/api/v1/', private );
|
||||||
|
|
||||||
|
|||||||
10
v1/src/apps/observers/index.js
Normal file
10
v1/src/apps/observers/index.js
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
const express = require('express');
|
||||||
|
const app = express();
|
||||||
|
|
||||||
|
const public = require('./public');
|
||||||
|
const private = require('./private');
|
||||||
|
|
||||||
|
app.use( public );
|
||||||
|
app.use( private );
|
||||||
|
|
||||||
|
module.exports = app;
|
||||||
22
v1/src/apps/observers/private/index.js
Normal file
22
v1/src/apps/observers/private/index.js
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
'use strict';
|
||||||
|
const router = require('express').Router();
|
||||||
|
|
||||||
|
const jwtValidator = require( '../../../lib/jwtValidator.js' );
|
||||||
|
const context = require( './lib/context' );
|
||||||
|
|
||||||
|
// const loads = require('./loads/routes.js');
|
||||||
|
|
||||||
|
router.use( jwtValidator.middleware );
|
||||||
|
router.use( context.middleware );
|
||||||
|
|
||||||
|
router.use( (req,res) => {
|
||||||
|
console.log( req.JWT );
|
||||||
|
console.log( req.context );
|
||||||
|
return res.status(500).send( {
|
||||||
|
error: "Not implemented yet"
|
||||||
|
} );
|
||||||
|
} )
|
||||||
|
|
||||||
|
// router.use('/loads', loads);
|
||||||
|
|
||||||
|
module.exports = router;
|
||||||
38
v1/src/apps/observers/private/lib/context/index.js
Normal file
38
v1/src/apps/observers/private/lib/context/index.js
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
'use strict';
|
||||||
|
const { getModel } = require( '../../../../../lib/Models' );
|
||||||
|
const ObserverClient = getModel('observers.client');
|
||||||
|
const ObserverWarehouse = getModel('observers.warehouse');
|
||||||
|
|
||||||
|
function get_model_from_type( user_type ){
|
||||||
|
let observer_model;
|
||||||
|
|
||||||
|
if( user_type == "client" ){
|
||||||
|
observer_model = ObserverClient;
|
||||||
|
}else if( user_type == "warehouse" ){
|
||||||
|
observer_model = ObserverWarehouse;
|
||||||
|
}else{
|
||||||
|
observer_model = null;
|
||||||
|
}
|
||||||
|
return observer_model;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function middleware( req, res, next ){
|
||||||
|
if( ! req.JWT?.isValid ){
|
||||||
|
return res.status(401).send({error:"Unauthorized",code:401});
|
||||||
|
}
|
||||||
|
const user_model = get_model_from_type( req.JWT.payload.user_type );
|
||||||
|
const userID = req.JWT.payload.sub;
|
||||||
|
|
||||||
|
req.context = {
|
||||||
|
user : await user_model.findById( userID , { password : 0 , session_token : 0 , session_token_exp : 0 } )
|
||||||
|
}
|
||||||
|
|
||||||
|
req.context.userId = req.context.user.id;
|
||||||
|
req.context.email = req.context.user.email;
|
||||||
|
req.context.user_type = req.JWT.payload.user_type;
|
||||||
|
next();
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
middleware
|
||||||
|
};
|
||||||
13
v1/src/apps/observers/private/loads/routes.js
Normal file
13
v1/src/apps/observers/private/loads/routes.js
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
'use strict';
|
||||||
|
const router = require('express').Router();
|
||||||
|
const services= require('./services.js');
|
||||||
|
|
||||||
|
router.get('/find', services.findList);
|
||||||
|
router.get('/calendar', services.findCalendarList);
|
||||||
|
router.post('/new', services.postLoad);
|
||||||
|
|
||||||
|
router.patch('/:id', services.patchLoad);
|
||||||
|
router.delete('/:id', services.deleteLoad);
|
||||||
|
router.get('/:id', services.getById);
|
||||||
|
|
||||||
|
module.exports = router;
|
||||||
335
v1/src/apps/observers/private/loads/services.js
Normal file
335
v1/src/apps/observers/private/loads/services.js
Normal file
@@ -0,0 +1,335 @@
|
|||||||
|
"use strict";
|
||||||
|
const { getModel } = require( '../../../lib/Models' );
|
||||||
|
const { getPagination, genKey } = require( '../../../lib/Misc.js' );
|
||||||
|
const { GenericHandler } = require( '../../../lib/Handlers/Generic.handler.js' );
|
||||||
|
const Model = getModel('loads');
|
||||||
|
const CompanyModel = getModel('companies');
|
||||||
|
const ProposalsModel = getModel('proposals');
|
||||||
|
const branchesModel = getModel('branches');
|
||||||
|
|
||||||
|
const carrier_projection = [
|
||||||
|
'company_name',
|
||||||
|
'company_code',
|
||||||
|
'createdAt',
|
||||||
|
'rfc'
|
||||||
|
];
|
||||||
|
|
||||||
|
const vehicle_projection = [
|
||||||
|
'vehicle_code',
|
||||||
|
'truck_type',
|
||||||
|
'driver',
|
||||||
|
'categories',
|
||||||
|
'circulation_serial_number',
|
||||||
|
'trailer_plate_1',
|
||||||
|
'trailer_plate_2',
|
||||||
|
'city',
|
||||||
|
];
|
||||||
|
const user_projection = ['first_name','last_name','middle_name'];
|
||||||
|
const populate_list = [
|
||||||
|
'product',
|
||||||
|
'company',
|
||||||
|
'categories',
|
||||||
|
'shipper_warehouse',
|
||||||
|
{path:'carrier',select: carrier_projection },
|
||||||
|
{path:'vehicle',select: vehicle_projection },
|
||||||
|
{path:'driver',select: user_projection },
|
||||||
|
{path:'bidder',select: user_projection },
|
||||||
|
];
|
||||||
|
const generic = new GenericHandler( Model, null, populate_list );
|
||||||
|
|
||||||
|
function getAndFilterList( query ){
|
||||||
|
const filter_list = [];
|
||||||
|
const {
|
||||||
|
company,
|
||||||
|
carrier,
|
||||||
|
vehicle,
|
||||||
|
driver,
|
||||||
|
status,
|
||||||
|
posted_by,
|
||||||
|
posted_by_name,
|
||||||
|
load_status,
|
||||||
|
published_date,
|
||||||
|
loaded_date,
|
||||||
|
transit_date,
|
||||||
|
categories,
|
||||||
|
product,
|
||||||
|
shipment_code,
|
||||||
|
shipper_warehouse,
|
||||||
|
est_loading_date,
|
||||||
|
alert_list,
|
||||||
|
} = query;
|
||||||
|
|
||||||
|
if( company ){ filter_list.push( { company } ); }
|
||||||
|
if( carrier ){ filter_list.push( { carrier } ); }
|
||||||
|
if( vehicle ){ filter_list.push( { vehicle } ); }
|
||||||
|
if( driver ){ filter_list.push( { driver } ); }
|
||||||
|
if( status ){ filter_list.push( { status } ); }
|
||||||
|
if( posted_by ) { filter_list.push({ posted_by }); }
|
||||||
|
if( posted_by_name ) { filter_list.push({ posted_by_name }); }
|
||||||
|
if( load_status ) { filter_list.push({ load_status }); }
|
||||||
|
if( published_date ) { filter_list.push({ published_date }); }
|
||||||
|
if( loaded_date ) { filter_list.push({ loaded_date }); }
|
||||||
|
if( transit_date ) { filter_list.push({ transit_date }); }
|
||||||
|
if( categories ) { filter_list.push({ categories }); }
|
||||||
|
if( product ) { filter_list.push({ product }); }
|
||||||
|
if( shipment_code ) { filter_list.push({ shipment_code }); }
|
||||||
|
if( shipper_warehouse ) { filter_list.push({ shipper_warehouse }); }
|
||||||
|
if( alert_list ) { filter_list.push({ alert_list }); }
|
||||||
|
if( est_loading_date ) {
|
||||||
|
if( (est_loading_date.gte == undefined) || (est_loading_date.gte == null) ){
|
||||||
|
throw "est_loading_date[gte] is required";
|
||||||
|
}
|
||||||
|
if( (est_loading_date.lte == undefined) || (est_loading_date.lte == null) ){
|
||||||
|
throw "est_loading_date[lte] is required";
|
||||||
|
}
|
||||||
|
filter_list.push({
|
||||||
|
"est_loading_date" : {
|
||||||
|
$gte : new Date( est_loading_date["gte"] ),
|
||||||
|
$lte : new Date( est_loading_date["lte"] )
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if( filter_list.length == 0 ){
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return filter_list;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function findLoads( query ){
|
||||||
|
const { $sort, company_name } = query;
|
||||||
|
const { page, elements } = getPagination( query );
|
||||||
|
const andFilterList = getAndFilterList( query ) || [];
|
||||||
|
|
||||||
|
let filter;
|
||||||
|
|
||||||
|
if( company_name ){
|
||||||
|
/* Populate list of company ids with match on the company_name */
|
||||||
|
const company_list = await CompanyModel.find( { company_name }, [ "id" ] );
|
||||||
|
const or_company_list = []
|
||||||
|
company_list.forEach( (item) =>{
|
||||||
|
or_company_list.push({"company" : item.id});
|
||||||
|
})
|
||||||
|
andFilterList.push({
|
||||||
|
$or : or_company_list
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if( andFilterList.length > 0 ){
|
||||||
|
filter = { $and : andFilterList };
|
||||||
|
}else{
|
||||||
|
filter = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const { total , limit, skip, data } = await generic.getList( page , elements, filter, null, $sort );
|
||||||
|
|
||||||
|
const load_list = data;
|
||||||
|
|
||||||
|
for(let i=0; i<load_list.length; i++){
|
||||||
|
const load_id = load_list[ i ].id;
|
||||||
|
load_list[i] = load_list[i].toObject();
|
||||||
|
const no_of_proposals = await ProposalsModel.count({ load : load_id });
|
||||||
|
load_list[i].no_of_proposals = no_of_proposals;
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
total,
|
||||||
|
limit,
|
||||||
|
skip,
|
||||||
|
data : load_list
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Busqueda de cargas por fecha, asumiendo que la companyId es
|
||||||
|
* siempre la del usuario solicitando los datos.
|
||||||
|
*/
|
||||||
|
async function findCalendarLoads( userId, companyId, query ){
|
||||||
|
const select = null;
|
||||||
|
const { date, load_status , $sort } = query;
|
||||||
|
const { global } = query;
|
||||||
|
const { shipper_warehouse } = query;
|
||||||
|
|
||||||
|
if( ! date ){
|
||||||
|
throw "Date field is required";
|
||||||
|
}
|
||||||
|
|
||||||
|
const { page, elements } = getPagination( query );
|
||||||
|
|
||||||
|
const orFilterList = [
|
||||||
|
{"company" : companyId},
|
||||||
|
{"carrier" : companyId}
|
||||||
|
]
|
||||||
|
|
||||||
|
const andFilterList = [
|
||||||
|
{
|
||||||
|
"est_loading_date" : {
|
||||||
|
$gte : new Date( date["gte"] ),
|
||||||
|
$lte : new Date( date["lte"] )
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
$or : orFilterList
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
if( !(global) || (global == 0) ){
|
||||||
|
andFilterList.push( {
|
||||||
|
$or : [
|
||||||
|
{"bidder" : userId},
|
||||||
|
{"posted_by" : userId},
|
||||||
|
]
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( load_status ){
|
||||||
|
andFilterList.push( { load_status } )
|
||||||
|
}
|
||||||
|
|
||||||
|
if( shipper_warehouse ){
|
||||||
|
andFilterList.push( { shipper_warehouse } )
|
||||||
|
}
|
||||||
|
|
||||||
|
const filter = {
|
||||||
|
$and : andFilterList,
|
||||||
|
};
|
||||||
|
|
||||||
|
const {
|
||||||
|
total,
|
||||||
|
limit,
|
||||||
|
skip,
|
||||||
|
query : model_query,
|
||||||
|
} = await generic.getListQuery( page , elements, filter , select );
|
||||||
|
|
||||||
|
if( $sort ){
|
||||||
|
model_query.sort( $sort );
|
||||||
|
}
|
||||||
|
|
||||||
|
const data = await generic.populateQuery( model_query );
|
||||||
|
|
||||||
|
return {
|
||||||
|
total,
|
||||||
|
limit,
|
||||||
|
skip,
|
||||||
|
data
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
async function findElementById( elementId ){
|
||||||
|
let retVal = await Model.findById( elementId ).populate( populate_list );
|
||||||
|
if( retVal ){
|
||||||
|
retVal = retVal.toObject();
|
||||||
|
const no_of_proposals = await ProposalsModel.count({ load : elementId });
|
||||||
|
retVal.no_of_proposals = no_of_proposals;
|
||||||
|
}else{
|
||||||
|
retVal = {};
|
||||||
|
}
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
const findCalendarList = async(req, res) => {
|
||||||
|
try{
|
||||||
|
const query = req.query || {};
|
||||||
|
const companyId = req.context.companyId;
|
||||||
|
const userId = req.context.userId;
|
||||||
|
const retVal = await findCalendarLoads( userId, companyId, query );
|
||||||
|
res.send( retVal );
|
||||||
|
}catch(error){
|
||||||
|
console.error( error );
|
||||||
|
return res.status( 500 ).send({ error });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const findList = async(req, res) => {
|
||||||
|
try{
|
||||||
|
const query = req.query || {};
|
||||||
|
const retVal = await findLoads( query );
|
||||||
|
res.send( retVal );
|
||||||
|
}catch(error){
|
||||||
|
console.error( error );
|
||||||
|
return res.status( 500 ).send({ error });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const getById = async(req, res) => {
|
||||||
|
try{
|
||||||
|
const elementId = req.params.id;
|
||||||
|
res.send( await findElementById( elementId ) );
|
||||||
|
}catch(error){
|
||||||
|
console.error( error );
|
||||||
|
return res.status( 500 ).send({ error });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const patchLoad = async(req, res) => {
|
||||||
|
try{
|
||||||
|
const elementId = req.params.id;
|
||||||
|
const permissions = req.context.permissions;
|
||||||
|
const data = req.body;
|
||||||
|
const load = await findElementById( elementId );
|
||||||
|
if( !load ){
|
||||||
|
throw "You can't modify this load";
|
||||||
|
}
|
||||||
|
if( !data ){
|
||||||
|
throw "load data not sent";
|
||||||
|
}
|
||||||
|
await Model.findByIdAndUpdate( elementId , data );
|
||||||
|
return res.send( await Model.findById( elementId ) );
|
||||||
|
}catch(error){
|
||||||
|
console.error( error );
|
||||||
|
return res.status( 500 ).send({ error });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const postLoad = async(req, res) => {
|
||||||
|
try{
|
||||||
|
const companyId = req.context.companyId;
|
||||||
|
const userId = req.context.userId;
|
||||||
|
const user_name = req.context.user.first_name;
|
||||||
|
const permissions = req.context.permissions;
|
||||||
|
const data = req.body;
|
||||||
|
if( !data ){
|
||||||
|
throw "Load data not sent";
|
||||||
|
}
|
||||||
|
if(permissions !== "role_shipper" ){
|
||||||
|
throw "You can't create loads";
|
||||||
|
}
|
||||||
|
data.company = companyId;
|
||||||
|
data.posted_by = userId;
|
||||||
|
data.name = user_name;
|
||||||
|
const load = new Model( data );
|
||||||
|
await load.save();
|
||||||
|
|
||||||
|
const id = "" + load._id;
|
||||||
|
const shipment_code = "ETA-" + genKey( 6, id );
|
||||||
|
await Model.findByIdAndUpdate( id , {
|
||||||
|
shipment_code
|
||||||
|
});
|
||||||
|
load.shipment_code = shipment_code;
|
||||||
|
return res.send( load );
|
||||||
|
}catch(error){
|
||||||
|
console.error( error );
|
||||||
|
return res.status( 500 ).send({ error });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const deleteLoad = async(req, res) => {
|
||||||
|
try{
|
||||||
|
const companyId = req.context.companyId;
|
||||||
|
const elementId = req.params.id;
|
||||||
|
const permissions = req.context.permissions;
|
||||||
|
const load = await findElementById( elementId , companyId );
|
||||||
|
if(!load){
|
||||||
|
throw "You can't delete this load";
|
||||||
|
}
|
||||||
|
if(permissions !== "role_shipper" ){
|
||||||
|
throw "You can't delete loads";
|
||||||
|
}
|
||||||
|
await Model.findByIdAndDelete( elementId );
|
||||||
|
return res.send(load);
|
||||||
|
}catch(error){
|
||||||
|
console.error( error );
|
||||||
|
return res.status( 500 ).send({ error });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = { findCalendarList, findList, getById, patchLoad, postLoad, deleteLoad };
|
||||||
23
v1/src/apps/observers/public/account/routes.js
Normal file
23
v1/src/apps/observers/public/account/routes.js
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
'use strict';
|
||||||
|
const router = require('express').Router();
|
||||||
|
const services= require('./services.js');
|
||||||
|
|
||||||
|
router.post('/client/authorize', services.Client_AuthorizeJWT);
|
||||||
|
router.post('/warehouse/authorize', services.Warehouse_AuthorizeJWT);
|
||||||
|
|
||||||
|
router.get('/client/authorize/:session_token', services.Client_RenewJWT);
|
||||||
|
router.get('/warehouse/authorize/:session_token', services.Warehouse_RenewJWT);
|
||||||
|
|
||||||
|
router.post('/client/signup', services.Client_TryCreateAccount);
|
||||||
|
router.post('/warehouse/signup', services.Warehouse_TryCreateAccount);
|
||||||
|
|
||||||
|
router.patch('/client/signup', services.Client_ConfirmAccount);
|
||||||
|
router.patch('/warehouse/signup', services.Warehouse_ConfirmAccount);
|
||||||
|
|
||||||
|
router.post('/client/recover', services.Client_RecoverPwd);
|
||||||
|
router.post('/warehouse/recover', services.Warehouse_RecoverPwd);
|
||||||
|
|
||||||
|
router.patch('/client/recover', services.Client_ConfirmRecoverPwd);
|
||||||
|
router.patch('/warehouse/recover', services.Warehouse_ConfirmRecoverPwd);
|
||||||
|
|
||||||
|
module.exports = router;
|
||||||
534
v1/src/apps/observers/public/account/services.js
Normal file
534
v1/src/apps/observers/public/account/services.js
Normal file
@@ -0,0 +1,534 @@
|
|||||||
|
"use strict";
|
||||||
|
const jsonwebtoken = require('jsonwebtoken');
|
||||||
|
|
||||||
|
const apiConfig = require('../../../../config/apiConfig.json' );
|
||||||
|
|
||||||
|
const { genKey, toSha256 } = require( '../../../../lib/Misc' );
|
||||||
|
const { emailEvent , EMAIL_EVENTS } = require( '../../../../lib/Handlers/MailClient' );
|
||||||
|
const { create_account, already_exists, login, login_with_session_token, reset_password } = require( '../../../../lib/Handlers/Observers' );
|
||||||
|
const { Validator } = require( "jsonschema" );
|
||||||
|
|
||||||
|
const jwtSecret = apiConfig.authentication.jwtSecret;
|
||||||
|
const jwtTimeout = apiConfig.authentication.jwtTimeout;//Timeout in hours
|
||||||
|
const jwtRenewalTimeout = apiConfig.authentication.jwtRenewalTimeout;//Timeout in hours
|
||||||
|
const jwtOptions = apiConfig.authentication.jwtOptions;
|
||||||
|
const validator = new Validator();
|
||||||
|
|
||||||
|
const create_account_schema = {
|
||||||
|
type : 'object',
|
||||||
|
properties : {
|
||||||
|
email : { type : 'string' , maxLength : 256 },
|
||||||
|
password : { type : 'string', maxLength : 256},
|
||||||
|
otp : { type : 'string', maxLength : 6 },
|
||||||
|
checksum : { type : 'string', maxLength : 32 }
|
||||||
|
},
|
||||||
|
required : [ 'email', 'password' ]
|
||||||
|
};
|
||||||
|
|
||||||
|
const confirm_account_schema = {
|
||||||
|
type : 'object',
|
||||||
|
properties : create_account_schema.properties,//Same properties
|
||||||
|
required : [ 'email', 'password', 'otp', 'checksum' ]//Different requirements
|
||||||
|
};
|
||||||
|
|
||||||
|
const login_account_schema = {
|
||||||
|
type : 'object',
|
||||||
|
properties : create_account_schema.properties,//Same properties
|
||||||
|
required : [ 'email', 'password' ]//Different requirements
|
||||||
|
};
|
||||||
|
|
||||||
|
const password_recover_schema = create_account_schema;
|
||||||
|
const confirm_password_recover_schema = {
|
||||||
|
type : 'object',
|
||||||
|
properties : create_account_schema.properties,//Same properties
|
||||||
|
required : [ 'email', 'password', 'otp', 'checksum' ]//Different requirements
|
||||||
|
};
|
||||||
|
|
||||||
|
async function AuthorizeJWT_email_pwd( user_type, email , password ){
|
||||||
|
const user = await login( user_type, email, password );
|
||||||
|
if( !user ){
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const current_date = new Date();
|
||||||
|
const iat = Math.floor( (current_date.getTime())/1000 );
|
||||||
|
const renewal_exp = ( iat + 3600*jwtRenewalTimeout ) * 1000;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Renew session token on every login event.
|
||||||
|
* Previous session token is lost
|
||||||
|
*/
|
||||||
|
const session_token = toSha256( `${new Date()}` );
|
||||||
|
const session_token_exp = new Date( renewal_exp );
|
||||||
|
user.session_token = session_token;
|
||||||
|
user.session_token_exp = session_token_exp;
|
||||||
|
await user.save();
|
||||||
|
|
||||||
|
const payload = {
|
||||||
|
iat: iat,
|
||||||
|
exp: iat + jwtTimeout * 3600,
|
||||||
|
aud: jwtOptions.audience,
|
||||||
|
iss: jwtOptions.audience,
|
||||||
|
user_type: user_type,
|
||||||
|
sub: user.id,
|
||||||
|
};
|
||||||
|
const jwt = jsonwebtoken.sign( payload , jwtSecret );
|
||||||
|
return {
|
||||||
|
accessToken : jwt,
|
||||||
|
payload : payload,
|
||||||
|
session_token,
|
||||||
|
session_token_exp,
|
||||||
|
user : user
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function valid_user_type( user_type ){
|
||||||
|
return ( (user_type == "client") || (user_type == "warehouse") );
|
||||||
|
}
|
||||||
|
|
||||||
|
async function AuthorizeJWT( user_type, body ){
|
||||||
|
if( !valid_user_type( user_type ) ){
|
||||||
|
throw "Invalid user_type";
|
||||||
|
}
|
||||||
|
|
||||||
|
if( validator.validate( body, login_account_schema ).valid ){
|
||||||
|
const { email, password } = body;
|
||||||
|
const retVal = await AuthorizeJWT_email_pwd( user_type, email , password );
|
||||||
|
if( !retVal ){
|
||||||
|
return {
|
||||||
|
status : 401,
|
||||||
|
payload:{
|
||||||
|
error: "Invalid credentials"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
return {
|
||||||
|
status : null,
|
||||||
|
payload : retVal
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
return {
|
||||||
|
status : 400,
|
||||||
|
payload:{
|
||||||
|
error: "Invalid request"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
async function RenewJWT( user_type, params ){
|
||||||
|
if( !valid_user_type( user_type ) ){
|
||||||
|
throw "Invalid user_type";
|
||||||
|
}
|
||||||
|
|
||||||
|
const login_session_token = params.session_token;
|
||||||
|
const user = await login_with_session_token( user_type, login_session_token );
|
||||||
|
if( !user ){
|
||||||
|
return {
|
||||||
|
status : 401,
|
||||||
|
payload:{
|
||||||
|
error: "Invalid or Expired Session Token"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const current_date = new Date();
|
||||||
|
const iat = Math.floor( (current_date.getTime())/1000 );
|
||||||
|
const renewal_exp = ( iat + 3600*jwtRenewalTimeout ) * 1000;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Renew session token on every login event.
|
||||||
|
* Previous session token is lost
|
||||||
|
*/
|
||||||
|
const session_token = toSha256( `${new Date()}` );
|
||||||
|
const session_token_exp = new Date( renewal_exp );
|
||||||
|
user.session_token = session_token;
|
||||||
|
user.session_token_exp = session_token_exp;
|
||||||
|
await user.save();
|
||||||
|
|
||||||
|
delete user.session_token;
|
||||||
|
delete user.session_token_exp;
|
||||||
|
|
||||||
|
const payload = {
|
||||||
|
iat: iat,
|
||||||
|
exp: iat + jwtTimeout * 3600,
|
||||||
|
aud: jwtOptions.audience,
|
||||||
|
iss: jwtOptions.audience,
|
||||||
|
user_type: user_type,
|
||||||
|
sub: user.id,
|
||||||
|
};
|
||||||
|
const jwt = jsonwebtoken.sign( payload , jwtSecret );
|
||||||
|
|
||||||
|
return {
|
||||||
|
status: null,
|
||||||
|
payload: {
|
||||||
|
accessToken : jwt,
|
||||||
|
payload : payload,
|
||||||
|
session_token,
|
||||||
|
session_token_exp,
|
||||||
|
user : user
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function TryCreateAccount( user_type, body ){
|
||||||
|
if( !valid_user_type( user_type ) ){
|
||||||
|
throw "Invalid user_type";
|
||||||
|
}
|
||||||
|
|
||||||
|
if( validator.validate( body , create_account_schema ).valid ){
|
||||||
|
const otp = genKey();
|
||||||
|
const { email : receiver , password } = body;
|
||||||
|
const email = receiver;
|
||||||
|
|
||||||
|
const it_exists = await already_exists( user_type, email );
|
||||||
|
if( it_exists ){
|
||||||
|
return {
|
||||||
|
status: 400,
|
||||||
|
payload: {
|
||||||
|
error : "Email already exists"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const content = { OTP : otp, user_name : email };
|
||||||
|
const checksum_entry = {
|
||||||
|
email : receiver,
|
||||||
|
password,
|
||||||
|
otp
|
||||||
|
};
|
||||||
|
const checksum = toSha256( JSON.stringify(checksum_entry)).substr(0, 32);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO: Send an confirmation email with client/warehouse templates!
|
||||||
|
*/
|
||||||
|
await emailEvent( EMAIL_EVENTS.ACCOUNT_VERIFY , receiver , content );
|
||||||
|
console.log(
|
||||||
|
content
|
||||||
|
);
|
||||||
|
return {
|
||||||
|
status: null,
|
||||||
|
payload: {
|
||||||
|
checksum
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
return {
|
||||||
|
status: 400,
|
||||||
|
payload: {
|
||||||
|
error : "Invalid request"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
async function ConfirmAccount( user_type, body ){
|
||||||
|
if( !valid_user_type( user_type ) ){
|
||||||
|
throw "Invalid user_type";
|
||||||
|
}
|
||||||
|
|
||||||
|
if( validator.validate( body , confirm_account_schema ).valid ){
|
||||||
|
const { email, password, otp, checksum } = body;
|
||||||
|
|
||||||
|
const it_exists = await already_exists( user_type, email );
|
||||||
|
if( it_exists ){
|
||||||
|
return {
|
||||||
|
status : 400,
|
||||||
|
payload : { error : "User already registered!" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const checksum_entry = {email, password, otp};
|
||||||
|
const recomputed_checksum = toSha256( JSON.stringify(checksum_entry)).substr(0, 32);
|
||||||
|
if( recomputed_checksum != checksum ){
|
||||||
|
return {
|
||||||
|
status : 400,
|
||||||
|
payload : { error : "Wrong OTP" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
await create_account( user_type, email, password );
|
||||||
|
|
||||||
|
const content = { user_name : email };
|
||||||
|
const receiver = email;
|
||||||
|
/**
|
||||||
|
* TODO: Send an confirmation email with client/warehouse templates!
|
||||||
|
*/
|
||||||
|
await emailEvent( EMAIL_EVENTS.ACCOUNT_CONFIRMED , receiver , content );
|
||||||
|
const retVal = await AuthorizeJWT_email_pwd( user_type, email , password );
|
||||||
|
|
||||||
|
return {
|
||||||
|
status : null,
|
||||||
|
payload: retVal
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
return {
|
||||||
|
status: 400,
|
||||||
|
payload: { error : "Invalid request" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function RecoverPwd( user_type, body ){
|
||||||
|
if( !valid_user_type( user_type ) ){
|
||||||
|
throw "Invalid user_type";
|
||||||
|
}
|
||||||
|
|
||||||
|
if( validator.validate( body , password_recover_schema ).valid ){
|
||||||
|
const otp = genKey();
|
||||||
|
const { email : receiver , password } = body;
|
||||||
|
const email = receiver;
|
||||||
|
|
||||||
|
const it_exists = await already_exists( user_type, email );
|
||||||
|
if( !it_exists ){
|
||||||
|
return {
|
||||||
|
status: 400,
|
||||||
|
payload: { error : "Email is not registered!" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const content = { OTP : otp, user_name : email };
|
||||||
|
const checksum_entry = {
|
||||||
|
email : receiver,
|
||||||
|
password,
|
||||||
|
otp
|
||||||
|
};
|
||||||
|
const checksum = toSha256( JSON.stringify(checksum_entry)).substr(0, 32);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO: Send an confirmation email with client/warehouse templates!
|
||||||
|
*/
|
||||||
|
await emailEvent( EMAIL_EVENTS.ACCOUNT_PWD_RESET , receiver , content );
|
||||||
|
console.log(
|
||||||
|
content
|
||||||
|
);
|
||||||
|
|
||||||
|
return {
|
||||||
|
status: null,
|
||||||
|
payload: { checksum }
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
return {
|
||||||
|
status: 400,
|
||||||
|
payload: { error: "Invalid request" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function ConfirmRecoverPwd( user_type, body ){
|
||||||
|
if( !valid_user_type( user_type ) ){
|
||||||
|
throw "Invalid user_type";
|
||||||
|
}
|
||||||
|
|
||||||
|
if( validator.validate( body , confirm_password_recover_schema ).valid ){
|
||||||
|
const { email, password, otp, checksum } = body;
|
||||||
|
|
||||||
|
const it_exists = await already_exists( user_type, email );
|
||||||
|
if( !it_exists ){
|
||||||
|
return {
|
||||||
|
status: 400,
|
||||||
|
payload: { error : "Email is not registered!" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const checksum_entry = {email, password, otp};
|
||||||
|
const recomputed_checksum = toSha256( JSON.stringify(checksum_entry)).substr(0, 32);
|
||||||
|
if( recomputed_checksum != checksum ){
|
||||||
|
return {
|
||||||
|
status: 400,
|
||||||
|
payload: { error : "Wrong OTP" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
await reset_password( user_type, email, password );
|
||||||
|
|
||||||
|
return {
|
||||||
|
status: null,
|
||||||
|
payload: { msg : "Password is reset!" }
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
return {
|
||||||
|
status: 400,
|
||||||
|
payload: { error : "Invalid request" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const Client_AuthorizeJWT = async(req, res) => {
|
||||||
|
try{
|
||||||
|
const result = await AuthorizeJWT( 'client', req.body );
|
||||||
|
if( !result.status ){
|
||||||
|
return res.send( result.payload );
|
||||||
|
}else{
|
||||||
|
return res.status(result.status).send( result.payload );
|
||||||
|
}
|
||||||
|
}catch( err ){
|
||||||
|
console.error( err );
|
||||||
|
return res.status(500).send({ error : "Login: Internal error" });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const Warehouse_AuthorizeJWT = async(req, res) => {
|
||||||
|
try{
|
||||||
|
const result = await AuthorizeJWT( 'warehouse', req.body );
|
||||||
|
if( !result.status ){
|
||||||
|
return res.send( result.payload );
|
||||||
|
}else{
|
||||||
|
return res.status(result.status).send( result.payload );
|
||||||
|
}
|
||||||
|
}catch( err ){
|
||||||
|
console.error( err );
|
||||||
|
return res.status(500).send({ error : "Login: Internal error" });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const Client_RenewJWT = async(req, res) => {
|
||||||
|
try{
|
||||||
|
const result = await RenewJWT( 'client', req.params );
|
||||||
|
if( !result.status ){
|
||||||
|
return res.send( result.payload );
|
||||||
|
}else{
|
||||||
|
return res.status(result.status).send( result.payload );
|
||||||
|
}
|
||||||
|
}catch( err ){
|
||||||
|
console.error( err );
|
||||||
|
return res.status(500).send({ error : "Renew: Internal error" });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const Warehouse_RenewJWT = async(req, res) => {
|
||||||
|
try{
|
||||||
|
const result = await RenewJWT( 'warehouse', req.params );
|
||||||
|
if( !result.status ){
|
||||||
|
return res.send( result.payload );
|
||||||
|
}else{
|
||||||
|
return res.status(result.status).send( result.payload );
|
||||||
|
}
|
||||||
|
}catch( err ){
|
||||||
|
console.error( err );
|
||||||
|
return res.status(500).send({ error : "Renew: Internal error" });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const Client_TryCreateAccount = async(req, res) => {
|
||||||
|
try{
|
||||||
|
const result = await TryCreateAccount( 'client', req.body );
|
||||||
|
if( !result.status ){
|
||||||
|
return res.send( result.payload );
|
||||||
|
}else{
|
||||||
|
return res.status(result.status).send( result.payload );
|
||||||
|
}
|
||||||
|
}catch( err ){
|
||||||
|
console.error( err );
|
||||||
|
return res.status(500).send({ error : "Account creation: Internal error" });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const Warehouse_TryCreateAccount = async(req, res) => {
|
||||||
|
try{
|
||||||
|
const result = await TryCreateAccount( 'warehouse', req.body );
|
||||||
|
if( !result.status ){
|
||||||
|
return res.send( result.payload );
|
||||||
|
}else{
|
||||||
|
return res.status(result.status).send( result.payload );
|
||||||
|
}
|
||||||
|
}catch( err ){
|
||||||
|
console.error( err );
|
||||||
|
return res.status(500).send({ error : "Account creation: Internal error" });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const Client_ConfirmAccount = async(req, res) => {
|
||||||
|
try{
|
||||||
|
const result = await ConfirmAccount( 'client', req.body );
|
||||||
|
if( !result.status ){
|
||||||
|
return res.send( result.payload );
|
||||||
|
}else{
|
||||||
|
return res.status(result.status).send( result.payload );
|
||||||
|
}
|
||||||
|
}catch( err ){
|
||||||
|
console.error( err );
|
||||||
|
return res.status(500).send({ error : "Account creation: Internal error" });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const Warehouse_ConfirmAccount = async(req, res) => {
|
||||||
|
try{
|
||||||
|
const result = await ConfirmAccount( 'warehouse', req.body );
|
||||||
|
if( !result.status ){
|
||||||
|
return res.send( result.payload );
|
||||||
|
}else{
|
||||||
|
return res.status(result.status).send( result.payload );
|
||||||
|
}
|
||||||
|
}catch( err ){
|
||||||
|
console.error( err );
|
||||||
|
return res.status(500).send({ error : "Account creation: Internal error" });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const Client_RecoverPwd = async(req, res) => {
|
||||||
|
try{
|
||||||
|
const result = await RecoverPwd( 'client', req.body );
|
||||||
|
if( !result.status ){
|
||||||
|
return res.send( result.payload );
|
||||||
|
}else{
|
||||||
|
return res.status(result.status).send( result.payload );
|
||||||
|
}
|
||||||
|
}catch( err ){
|
||||||
|
console.error( err );
|
||||||
|
return res.status(500).send({ error : "Password Recover: Internal error" });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const Warehouse_RecoverPwd = async(req, res) => {
|
||||||
|
try{
|
||||||
|
const result = await RecoverPwd( 'warehouse', req.body );
|
||||||
|
if( !result.status ){
|
||||||
|
return res.send( result.payload );
|
||||||
|
}else{
|
||||||
|
return res.status(result.status).send( result.payload );
|
||||||
|
}
|
||||||
|
}catch( err ){
|
||||||
|
console.error( err );
|
||||||
|
return res.status(500).send({ error : "Password Recover: Internal error" });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const Client_ConfirmRecoverPwd = async(req, res) => {
|
||||||
|
try{
|
||||||
|
const result = await ConfirmRecoverPwd( 'client', req.body );
|
||||||
|
if( !result.status ){
|
||||||
|
return res.send( result.payload );
|
||||||
|
}else{
|
||||||
|
return res.status(result.status).send( result.payload );
|
||||||
|
}
|
||||||
|
}catch( err ){
|
||||||
|
console.error( err );
|
||||||
|
return res.status(500).send({ error : "Password Recover: Internal error" });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const Warehouse_ConfirmRecoverPwd = async(req, res) => {
|
||||||
|
try{
|
||||||
|
const result = await ConfirmRecoverPwd( 'warehouse', req.body );
|
||||||
|
if( !result.status ){
|
||||||
|
return res.send( result.payload );
|
||||||
|
}else{
|
||||||
|
return res.status(result.status).send( result.payload );
|
||||||
|
}
|
||||||
|
}catch( err ){
|
||||||
|
console.error( err );
|
||||||
|
return res.status(500).send({ error : "Password Recover: Internal error" });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
Client_AuthorizeJWT,
|
||||||
|
Warehouse_AuthorizeJWT,
|
||||||
|
Client_RenewJWT,
|
||||||
|
Warehouse_RenewJWT,
|
||||||
|
Client_TryCreateAccount,
|
||||||
|
Warehouse_TryCreateAccount,
|
||||||
|
Client_ConfirmAccount,
|
||||||
|
Warehouse_ConfirmAccount,
|
||||||
|
Client_RecoverPwd,
|
||||||
|
Warehouse_RecoverPwd,
|
||||||
|
Client_ConfirmRecoverPwd,
|
||||||
|
Warehouse_ConfirmRecoverPwd
|
||||||
|
};
|
||||||
8
v1/src/apps/observers/public/index.js
Normal file
8
v1/src/apps/observers/public/index.js
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
'use strict';
|
||||||
|
const router = require('express').Router();
|
||||||
|
|
||||||
|
const account = require('./account/routes.js');
|
||||||
|
|
||||||
|
router.use('/account', account);
|
||||||
|
|
||||||
|
module.exports = router;
|
||||||
@@ -116,6 +116,9 @@ const RenewJWT = async(req, res) => {
|
|||||||
user.session_token_exp = session_token_exp;
|
user.session_token_exp = session_token_exp;
|
||||||
await user.save();
|
await user.save();
|
||||||
|
|
||||||
|
delete user.session_token;
|
||||||
|
delete user.session_token_exp;
|
||||||
|
|
||||||
const payload = {
|
const payload = {
|
||||||
iat: iat,
|
iat: iat,
|
||||||
exp: iat + jwtTimeout * 3600,
|
exp: iat + jwtTimeout * 3600,
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ const morgan = require('morgan');
|
|||||||
const helmet = require('helmet');
|
const helmet = require('helmet');
|
||||||
const bodyParser = require('body-parser');
|
const bodyParser = require('body-parser');
|
||||||
const fileUpload = require('express-fileupload');
|
const fileUpload = require('express-fileupload');
|
||||||
const middlewares = require( `${ROOT_PATH}/${LIB_PATH}/Middlewares.js` );
|
const middlewares = require( './lib//Middlewares.js' );
|
||||||
|
|
||||||
const mongoose = require('mongoose');
|
const mongoose = require('mongoose');
|
||||||
mongoose.connect(
|
mongoose.connect(
|
||||||
|
|||||||
95
v1/src/lib/Handlers/Observers/index.js
Normal file
95
v1/src/lib/Handlers/Observers/index.js
Normal file
@@ -0,0 +1,95 @@
|
|||||||
|
'user strict';
|
||||||
|
const { getModel } = require( '../../Models' );
|
||||||
|
const apiConfig = require( '../../../config/apiConfig.json' );
|
||||||
|
const { toSha256 } = require( '../../Misc' );
|
||||||
|
const ObserverClient = getModel('observers.client');
|
||||||
|
const ObserverWarehouse = getModel('observers.warehouse');
|
||||||
|
|
||||||
|
const pwd_secret = apiConfig.authentication.pwdSecret;
|
||||||
|
|
||||||
|
function get_model_from_type( user_type ){
|
||||||
|
let observer_model;
|
||||||
|
|
||||||
|
if( user_type == "client" ){
|
||||||
|
observer_model = ObserverClient;
|
||||||
|
}else if( user_type == "warehouse" ){
|
||||||
|
observer_model = ObserverWarehouse;
|
||||||
|
}else{
|
||||||
|
observer_model = null;
|
||||||
|
}
|
||||||
|
return observer_model;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function create_account( user_type, email, password ){
|
||||||
|
let safe_password = toSha256( password + pwd_secret );
|
||||||
|
let user_model = get_model_from_type( user_type );
|
||||||
|
if( user_model == null ){ return null; }
|
||||||
|
|
||||||
|
const user = new user_model({
|
||||||
|
email,
|
||||||
|
password : safe_password,
|
||||||
|
});
|
||||||
|
|
||||||
|
await user.save();
|
||||||
|
return user;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function reset_password( user_type, email, password ){
|
||||||
|
let safe_password = toSha256( password + pwd_secret );
|
||||||
|
let user_model = get_model_from_type( user_type );
|
||||||
|
if( user_model == null ){ return null; }
|
||||||
|
|
||||||
|
const user = await user_model.findOne({ email });
|
||||||
|
|
||||||
|
if( user ){
|
||||||
|
user.password = safe_password;
|
||||||
|
await user.save();
|
||||||
|
return user;
|
||||||
|
}else{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function already_exists( user_type, email ){
|
||||||
|
let user_model = get_model_from_type( user_type );
|
||||||
|
if( user_model == null ){ return null; }
|
||||||
|
|
||||||
|
const user = await user_model.findOne( { email } );
|
||||||
|
if( !user ){
|
||||||
|
return false;
|
||||||
|
}else{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function login( user_type, email , password ){
|
||||||
|
let user_model = get_model_from_type( user_type );
|
||||||
|
if( user_model == null ){ return null; }
|
||||||
|
|
||||||
|
let safe_password = toSha256( password + pwd_secret );
|
||||||
|
const user = await user_model.findOne({
|
||||||
|
email , password : safe_password
|
||||||
|
},{ password : 0 , session_token : 0 , session_token_exp : 0 });
|
||||||
|
|
||||||
|
if( !user ){
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return user;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function login_with_session_token( user_type, session_token ){
|
||||||
|
let user_model = get_model_from_type( user_type );
|
||||||
|
if( user_model == null ){ return null; }
|
||||||
|
|
||||||
|
const user = await user_model.findOne({
|
||||||
|
session_token,
|
||||||
|
session_token_exp : { $gte: new Date() }
|
||||||
|
},{ password : 0 , session_token : 0 , session_token_exp : 0 });
|
||||||
|
|
||||||
|
if( !user ){
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return user;
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = { create_account, already_exists, login, login_with_session_token, reset_password };
|
||||||
18
v1/src/lib/Models/Observers/index.js
Normal file
18
v1/src/lib/Models/Observers/index.js
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
const mongoose = require('mongoose');
|
||||||
|
const { Schema } = mongoose;
|
||||||
|
|
||||||
|
const schema = new Schema({
|
||||||
|
email: { type: String, unique: true, lowercase: true },
|
||||||
|
password: { type: String , maxLength : 256 },
|
||||||
|
session_token : { type : String, maxLength : 256 },
|
||||||
|
session_token_exp : { type: Date },
|
||||||
|
createdAt: { type : Date, required : true, default : () => { return Date.now(); } }
|
||||||
|
});
|
||||||
|
|
||||||
|
const warehouse = mongoose.model( "observer_warehouse", schema )
|
||||||
|
const client = mongoose.model( "observer_client", schema )
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
warehouse,
|
||||||
|
client
|
||||||
|
};
|
||||||
@@ -22,6 +22,8 @@ const trackings = require('./trackings.model.js');
|
|||||||
const users = require('./users.model.js');
|
const users = require('./users.model.js');
|
||||||
const vehicles = require('./vehicles.model.js');
|
const vehicles = require('./vehicles.model.js');
|
||||||
|
|
||||||
|
const observers = require('./Observers')
|
||||||
|
|
||||||
function getModel( name ){
|
function getModel( name ){
|
||||||
switch( name ){
|
switch( name ){
|
||||||
case 'branches':
|
case 'branches':
|
||||||
@@ -66,6 +68,10 @@ function getModel( name ){
|
|||||||
return users;
|
return users;
|
||||||
case 'vehicles':
|
case 'vehicles':
|
||||||
return vehicles;
|
return vehicles;
|
||||||
|
case 'observers.client':
|
||||||
|
return observers.client;
|
||||||
|
case 'observers.warehouse':
|
||||||
|
return observers.warehouse;
|
||||||
default:
|
default:
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user