2019-06-23 21:27:52 +00:00
/ *
* This file is part of the authRxbn eco - system .
*
* ( c ) Ruben Meyer < contact @ rxbn . de >
*
* For the full copyright and license information , please view the LICENSE
* file that was distributed with this source code .
* /
// init
var mongoose = require ( 'mongoose' ) ;
var crypto = require ( 'crypto' ) ;
var methods = { } ;
// connect
mongoose . connect ( global [ 'gds' ] . cfg . mongoose . uri , {
useNewUrlParser : true
} ) ;
global [ 'gds' ] . db = mongoose . connection ;
var mdls = require ( './models.js' ) ;
var models = mdls ( global [ 'gds' ] . db ) ;
( async function ( ) {
global [ 'gds' ] . db = await global [ 'gds' ] . db . useDb ( global [ 'gds' ] . cfg . mongoose . db ) ;
models = mdls ( global [ 'gds' ] . db ) ;
} ) ( ) ;
// connection error handling
global [ 'gds' ] . db . on ( 'error' , ( data ) => {
global [ 'modules' ] . logs . error ( 'MongoDB connection error:\n' , data ) ;
process . exit ( ) ; // exit on connection error
} ) ;
// // // //////// //////// ///////
// // // // // // //
// // // ////// ////// //////
// // // // // // //
// //////// ////// //////// // //
//
/////////////////////////////////////////////
/ * *
* Adds User to Database
* @ author Ruben Meyer
* @ param { String } firstname First name
* @ param { String } lastname Last name
* @ param { String } email E - Mail
* @ param { String } password hashed PW
* @ param { Number } group Group id ( normally 0 - > user )
* @ param { Function } callback Callback function ( error , reply )
* /
methods . addUser = ( nick , email , pass , group , callback ) => {
if ( typeof callback !== 'function' ) callback = function ( ) { } ;
if ( typeof nick !== 'string' ) return callback ( new TypeError ( 'nick is not a string::database.addUser(' + nick + ',' + email + ',' + pass + ',' + group + ',callback)' , module . filename ) ) ;
if ( typeof email !== 'string' ) return callback ( new TypeError ( 'email is not a string::database.addUser(' + nick + ',' + email + ',' + pass + ',' + group + ',callback)' , module . filename ) ) ;
if ( typeof pass !== 'string' ) return callback ( new TypeError ( 'pass is not a string::database.addUser(' + nick + ',' + email + ',' + pass + ',' + group + ',callback)' , module . filename ) ) ;
if ( isNaN ( group ) ) return callback ( new TypeError ( 'group is not a number::database.addUser(' + nick + ',' + email + ',' + pass + ',' + group + ',callback)' , module . filename ) ) ;
var User = models . user ;
let tempUser = new User ( ) ;
tempUser . nickname = nick ;
tempUser . email = email ;
tempUser . passhash = pass ;
tempUser . group = group ;
tempUser . save ( ( err ) => {
if ( ! err ) callback ( null , 1 ) ;
else callback ( err ) ;
} ) ;
} ;
/ * *
* Deletes User from Database
* @ author Ruben Meyer
* @ TODO
* @ param { String } haystack email or nick
* @ param { Function } callback Callback function ( error , reply )
* /
methods . delUser = ( haystack , callback ) => {
if ( typeof callback !== 'function' ) callback = function ( ) { } ;
if ( typeof haystack !== 'string' ) return callback ( new TypeError ( 'haystack is not a string::database.delUser(' + haystack + ',callback)' , module . filename ) ) ;
var User = models . user ;
User . find ( ) . or ( [ { nickname : haystack } , { email : haystack } ] )
. then ( ( users ) => {
// TODO delete user
callback ( null , 1 ) ;
} ) . catch ( ( err ) => {
callback ( err ) ;
} ) ;
} ;
/ * *
* gets entry by email
* @ author Ruben Meyer
* @ param { String | String [ ] } haystack email or nick
* @ param { Function } callback Callback function ( reply - > Array users )
* /
methods . getUser = ( haystack , callback ) => {
if ( typeof callback !== 'function' ) callback = function ( ) { } ;
if ( typeof haystack !== 'string' && typeof haystack !== 'object' ) return callback ( new TypeError ( 'email or nickname is not a string|object::database.getUser(' + haystack + ',callback)' , module . filename ) ) ;
var User = models . user ;
let or = [ ] ;
if ( typeof haystack === 'string' ) {
or = [ { nickname : haystack } , { email : haystack } , { token : haystack } ] ;
if ( haystack . match ( /^[0-9a-fA-F]{24}$/ ) ) or . push ( { _id : haystack } ) ;
}
else {
or = [ ] ;
for ( let i = 0 ; i < haystack . length ; i ++ ) {
if ( haystack [ i ] . match ( /^[0-9a-fA-F]{24}$/ ) ) or . push ( { _id : haystack [ i ] } ) ;
or . push ( { nickname : haystack [ i ] } ) ;
or . push ( { email : haystack [ i ] } ) ;
or . push ( { token : haystack [ i ] } ) ;
}
}
User . find ( ) . or ( or )
. then ( ( users ) => {
if ( users . length > 0 )
return callback ( null , users ) ;
else
return callback ( null , false ) ;
} ) . catch ( ( err ) => {
return callback ( err ) ;
} ) ;
} ;
/ * *
* updates obj keys in user entry
* @ author Ruben Meyer
* @ param { Number } id User ID
* @ param { Object } obj data
* @ param { Function } callback Callback function
* /
methods . updateUserProfile = ( id , obj , callback ) => {
if ( typeof callback !== 'function' ) callback = function ( ) { } ;
if ( typeof id !== 'string' ) return callback ( new TypeError ( 'id is not a string::database.updateUserProfile(' + id + ',' + JSON . stringify ( obj ) + ',callback)' , module . filename ) ) ;
if ( typeof obj !== 'object' ) return callback ( new TypeError ( 'obj is not an object::database.updateUserProfile(' + id + ',' + JSON . stringify ( obj ) + ',callback)' , module . filename ) ) ;
var User = models . user ;
User . findByIdAndUpdate ( id , obj , ( err , data ) => {
if ( err ) callback ( err ) ;
else callback ( null , data ) ;
} ) ;
} ;
/ * *
* updates data based on login
* @ author Ruben Meyer
* @ param { Number } id User ID
* @ param { Object } options options JSON - > remember
* @ param { Function } callback Callback function ( date => 'Login Date' , token => 'RememberMe Cookie Token' )
* /
methods . updateNewAction = ( id , options , callback ) => {
if ( typeof callback !== 'function' ) callback = function ( ) { } ;
if ( typeof id !== 'string' ) return callback ( new TypeError ( 'id is not a string::database.updateNewAction(' + id + ',' + JSON . stringify ( options ) + ',callback)' , module . filename ) ) ;
if ( typeof options !== 'object' && options !== null ) return callback ( new TypeError ( 'obj is not an object::database.updateUserProfile(' + id + ',' + JSON . stringify ( obj ) + ',callback)' , module . filename ) ) ;
let date = new Date ( ) . toISOString ( ) ;
let timestamp = new Date ( date ) . getTime ( ) ;
functions . updateUserProfile ( id , {
last _action : date
} , ( err , rep ) => {
if ( err ) return callback ( err ) ;
if ( options . rememberme && options . new _token !== false ) {
var token = ( [ 1e7 ] + - 1e3 + - 4e3 + - 8e3 + - 1e11 ) . replace ( /[018]/g , ( c ) => ( c ^ crypto . randomBytes ( new Uint8Array ( 1 ) . length ) [ 0 ] & 15 >> c / 4 ) . toString ( 16 ) ) ;
var Remember = models . remember ;
Remember . findOneAndUpdate ( { userId : id } , { token : token , timestamp : Date . now ( ) } , { upsert : true } , ( err1 , data ) => {
if ( err1 ) callback ( err1 ) ;
return callback ( null , {
date : date ,
timestamp : timestamp ,
token : token
} ) ;
} ) ;
} else {
callback ( null , {
date : date ,
timestamp : timestamp ,
token : options . old _token
} ) ;
}
} ) ;
} ;
// //////// //////// //////// //////
// // // // // // // //
// //////// /////// //////// //////
// // // // // //
// // // // // //////
//
//////////////////////////////////////////////
/ * *
* get Applications
* @ author Ruben Meyer
* @ param { Function } callback Callback function ( err , apps )
* /
methods . getApps = ( callback ) => {
if ( typeof callback !== 'function' ) callback = function ( ) { } ;
var Application = models . application ;
Application . find ( { } , ( err , apps ) => {
if ( err ) callback ( err ) ;
else callback ( null , apps ) ;
} ) ;
} ;
/ * *
* return auth obj
* @ author Ruben Meyer
* @ param { Object } obj data obj ( aId , uId )
* @ param { Function } callback Callback function ( err , obj ) obj - > ( aId , uId , token )
* /
methods . setAuthCode = ( obj , callback ) => {
if ( typeof callback !== 'function' ) callback = function ( ) { } ;
if ( typeof obj !== 'object' ) return callback ( new TypeError ( 'obj is not an object::database.setAuthCode(' + JSON . stringify ( obj ) + ',callback)' , module . filename ) ) ;
var AuthCode = models . authCode ;
let query = {
applicationId : obj . aId ,
userId : obj . uId
} ;
let change = {
token : ( [ 1e7 ] + - 1e3 + - 4e3 + - 8e3 + - 1e11 ) . replace ( /[018]/g , ( c ) => ( c ^ crypto . randomBytes ( new Uint8Array ( 1 ) . length ) [ 0 ] & 15 >> c / 4 ) . toString ( 16 ) ) ,
timestamp : Date . now ( )
} ;
AuthCode . findOneAndUpdate ( query , change , { upsert : true } , ( err1 , data ) => {
if ( err1 ) callback ( err1 ) ;
return callback ( null , {
timestamp : change . timestamp ,
token : change . token
} ) ;
} ) ;
} ;
/ * *
* return auth obj
* @ author Ruben Meyer
* @ param { Object } obj data obj ( aId , aSecret , uId , token )
* @ param { Function } callback Callback function ( err , bool )
* /
methods . getAuth = ( obj , callback ) => {
if ( typeof callback !== 'function' ) callback = function ( ) { } ;
if ( typeof obj !== 'object' ) return callback ( new TypeError ( 'obj is not an object::database.getAuthCode(' + JSON . stringify ( obj ) + ',callback)' , module . filename ) ) ;
var AuthCode = models . authCode ;
AuthCode . findOne ( {
$and : [
{ applicationId : mongoose . Types . ObjectId ( obj . aId ) } ,
{ userId : mongoose . Types . ObjectId ( obj . uId ) } ,
{ token : obj . token }
]
} , ( err , data ) => {
if ( err ) callback ( err ) ;
else {
if ( typeof data === "object" ) {
if ( data === null || data === [ ] ) return callback ( null , false ) ;
var Application = models . application ;
Application . findOne ( {
$and : [
{ _id : mongoose . Types . ObjectId ( obj . aId ) } ,
{ secret : obj . aSecret }
]
} , ( err1 , data1 ) => {
if ( err1 ) callback ( err1 ) ;
else {
if ( obj . token == data . token
&& obj . aId == String ( data . applicationId )
&& obj . uId == String ( data . userId )
&& obj . aSecret == data1 . secret ) {
callback ( null , true ) ;
//functions.setAuthCode({
// aId: obj.aId,
// uId: obj.uId
//}, () => {});
}
else callback ( null , false ) ;
}
} ) ;
} else callback ( null , false ) ;
}
} ) ;
} ;
/ * *
* return if app is permitted to do access call
* @ author Ruben Meyer
* @ param { Object } obj data obj ( aId , redirectUrl )
* @ param { Function } callback Callback function ( err , bool )
* /
methods . verifyAppCall = ( obj , callback ) => {
} ;
// //////// //////// //////// //////// ////////
// // // // // // //
// //////// // // // // ////////
// // // //////// // //
// //////// // // // // ////////
//
////////////////////////////////////////////////////////
/ * *
* callback with user count
* @ author Ruben Meyer
* @ param { Function } callback Callback function ( reply - > int )
* /
methods . userCount = ( callback ) => {
if ( typeof callback !== 'function' ) callback = function ( ) { } ;
var User = models . user ;
User . countDocuments ( { } , ( err , count ) => {
callback ( ( err ) ? err : count ) ;
} ) ;
} ;
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
module . exports = methods ;