database module; partly outdated
This commit is contained in:
parent
f0c0d0223b
commit
815f058ffe
|
@ -15,7 +15,7 @@ $ DB_URL=mongodb://user:pass@ip:port/db DB_NAME=authRxbn NODE_ENV=debug node app
|
||||||
# TODO
|
# TODO
|
||||||
| title | description | - |
|
| title | description | - |
|
||||||
| ----- | ----------- | --- |
|
| ----- | ----------- | --- |
|
||||||
| database models | user, service, etc. pp. | - |
|
| database module | remove rememberMe part; add more stats methods | - |
|
||||||
| modules | database, authentication, etc. pp. | - |
|
| modules | database, authentication, etc. pp. | - |
|
||||||
| cli user management | get, add, modify, delete user data | - |
|
| cli user management | get, add, modify, delete user data | - |
|
||||||
| event handling | handle CLI events | - |
|
| event handling | handle CLI events | - |
|
||||||
|
|
9
app.js
9
app.js
|
@ -7,7 +7,7 @@
|
||||||
|
|
||||||
// GDS: Global Data System
|
// GDS: Global Data System
|
||||||
global['gds'] = {
|
global['gds'] = {
|
||||||
debug: (process.env.NODE_ENV === 'debug') ? 1 : 0,
|
debug: (process.env.NODE_ENV === 'debug') ? true : false,
|
||||||
db: null,
|
db: null,
|
||||||
cache: {},
|
cache: {},
|
||||||
cfg: require(__dirname+'/bin/config')
|
cfg: require(__dirname+'/bin/config')
|
||||||
|
@ -22,6 +22,13 @@ let load = (name) => {
|
||||||
return require(__dirname+'/bin/'+name+'/module');
|
return require(__dirname+'/bin/'+name+'/module');
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// environment variable check
|
||||||
|
if(typeof process.env.DB_URL == 'undefined' || typeof process.env.DB_NAME == 'undefined') {
|
||||||
|
if(typeof process.env.DB_URL == 'undefined') console.error("environment variable DB_URL is not set");
|
||||||
|
if(typeof process.env.DB_NAME == 'undefined') console.error("environment variable DB_NAME is not set");
|
||||||
|
process.exit();
|
||||||
|
}
|
||||||
|
|
||||||
global['modules'].events = load('events'); // event handler
|
global['modules'].events = load('events'); // event handler
|
||||||
global['modules'].cli = load('cli'); // command line interface
|
global['modules'].cli = load('cli'); // command line interface
|
||||||
global['modules'].logs = load('logs'); // log handler
|
global['modules'].logs = load('logs'); // log handler
|
||||||
|
|
|
@ -20,6 +20,7 @@ models.user = new Schema({
|
||||||
type: String,
|
type: String,
|
||||||
validate: [
|
validate: [
|
||||||
{ validator: function(value) {
|
{ validator: function(value) {
|
||||||
|
// @url: http://emailregex.com/
|
||||||
let regex = /^(([^<>()\[\]\.,;:\s@\"]+(\.[^<>()\[\]\.,;:\s@\"]+)*)|(\".+\"))@(([^<>()[\]\.,;:\s@\"]+\.)+[^<>()[\]\.,;:\s@\"]{2,})$/i;
|
let regex = /^(([^<>()\[\]\.,;:\s@\"]+(\.[^<>()\[\]\.,;:\s@\"]+)*)|(\".+\"))@(([^<>()[\]\.,;:\s@\"]+\.)+[^<>()[\]\.,;:\s@\"]{2,})$/i;
|
||||||
return regex.test(value);
|
return regex.test(value);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,345 @@
|
||||||
|
/*
|
||||||
|
* 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;
|
Loading…
Reference in New Issue