larvituser
Advanced tools
Comparing version 0.14.0 to 0.15.0
'use strict'; | ||
const EventEmitter = require('events').EventEmitter, | ||
eventEmitter = new EventEmitter(), | ||
topLogPrefix = 'larvituser: dataWriter.js - ', | ||
DbMigration = require('larvitdbmigration'), | ||
Intercom = require('larvitamintercom'), | ||
helpers = require(__dirname + '/helpers.js'), | ||
Helpers = require(__dirname + '/helpers.js'), | ||
uuidLib = require('uuid'), | ||
checkKey = require('check-object-key'), | ||
lUtils = require('larvitutils'), | ||
LUtils = require('larvitutils'), | ||
amsync = require('larvitamsync'), | ||
async = require('async'), | ||
log = require('winston'), | ||
db = require('larvitdb'); | ||
async = require('async'); | ||
let readyInProgress = false, | ||
isReady = false; | ||
function DataWriter(options, cb) { | ||
const that = this; | ||
function addUserDataFields(params, deliveryTag, msgUuid, cb) { | ||
const userUuidBuffer = lUtils.uuidToBuffer(params.userUuid), | ||
that.readyInProgress = false; | ||
that.isReady = false; | ||
if ( ! options.log) { | ||
const tmpLUtils = new LUtils(); | ||
options.log = new tmpLUtils.Log(); | ||
} | ||
that.options = options; | ||
for (const key of Object.keys(options)) { | ||
that[key] = options[key]; | ||
} | ||
that.lUtils = new LUtils({'log': that.log}); | ||
that.emitter = new EventEmitter(); | ||
that.listenToQueue(function (err) { | ||
if (err) return cb(err); | ||
that.helpers = new Helpers({ | ||
'dataWriter': that, | ||
'log': that.log, | ||
'db': that.db | ||
}); | ||
cb(); | ||
}); | ||
} | ||
DataWriter.prototype.addUserDataFields = function addUserDataFields(params, deliveryTag, msgUuid, cb) { | ||
const userUuidBuffer = this.lUtils.uuidToBuffer(params.userUuid), | ||
logPrefix = topLogPrefix + 'addUserDataFields() - ', | ||
dbValues = [], | ||
tasks = []; | ||
tasks = [], | ||
that = this; | ||
let sql = 'INSERT INTO user_users_data (userUuid, fieldUuid, data) VALUES'; | ||
let sql = 'INSERT INTO user_users_data (userUuid, fieldUuid, data) VALUES'; | ||
@@ -40,4 +67,4 @@ if (typeof deliveryTag === 'function') { | ||
const err = new Error('Invalid userUuid'); | ||
log.warn(logPrefix + err.message); | ||
if (msgUuid !== false) exports.emitter.emit(msgUuid, err); | ||
that.log.warn(logPrefix + err.message); | ||
if (msgUuid !== false) that.emitter.emit(msgUuid, err); | ||
return cb(err); | ||
@@ -48,7 +75,7 @@ } | ||
tasks.push(function (cb) { | ||
helpers.getFieldUuid(key, function (err, fieldUuid) { | ||
const fieldUuidBuffer = lUtils.uuidToBuffer(fieldUuid); | ||
that.helpers.getFieldUuid(key, function (err, fieldUuid) { | ||
const fieldUuidBuffer = that.lUtils.uuidToBuffer(fieldUuid); | ||
if (err) { | ||
log.warn(logPrefix + err.message); | ||
that.log.warn(logPrefix + err.message); | ||
return cb(err); | ||
@@ -59,3 +86,3 @@ } | ||
const err = new Error('Invalid fieldUuid'); | ||
log.warn(logPrefix + err.message); | ||
that.log.warn(logPrefix + err.message); | ||
return cb(err); | ||
@@ -86,15 +113,15 @@ } | ||
if (err) { | ||
log.warn(logPrefix + err.message); | ||
if (msgUuid !== false) exports.emitter.emit(msgUuid, err); | ||
that.log.warn(logPrefix + err.message); | ||
if (msgUuid !== false) that.emitter.emit(msgUuid, err); | ||
return cb(err); | ||
} | ||
sql = sql.substring(0, sql.length - 1); | ||
sql = sql.substring(0, sql.length - 1); | ||
if (dbValues.length === 0) { | ||
log.info(logPrefix + 'No fields or field data specifed'); | ||
that.log.info(logPrefix + 'No fields or field data specifed'); | ||
// We need to setImmediate here since a listener on the other side must be done async to obtain a msgUuid | ||
setImmediate(function () { | ||
if (msgUuid !== false) exports.emitter.emit(msgUuid); | ||
if (msgUuid !== false) that.emitter.emit(msgUuid); | ||
return cb(); | ||
@@ -105,15 +132,16 @@ }); | ||
db.query(sql, dbValues, function (err) { | ||
that.db.query(sql, dbValues, function (err) { | ||
if (err) { | ||
log.warn(topLogPrefix + 'addUserDataFields() - ' + err.message); | ||
that.log.warn(topLogPrefix + 'addUserDataFields() - ' + err.message); | ||
} | ||
if (msgUuid !== false) exports.emitter.emit(msgUuid, err); | ||
if (msgUuid !== false) that.emitter.emit(msgUuid, err); | ||
cb(err); | ||
}); | ||
}); | ||
} | ||
}; | ||
function addUserField(params, deliveryTag, msgUuid, cb) { | ||
const logPrefix = topLogPrefix + 'addUserField() - ', | ||
uuidBuffer = lUtils.uuidToBuffer(params.uuid), | ||
DataWriter.prototype.addUserField = function addUserField(params, deliveryTag, msgUuid, cb) { | ||
const uuidBuffer = this.lUtils.uuidToBuffer(params.uuid), | ||
logPrefix = topLogPrefix + 'addUserField() - ', | ||
that = this, | ||
name = params.name, | ||
@@ -123,34 +151,35 @@ sql = 'INSERT IGNORE INTO user_data_fields (uuid, name) VALUES(?,?)'; | ||
if (typeof cb !== 'function') { | ||
cb = function () {}; | ||
cb = function () {}; | ||
} | ||
if (uuidBuffer === false) { | ||
const e = new Error('Invalid field uuid'); | ||
log.warn(logPrefix + e.message); | ||
const err = new Error('Invalid field uuid'); | ||
that.log.warn(logPrefix + err.message); | ||
exports.emitter.emit(msgUuid, e); | ||
exports.emitter.emit('addedField_' + name, e); | ||
that.emitter.emit(msgUuid, err); | ||
that.emitter.emit('addedField_' + name, err); | ||
return cb(err); | ||
} | ||
db.query(sql, [uuidBuffer, name], function (err) { | ||
if (err) log.warn(logPrefix + err.message); | ||
that.db.query(sql, [uuidBuffer, name], function (err) { | ||
if (err) that.log.warn(logPrefix + err.message); | ||
exports.emitter.emit(msgUuid, err); | ||
exports.emitter.emit('addedField_' + name, err); | ||
that.emitter.emit(msgUuid, err); | ||
that.emitter.emit('addedField_' + name, err); | ||
cb(err); | ||
}); | ||
} | ||
}; | ||
function addUserFieldReq(params, deliveryTag, msgUuid, cb) { | ||
DataWriter.prototype.addUserFieldReq = function addUserFieldReq(params, deliveryTag, msgUuid, cb) { | ||
const logPrefix = topLogPrefix + 'addUserFieldReq() - ', | ||
fieldName = params.name; | ||
fieldName = params.name, | ||
that = this; | ||
if (typeof cb !== 'function') { | ||
cb = function () {}; | ||
cb = function () {}; | ||
} | ||
if (exports.mode === 'master') { | ||
if (that.mode === 'master' || that.mode === 'noSync') { | ||
function run() { | ||
if (exports.addUserFieldReqRunning === true) { | ||
if (that.addUserFieldReqRunning === true) { | ||
setTimeout(run, 10); | ||
@@ -160,7 +189,7 @@ return; | ||
exports.addUserFieldReqRunning = true; | ||
that.addUserFieldReqRunning = true; | ||
// Check if this is already set in the database | ||
db.query('SELECT uuid FROM user_data_fields WHERE name = ?', [fieldName], function (err, rows) { | ||
const options = {'exchange': exports.exchangeName}, | ||
that.db.query('SELECT uuid FROM user_data_fields WHERE name = ?', [fieldName], function (err, rows) { | ||
const options = {'exchange': that.exchangeName}, | ||
sendObj = {}; | ||
@@ -173,16 +202,16 @@ | ||
sendObj.params.name = fieldName; | ||
sendObj.params.uuid = (rows.length) ? lUtils.formatUuid(rows[0].uuid) : uuidLib.v1(); | ||
sendObj.params.uuid = (rows.length) ? that.lUtils.formatUuid(rows[0].uuid) : uuidLib.v1(); | ||
exports.emitter.once('addedField_' + fieldName, function (err) { | ||
that.emitter.once('addedField_' + fieldName, function (err) { | ||
if (err) return cb(err); | ||
exports.addUserFieldReqRunning = false; | ||
that.addUserFieldReqRunning = false; | ||
}); | ||
exports.intercom.send(sendObj, options, function (err, msgUuid2) { | ||
that.intercom.send(sendObj, options, function (err, msgUuid2) { | ||
if (err) return cb(err); | ||
exports.emitter.once(msgUuid2, function (err) { | ||
that.emitter.once(msgUuid2, function (err) { | ||
if (err) return cb(err); | ||
exports.emitter.emit(msgUuid, err); | ||
that.emitter.emit(msgUuid, err); | ||
@@ -196,14 +225,15 @@ cb(err); | ||
} else { | ||
log.debug(logPrefix + 'Ignoring since we are not master'); | ||
that.log.debug(logPrefix + 'Ignoring since we are not master or noSync'); | ||
} | ||
} | ||
}; | ||
function create(params, deliveryTag, msgUuid, cb) { | ||
const logPrefix = topLogPrefix + 'create() - ', | ||
DataWriter.prototype.create = function create(params, deliveryTag, msgUuid, cb) { | ||
const uuidBuffer = this.lUtils.uuidToBuffer(params.uuid), | ||
logPrefix = topLogPrefix + 'create() - ', | ||
dbFields = [], | ||
sql = 'INSERT IGNORE INTO user_users (uuid, username, password) VALUES(?,?,?);', | ||
uuidBuffer = lUtils.uuidToBuffer(params.uuid); | ||
that = this, | ||
sql = 'INSERT IGNORE INTO user_users (uuid, username, password) VALUES(?,?,?);'; | ||
if (cb === undefined || typeof cb !== 'function') { | ||
cb = function () {}; | ||
cb = function () {}; | ||
} | ||
@@ -216,15 +246,15 @@ | ||
if (uuidBuffer === false) { | ||
const err = new Error('Invalid user uuid supplied: "' + params.uuid + '", deliveryTag: "' + deliveryTag + '", msgUuid: "' + msgUuid + '"'); | ||
const err = new Error('Invalid user uuid supplied: "' + params.uuid + '", deliveryTag: "' + deliveryTag + '", msgUuid: "' + msgUuid + '"'); | ||
log.warn(logPrefix + err.message); | ||
exports.emitter.emit(msgUuid, err); | ||
that.log.warn(logPrefix + err.message); | ||
that.emitter.emit(msgUuid, err); | ||
return cb(err); | ||
} | ||
db.query(sql, dbFields, function (err, results) { | ||
const fieldsParams = {}; | ||
that.db.query(sql, dbFields, function (err, results) { | ||
const fieldsParams = {}; | ||
if (results.affectedRows === 0) { | ||
const err = new Error('No user created, duplicate key on uuid: "' + params.uuid + '" or username: "' + params.username + '"'); | ||
log.warn(logPrefix + err.message); | ||
that.log.warn(logPrefix + err.message); | ||
return cb(err); | ||
@@ -234,4 +264,4 @@ } | ||
if (err) { | ||
log.warn(logPrefix + err.message); | ||
exports.emitter.emit(msgUuid, err); | ||
that.log.warn(logPrefix + err.message); | ||
that.emitter.emit(msgUuid, err); | ||
return cb(err); | ||
@@ -243,25 +273,21 @@ } | ||
addUserDataFields(fieldsParams, function (err) { | ||
that.addUserDataFields(fieldsParams, function (err) { | ||
if (err) { | ||
log.warn(logPrefix + err.message); | ||
that.log.warn(logPrefix + err.message); | ||
} | ||
exports.emitter.emit(msgUuid, err); | ||
that.emitter.emit(msgUuid, err); | ||
cb(err); | ||
}); | ||
}); | ||
} | ||
}; | ||
function listenToQueue(retries, cb) { | ||
DataWriter.prototype.listenToQueue = function listenToQueue(cb) { | ||
const logPrefix = topLogPrefix + 'listenToQueue() - ', | ||
options = {'exchange': exports.exchangeName}, | ||
tasks = []; | ||
options = {'exchange': this.exchangeName}, | ||
tasks = [], | ||
that = this; | ||
let listenMethod; | ||
if (typeof retries === 'function') { | ||
cb = retries; | ||
retries = 0; | ||
} | ||
if (typeof cb !== 'function') { | ||
@@ -271,32 +297,4 @@ cb = function () {}; | ||
if (retries === undefined) { | ||
retries = 0; | ||
} | ||
tasks.push(function (cb) { | ||
checkKey({ | ||
'obj': exports, | ||
'objectKey': 'mode', | ||
'validValues': ['master', 'slave', 'noSync'], | ||
'default': 'master' | ||
}, function (err, warning) { | ||
if (warning) log.warn(logPrefix + warning); | ||
cb(err); | ||
}); | ||
}); | ||
tasks.push(function (cb) { | ||
checkKey({ | ||
'obj': exports, | ||
'objectKey': 'intercom', | ||
'default': new Intercom('loopback interface'), | ||
'defaultLabel': 'loopback interface' | ||
}, function (err, warning) { | ||
if (warning) log.warn(logPrefix + warning); | ||
cb(err); | ||
}); | ||
}); | ||
tasks.push(function (cb) { | ||
if (exports.mode === 'master') { | ||
if (that.mode === 'master') { | ||
listenMethod = 'consume'; | ||
@@ -307,11 +305,11 @@ options.exclusive = true; // It is important no other client tries to sneak | ||
// // minion goes offline. | ||
} else if (exports.mode === 'slave' || exports.mode === 'noSync') { | ||
listenMethod = 'subscribe'; | ||
} else if (that.mode === 'slave' || that.mode === 'noSync') { | ||
listenMethod = 'subscribe'; | ||
} else { | ||
const err = new Error('Invalid exports.mode. Must be either "master", "slave" or "noSync"'); | ||
log.error(logPrefix + err.message); | ||
const err = new Error('Invalid that.mode. Must be either "master", "slave" or "noSync"'); | ||
that.log.error(logPrefix + err.message); | ||
return cb(err); | ||
} | ||
log.info(logPrefix + 'listenMethod: ' + listenMethod); | ||
that.log.info(logPrefix + 'listenMethod: ' + listenMethod); | ||
cb(); | ||
@@ -321,14 +319,14 @@ }); | ||
tasks.push(function (cb) { | ||
exports.intercom.ready(function (err) { | ||
that.intercom.ready(function (err) { | ||
if (err) { | ||
log.error(logPrefix + 'intercom.ready() err: ' + err.message); | ||
that.log.error(logPrefix + 'intercom.ready() err: ' + err.message); | ||
return; | ||
} | ||
exports.intercom[listenMethod](options, function (message, ack, deliveryTag) { | ||
exports.ready(function (err) { | ||
that.intercom[listenMethod](options, function (message, ack, deliveryTag) { | ||
that.ready(function (err) { | ||
ack(err); // Ack first, if something goes wrong we log it and handle it manually | ||
if (err) { | ||
log.error(logPrefix + 'intercom.' + listenMethod + '() - exports.ready() returned err: ' + err.message); | ||
that.log.error(logPrefix + 'intercom.' + listenMethod + '() - that.ready() returned err: ' + err.message); | ||
return; | ||
@@ -338,10 +336,10 @@ } | ||
if (typeof message !== 'object') { | ||
log.error(logPrefix + 'intercom.' + listenMethod + '() - Invalid message received, is not an object! deliveryTag: "' + deliveryTag + '"'); | ||
that.log.error(logPrefix + 'intercom.' + listenMethod + '() - Invalid message received, is not an object! deliveryTag: "' + deliveryTag + '"'); | ||
return; | ||
} | ||
if (typeof exports[message.action] === 'function') { | ||
exports[message.action](message.params, deliveryTag, message.uuid); | ||
if (typeof that[message.action] === 'function') { | ||
that[message.action](message.params, deliveryTag, message.uuid); | ||
} else { | ||
log.warn(logPrefix + 'intercom.' + listenMethod + '() - Unknown message.action received: "' + message.action + '"'); | ||
that.log.warn(logPrefix + 'intercom.' + listenMethod + '() - Unknown message.action received: "' + message.action + '"'); | ||
} | ||
@@ -354,18 +352,14 @@ }); | ||
// Run the ready function | ||
tasks.push(ready); | ||
tasks.push(function (cb) { | ||
that.ready(cb); | ||
}); | ||
async.series(tasks, cb); | ||
} | ||
// Run listenToQueue as soon as all I/O is done, this makes sure the exports.mode can be set | ||
// by the application before listening commences | ||
setImmediate(listenToQueue); | ||
}; | ||
function ready(retries, cb) { | ||
const logPrefix = topLogPrefix + 'ready() - ', | ||
tasks = []; | ||
DataWriter.prototype.ready = function ready(cb) { | ||
const that = this, | ||
logPrefix = topLogPrefix + 'ready() - '; | ||
if (typeof retries === 'function') { | ||
cb = retries; | ||
retries = 0; | ||
} | ||
let dbMigration; | ||
@@ -376,82 +370,32 @@ if (typeof cb !== 'function') { | ||
if (retries === undefined) { | ||
retries = 0; | ||
} | ||
if (that.isReady === true) return cb(); | ||
if (isReady === true) return cb(); | ||
if (readyInProgress === true) { | ||
eventEmitter.on('ready', cb); | ||
if (that.readyInProgress === true) { | ||
that.emitter.on('ready', cb); | ||
return; | ||
} | ||
readyInProgress = true; | ||
that.readyInProgress = true; | ||
tasks.push(function (cb) { | ||
checkKey({ | ||
'obj': exports, | ||
'objectKey': 'mode', | ||
'validValues': ['master', 'slave', 'noSync'], | ||
'default': 'noSync' | ||
}, function (err, warning) { | ||
if (warning) log.warn(logPrefix + warning); | ||
cb(err); | ||
}); | ||
}); | ||
that.log.debug(logPrefix + 'Waiting for dbmigration()'); | ||
tasks.push(function (cb) { | ||
checkKey({ | ||
'obj': exports, | ||
'objectKey': 'intercom', | ||
'default': new Intercom('loopback interface'), | ||
'defaultLabel': 'loopback interface' | ||
}, function (err, warning) { | ||
if (warning) log.warn(logPrefix + warning); | ||
cb(err); | ||
}); | ||
dbMigration = new DbMigration({ | ||
'log': that.log, | ||
'dbType': 'mariadb', | ||
'dbDriver': that.db, | ||
'tableName': 'users_db_version', | ||
'migrationScriptsPath': __dirname + '/dbmigration' | ||
}); | ||
tasks.push(function (cb) { | ||
if (exports.mode === 'slave') { | ||
log.verbose(logPrefix + 'exports.mode: "' + exports.mode + '", so read'); | ||
amsync.mariadb({ | ||
'exchange': exports.exchangeName + '_dataDump', | ||
'intercom': exports.intercom | ||
}, cb); | ||
} else { | ||
cb(); | ||
dbMigration.run(function (err) { | ||
if (err) { | ||
that.log.error(logPrefix + err.message); | ||
return cb(err); | ||
} | ||
}); | ||
// Migrate database | ||
tasks.push(function (cb) { | ||
const options = {}; | ||
that.isReady = true; | ||
that.emitter.emit('ready'); | ||
let dbMigration; | ||
log.debug(logPrefix + 'Waiting for dbmigration()'); | ||
options.dbType = 'larvitdb'; | ||
options.dbDriver = db; | ||
options.tableName = 'users_db_version'; | ||
options.migrationScriptsPath = __dirname + '/dbmigration'; | ||
dbMigration = new DbMigration(options); | ||
dbMigration.run(function (err) { | ||
if (err) { | ||
log.error(logPrefix + err.message); | ||
} | ||
cb(err); | ||
}); | ||
}); | ||
async.series(tasks, function (err) { | ||
if (err) return; | ||
isReady = true; | ||
eventEmitter.emit('ready'); | ||
if (exports.mode === 'master') { | ||
runDumpServer(cb); | ||
if (that.mode === 'master') { | ||
that.runDumpServer(cb); | ||
} else { | ||
@@ -461,12 +405,13 @@ cb(); | ||
}); | ||
} | ||
}; | ||
function replaceFields(params, deliveryTag, msgUuid, cb) { | ||
DataWriter.prototype.replaceFields = function replaceFields(params, deliveryTag, msgUuid, cb) { | ||
const fieldNamesToUuidBufs = {}, | ||
userUuidBuf = lUtils.uuidToBuffer(params.userUuid), | ||
userUuidBuf = this.lUtils.uuidToBuffer(params.userUuid), | ||
logPrefix = topLogPrefix + 'replaceFields() - ', | ||
tasks = []; | ||
tasks = [], | ||
that = this; | ||
if (cb === undefined || typeof cb !== 'function') { | ||
cb = function () {}; | ||
cb = function () {}; | ||
} | ||
@@ -477,4 +422,4 @@ | ||
log.warn(logPrefix + err.message); | ||
exports.emitter.emit(msgUuid, err); | ||
that.log.warn(logPrefix + err.message); | ||
that.emitter.emit(msgUuid, err); | ||
return cb(err); | ||
@@ -485,3 +430,3 @@ } | ||
tasks.push(function (cb) { | ||
db.query('SELECT * FROM user_users WHERE uuid = ?', userUuidBuf, function (err, rows) { | ||
that.db.query('SELECT * FROM user_users WHERE uuid = ?', userUuidBuf, function (err, rows) { | ||
if (err) return cb(err); | ||
@@ -491,3 +436,3 @@ | ||
const err = new Error('Invalid user uuid: "' + params.userUuid + '", no records found in database of this user'); | ||
log.warn(logPrefix + err.message); | ||
that.log.warn(logPrefix + err.message); | ||
return cb(err); | ||
@@ -502,3 +447,3 @@ } | ||
tasks.push(function (cb) { | ||
db.query('DELETE FROM user_users_data WHERE userUuid = ?', [userUuidBuf], cb); | ||
that.db.query('DELETE FROM user_users_data WHERE userUuid = ?', [userUuidBuf], cb); | ||
}); | ||
@@ -512,9 +457,9 @@ | ||
tasks.push(function (cb) { | ||
helpers.getFieldUuid(fieldName, function (err, fieldUuid) { | ||
fieldNamesToUuidBufs[fieldName] = lUtils.uuidToBuffer(fieldUuid); | ||
that.helpers.getFieldUuid(fieldName, function (err, fieldUuid) { | ||
fieldNamesToUuidBufs[fieldName] = that.lUtils.uuidToBuffer(fieldUuid); | ||
if (fieldNamesToUuidBufs[fieldName] === false) { | ||
const e = new Error('Invalid field uuid'); | ||
log.warn(logPrefix + e.message); | ||
return cb(e); | ||
const err = new Error('Invalid field uuid'); | ||
that.log.warn(logPrefix + err.message); | ||
return cb(err); | ||
} | ||
@@ -534,3 +479,3 @@ | ||
let sql = 'INSERT INTO user_users_data (userUuid, fieldUuid, data) VALUES'; | ||
let sql = 'INSERT INTO user_users_data (userUuid, fieldUuid, data) VALUES'; | ||
@@ -541,3 +486,3 @@ if ( ! params.fields) return cb(); | ||
if ( ! (params.fields[fieldName] instanceof Array)) { | ||
params.fields[fieldName] = [params.fields[fieldName]]; | ||
params.fields[fieldName] = [params.fields[fieldName]]; | ||
} | ||
@@ -555,29 +500,30 @@ | ||
sql = sql.substring(0, sql.length - 1) + ';'; | ||
sql = sql.substring(0, sql.length - 1) + ';'; | ||
if (dbFields.length === 0) return cb(); | ||
db.query(sql, dbFields, cb); | ||
that.db.query(sql, dbFields, cb); | ||
}); | ||
async.series(tasks, function (err) { | ||
if (err) log.warn(logPrefix + err.message); | ||
exports.emitter.emit(msgUuid, err); | ||
if (err) that.log.warn(logPrefix + err.message); | ||
that.emitter.emit(msgUuid, err); | ||
cb(err); | ||
}); | ||
} | ||
}; | ||
function rmUser(params, deliveryTag, msgUuid, cb) { | ||
const logPrefix = topLogPrefix + 'rmUser() - ', | ||
DataWriter.prototype.rmUser = function rmUser(params, deliveryTag, msgUuid, cb) { | ||
const uuidBuffer = this.lUtils.uuidToBuffer(params.userUuid), | ||
logPrefix = topLogPrefix + 'rmUser() - ', | ||
tasks = [], | ||
uuidBuffer = lUtils.uuidToBuffer(params.userUuid); | ||
that = this; | ||
if (cb === undefined || typeof cb !== 'function') { | ||
cb = function () {}; | ||
cb = function () {}; | ||
} | ||
if (uuidBuffer === false) { | ||
const err = new Error('Invalid user uuid'); | ||
log.warn(logPrefix + err.message); | ||
exports.emitter.emit(msgUuid, err); | ||
const err = new Error('Invalid user uuid'); | ||
that.log.warn(logPrefix + err.message); | ||
that.emitter.emit(msgUuid, err); | ||
return cb(err); | ||
@@ -589,3 +535,3 @@ } | ||
db.query(sql, [uuidBuffer], cb); | ||
that.db.query(sql, [uuidBuffer], cb); | ||
}); | ||
@@ -596,26 +542,27 @@ | ||
db.query(sql, [uuidBuffer], cb); | ||
that.db.query(sql, [uuidBuffer], cb); | ||
}); | ||
async.series(tasks, function (err) { | ||
if (err) log.warn(logPrefix + err.message); | ||
exports.emitter.emit(msgUuid, err); | ||
if (err) that.log.warn(logPrefix + err.message); | ||
that.emitter.emit(msgUuid, err); | ||
cb(err); | ||
}); | ||
} | ||
}; | ||
function rmUserField(params, deliveryTag, msgUuid, cb) { | ||
const logPrefix = topLogPrefix + 'rmUserField() - '; | ||
DataWriter.prototype.rmUserField = function rmUserField(params, deliveryTag, msgUuid, cb) { | ||
const logPrefix = topLogPrefix + 'rmUserField() - ', | ||
that = this; | ||
if (cb === undefined || typeof cb !== 'function') { | ||
cb = function () {}; | ||
cb = function () {}; | ||
} | ||
helpers.getFieldUuid(params.fieldName, function (err, fieldUuid) { | ||
const userUuidBuffer = lUtils.uuidToBuffer(params.userUuid), | ||
fieldUuidBuffer = lUtils.uuidToBuffer(fieldUuid), | ||
that.helpers.getFieldUuid(params.fieldName, function (err, fieldUuid) { | ||
const userUuidBuffer = that.lUtils.uuidToBuffer(params.userUuid), | ||
fieldUuidBuffer = that.lUtils.uuidToBuffer(fieldUuid), | ||
sql = 'DELETE FROM user_users_data WHERE userUuid = ? AND fieldUuid = ?'; | ||
if (err) { | ||
exports.emitter.emit(msgUuid, err); | ||
that.emitter.emit(msgUuid, err); | ||
return; | ||
@@ -625,42 +572,46 @@ } | ||
if (userUuidBuffer === false) { | ||
const e = new Error('Invalid user uuid'); | ||
log.warn(logPrefix + e.message); | ||
exports.emitter.emit(msgUuid, err); | ||
return cb(e); | ||
const err = new Error('Invalid user uuid'); | ||
that.log.warn(logPrefix + err.message); | ||
that.emitter.emit(msgUuid, err); | ||
return cb(err); | ||
} | ||
if (fieldUuidBuffer === false) { | ||
const e = new Error('Invalid field uuid'); | ||
log.warn(logPrefix + e.message); | ||
exports.emitter.emit(msgUuid, err); | ||
return cb(e); | ||
const err = new Error('Invalid field uuid'); | ||
that.log.warn(logPrefix + err.message); | ||
that.emitter.emit(msgUuid, err); | ||
return cb(err); | ||
} | ||
db.query(sql, [userUuidBuffer, fieldUuidBuffer], function (err) { | ||
if (err) log.warn(logPrefix + err.message); | ||
exports.emitter.emit(msgUuid, err); | ||
that.db.query(sql, [userUuidBuffer, fieldUuidBuffer], function (err) { | ||
if (err) that.log.warn(logPrefix + err.message); | ||
that.emitter.emit(msgUuid, err); | ||
cb(err); | ||
}); | ||
}); | ||
} | ||
}; | ||
function runDumpServer(cb) { | ||
const args = [], | ||
options = { | ||
'exchange': exports.exchangeName + '_dataDump', | ||
'host': (exports.amsync && exports.amsync.host) ? exports.amsync.host : null, | ||
'minPort': (exports.amsync && exports.amsync.minPort) ? exports.amsync.minPort : null, | ||
'maxPort': (exports.amsync && exports.amsync.maxPort) ? exports.amsync.maxPort : null | ||
DataWriter.prototype.runDumpServer = function runDumpServer(cb) { | ||
const that = this, | ||
args = [], | ||
options = { | ||
'Content-Type': 'application/sql', | ||
'exchange': that.exchangeName + '_dataDump', | ||
'intercom': that.intercom, | ||
'minPort': (that.amsync && that.amsync.minPort) ? that.amsync.minPort : null, | ||
'maxPort': (that.amsync && that.amsync.maxPort) ? that.amsync.maxPort : null, | ||
'host': (that.amsync && that.amsync.host) ? that.amsync.host : null, | ||
'log': that.log, | ||
}; | ||
if (db.conf.host) { | ||
if (that.db.conf.host) { | ||
args.push('-h'); | ||
args.push(db.conf.host); | ||
args.push(that.db.conf.host); | ||
} | ||
args.push('-u'); | ||
args.push(db.conf.user); | ||
args.push(that.db.conf.user); | ||
if (db.conf.password) { | ||
args.push('-p' + db.conf.password); | ||
if (that.db.conf.password) { | ||
args.push('-p' + that.db.conf.password); | ||
} | ||
@@ -670,3 +621,3 @@ | ||
args.push('--hex-blob'); | ||
args.push(db.conf.database); | ||
args.push(that.db.conf.database); | ||
@@ -685,23 +636,21 @@ // Tables | ||
options['Content-Type'] = 'application/sql'; | ||
options.intercom = exports.intercom; | ||
new amsync.SyncServer(options, cb); | ||
} | ||
}; | ||
function setPassword(params, deliveryTag, msgUuid, cb) { | ||
DataWriter.prototype.setPassword = function setPassword(params, deliveryTag, msgUuid, cb) { | ||
const logPrefix = topLogPrefix + 'setPassword() - ', | ||
dbFields = [], | ||
userUuidBuffer = lUtils.uuidToBuffer(params.userUuid), | ||
userUuidBuffer = this.lUtils.uuidToBuffer(params.userUuid), | ||
that = this, | ||
sql = 'UPDATE user_users SET password = ? WHERE uuid = ?;'; | ||
if (cb === undefined || typeof cb !== 'function') { | ||
cb = function () {}; | ||
cb = function () {}; | ||
} | ||
if (userUuidBuffer === false) { | ||
const e = new Error('Invalid user uuid'); | ||
log.warn(logPrefix + e.message); | ||
exports.emitter.emit(msgUuid, err); | ||
return cb(e); | ||
const err = new Error('Invalid user uuid'); | ||
that.log.warn(logPrefix + err.message); | ||
that.emitter.emit(msgUuid, err); | ||
return cb(err); | ||
} | ||
@@ -716,45 +665,34 @@ | ||
dbFields.push(userUuidBuffer); | ||
db.query(sql, dbFields, function (err) { | ||
if (err) log.warn(logPrefix + err.message); | ||
exports.emitter.emit(msgUuid, err); | ||
that.db.query(sql, dbFields, function (err) { | ||
if (err) that.log.warn(logPrefix + err.message); | ||
that.emitter.emit(msgUuid, err); | ||
cb(err); | ||
}); | ||
} | ||
}; | ||
function setUsername(params, deliveryTag, msgUuid, cb) { | ||
DataWriter.prototype.setUsername = function setUsername(params, deliveryTag, msgUuid, cb) { | ||
const logPrefix = topLogPrefix + 'setUsername() - ', | ||
userUuidBuffer = lUtils.uuidToBuffer(params.userUuid), | ||
userUuidBuffer = this.lUtils.uuidToBuffer(params.userUuid), | ||
dbFields = [params.username, userUuidBuffer], | ||
that = this, | ||
sql = 'UPDATE user_users SET username = ? WHERE uuid = ?;'; | ||
if (cb === undefined || typeof cb !== 'function') { | ||
cb = function () {}; | ||
cb = function () {}; | ||
} | ||
if (userUuidBuffer === false) { | ||
const e = new Error('Invalid user uuid'); | ||
log.warn(logPrefix + e.message); | ||
exports.emitter.emit(msgUuid, err); | ||
return cb(e); | ||
const err = new Error('Invalid user uuid'); | ||
that.log.warn(logPrefix + err.message); | ||
that.emitter.emit(msgUuid, err); | ||
return cb(err); | ||
} | ||
db.query(sql, dbFields, function (err) { | ||
if (err) log.warn(logPrefix + err.message); | ||
exports.emitter.emit(msgUuid, err); | ||
that.db.query(sql, dbFields, function (err) { | ||
if (err) that.log.warn(logPrefix + err.message); | ||
that.emitter.emit(msgUuid, err); | ||
cb(err); | ||
}); | ||
} | ||
}; | ||
exports.addUserDataFields = addUserDataFields; | ||
exports.addUserField = addUserField; | ||
exports.addUserFieldReq = addUserFieldReq; | ||
exports.create = create; | ||
exports.emitter = new EventEmitter(); | ||
exports.exchangeName = 'larvituser'; | ||
exports.options = undefined; | ||
exports.ready = ready; | ||
exports.replaceFields = replaceFields; | ||
exports.rmUser = rmUser; | ||
exports.rmUserField = rmUserField; | ||
exports.setPassword = setPassword; | ||
exports.setUsername = setUsername; | ||
exports = module.exports = DataWriter; |
132
helpers.js
'use strict'; | ||
const lUtils = require('larvitutils'), | ||
db = require('larvitdb'); | ||
const topLogPrefix = 'larvituser: helpers.js - ', | ||
LUtils = require('larvitutils'); | ||
let dataWriter; | ||
function Helpers(options) { | ||
const logPrefix = topLogPrefix + 'Helpers() - ', | ||
that = this; | ||
if ( ! options.log) { | ||
const tmpLUtils = new LUtils(); | ||
options.log = new tmpLUtils.Log(); | ||
} | ||
that.options = options; | ||
for (const key of Object.keys(options)) { | ||
that[key] = options[key]; | ||
} | ||
that.lUtils = new LUtils({'log': that.log}); | ||
if ( ! that.log) { | ||
const err = new Error('Required option log not set'); | ||
that.log.error(logPrefix + err.message); | ||
throw err; | ||
} | ||
if ( ! that.dataWriter) { | ||
const err = new Error('Required option dataWriter not set'); | ||
that.log.error(logPrefix + err.message); | ||
throw err; | ||
} | ||
if ( ! that.db) { | ||
const err = new Error('Required option db not set'); | ||
that.log.error(logPrefix + err.message); | ||
throw err; | ||
} | ||
} | ||
/** | ||
@@ -14,23 +48,24 @@ * Get field name by uuid | ||
*/ | ||
function getFieldName(uuid, cb) { | ||
ready(function () { | ||
const fieldUuidBuffer = lUtils.uuidToBuffer(uuid), | ||
sql = 'SELECT name FROM user_data_fields WHERE uuid = ?'; | ||
Helpers.prototype.getFieldName = function getFieldName(uuid, cb) { | ||
const fieldUuidBuffer = this.lUtils.uuidToBuffer(uuid), | ||
logPrefix = topLogPrefix + 'getFieldName() - ', | ||
that = this, | ||
sql = 'SELECT name FROM user_data_fields WHERE uuid = ?'; | ||
if (fieldUuidBuffer === false) { | ||
const e = new Error('Invalid field uuid'); | ||
return cb(e); | ||
} | ||
if (fieldUuidBuffer === false) { | ||
const err = new Error('Invalid field uuid'); | ||
that.log.verbose(logPrefix + err.message); | ||
return cb(err); | ||
} | ||
db.query(sql, [fieldUuidBuffer], function (err, rows) { | ||
if (err) { cb(err); return; } | ||
that.db.query(sql, [fieldUuidBuffer], function (err, rows) { | ||
if (err) return cb(err); | ||
if (rows.length) { | ||
cb(null, rows[0].name); | ||
} else { | ||
cb(null, false); | ||
} | ||
}); | ||
if (rows.length) { | ||
cb(null, rows[0].name); | ||
} else { | ||
cb(null, false); | ||
} | ||
}); | ||
} | ||
}; | ||
@@ -43,42 +78,35 @@ /** | ||
*/ | ||
function getFieldUuid(fieldName, cb) { | ||
ready(function () { | ||
const dbFields = [], | ||
sql = 'SELECT uuid FROM user_data_fields WHERE name = ?'; | ||
Helpers.prototype.getFieldUuid = function getFieldUuid(fieldName, cb) { | ||
const dbFields = [], | ||
that = this, | ||
sql = 'SELECT uuid FROM user_data_fields WHERE name = ?'; | ||
fieldName = fieldName.trim(); | ||
dbFields.push(fieldName); | ||
fieldName = fieldName.trim(); | ||
dbFields.push(fieldName); | ||
db.query(sql, dbFields, function (err, rows) { | ||
if (err) { cb(err); return; } | ||
that.db.query(sql, dbFields, function (err, rows) { | ||
if (err) return cb(err); | ||
if (rows.length) { | ||
cb(null, lUtils.formatUuid(rows[0].uuid)); | ||
} else { | ||
const options = {'exchange': dataWriter.exchangeName}, | ||
sendObj = {}; | ||
if (rows.length) { | ||
cb(null, that.lUtils.formatUuid(rows[0].uuid)); | ||
} else { | ||
const options = {'exchange': that.dataWriter.exchangeName}, | ||
sendObj = {}; | ||
sendObj.action = 'addUserFieldReq'; | ||
sendObj.params = {}; | ||
sendObj.params.name = fieldName; | ||
sendObj.action = 'addUserFieldReq'; | ||
sendObj.params = {}; | ||
sendObj.params.name = fieldName; | ||
dataWriter.intercom.send(sendObj, options, function (err) { | ||
if (err) { cb(err); return; } | ||
that.dataWriter.intercom.send(sendObj, options, function (err) { | ||
if (err) return cb(err); | ||
dataWriter.emitter.once('addedField_' + fieldName, function (err) { | ||
if (err) { cb(err); return; } | ||
getFieldUuid(fieldName, cb); | ||
}); | ||
that.dataWriter.emitter.once('addedField_' + fieldName, function (err) { | ||
if (err) return cb(err); | ||
that.getFieldUuid(fieldName, cb); | ||
}); | ||
} | ||
}); | ||
}); | ||
} | ||
}); | ||
} | ||
}; | ||
function ready(cb) { | ||
dataWriter = require(__dirname + '/dataWriter.js'); // We must do this here since it might not be instanciated on module load | ||
dataWriter.ready(cb); | ||
} | ||
exports.getFieldName = getFieldName; | ||
exports.getFieldUuid = getFieldUuid; | ||
exports = module.exports = Helpers; |
798
index.js
'use strict'; | ||
const topLogPrefix = 'larvituser: index.js: ', | ||
dataWriter = require(__dirname + '/dataWriter.js'), | ||
DataWriter = require(__dirname + '/dataWriter.js'), | ||
Intercom = require('larvitamintercom'), | ||
uuidLib = require('uuid'), | ||
lUtils = require('larvitutils'), | ||
Helpers = require(__dirname + '/helpers.js'), | ||
LUtils = require('larvitutils'), | ||
bcrypt = require('bcryptjs'), | ||
async = require('async'), | ||
log = require('winston'), | ||
db = require('larvitdb'); | ||
async = require('async'); | ||
function User(options, cb) { | ||
const logPrefix = topLogPrefix + 'User() - ', | ||
that = this; | ||
that.options = options || {}; | ||
if ( ! options.log) { | ||
const tmpLUtils = new LUtils(); | ||
options.log = new tmpLUtils.Log(); | ||
} | ||
that.options = options; | ||
for (const key of Object.keys(options)) { | ||
that[key] = options[key]; | ||
} | ||
that.lUtils = new LUtils({'log': that.log}); | ||
if ( ! that.db) { | ||
const err = new Error('Required option db is missing'); | ||
that.log.error(logPrefix + err.message); | ||
throw err; | ||
} | ||
if ( ! that.exchangeName) { | ||
that.exchangeName = 'larvituser'; | ||
} | ||
if ( ! that.mode) { | ||
that.log.info(logPrefix + 'No "mode" option given, defaulting to "noSync"'); | ||
that.mode = 'noSync'; | ||
} else if (['noSync', 'master', 'slave'].indexOf(that.mode) === - 1) { | ||
const err = new Error('Invalid "mode" option given: "' + that.mode + '"'); | ||
that.log.error(logPrefix + err.message); | ||
throw err; | ||
} | ||
if ( ! that.intercom) { | ||
that.log.info(logPrefix + 'No "intercom" option given, defaulting to "loopback interface"'); | ||
that.intercom = new Intercom('loopback interface'); | ||
} | ||
that.dataWriter = new DataWriter({ | ||
'exchangeName': that.exchangeName, | ||
'intercom': that.intercom, | ||
'mode': that.mode, | ||
'log': that.log, | ||
'db': that.db, | ||
'amsync_host': that.options.amsync_host || null, | ||
'amsync_minPort': that.options.amsync_minPort || null, | ||
'amsync_maxPort': that.options.amsync_maxPort || null | ||
}, function (err) { | ||
if (err) return cb(err); | ||
that.helpers = new Helpers({ | ||
'dataWriter': that.dataWriter, | ||
'log': that.log, | ||
'db': that.db | ||
}); | ||
cb(); | ||
}); | ||
}; | ||
/** | ||
@@ -20,9 +85,10 @@ * Add a single user field to database | ||
*/ | ||
function addUserDataField(userUuid, fieldName, fieldValue, cb) { | ||
const fields = {}; | ||
User.prototype.addUserDataField = function addUserDataField(userUuid, fieldName, fieldValue, cb) { | ||
const fields = {}, | ||
that = this; | ||
fields[fieldName] = fieldValue; | ||
fields[fieldName] = fieldValue; | ||
addUserDataFields(userUuid, fields, cb); | ||
} | ||
that.addUserDataFields(userUuid, fields, cb); | ||
}; | ||
@@ -36,22 +102,19 @@ /** | ||
*/ | ||
function addUserDataFields(userUuid, fields, cb) { | ||
dataWriter.ready(function (err) { | ||
const options = {'exchange': dataWriter.exchangeName}, | ||
sendObj = {}; | ||
User.prototype.addUserDataFields = function addUserDataFields(userUuid, fields, cb) { | ||
const options = {'exchange': this.exchangeName}, | ||
sendObj = {}, | ||
that = this; | ||
if (err) return cb(err); | ||
// do not want to broadcast msg on queue for no reason | ||
if ( ! fields || Object.keys(fields).length === 0) return cb(); | ||
// do not want to broadcast msg on queue for no reason | ||
if ( ! fields || Object.keys(fields).length === 0) return cb(); | ||
sendObj.action = 'addUserDataFields'; | ||
sendObj.params = {}; | ||
sendObj.params.userUuid = userUuid; | ||
sendObj.params.fields = fields; | ||
sendObj.action = 'addUserDataFields'; | ||
sendObj.params = {}; | ||
sendObj.params.userUuid = userUuid; | ||
sendObj.params.fields = fields; | ||
that.intercom.send(sendObj, options, function (err, msgUuid) { | ||
if (err) return cb(err); | ||
dataWriter.intercom.send(sendObj, options, function (err, msgUuid) { | ||
if (err) return cb(err); | ||
dataWriter.emitter.once(msgUuid, cb); | ||
}); | ||
that.dataWriter.emitter.once(msgUuid, cb); | ||
}); | ||
@@ -66,10 +129,11 @@ }; | ||
*/ | ||
function checkPassword(password, hash, cb) { | ||
const logPrefix = topLogPrefix + 'checkPassword() - '; | ||
User.prototype.checkPassword = function checkPassword(password, hash, cb) { | ||
const logPrefix = topLogPrefix + 'checkPassword() - ', | ||
that = this; | ||
password = password.trim(); | ||
password = password.trim(); | ||
bcrypt.compare(password, hash, function (err, result) { | ||
if (err) { | ||
log.error(logPrefix + err.message); | ||
that.log.error(logPrefix + err.message); | ||
} | ||
@@ -79,3 +143,3 @@ | ||
}); | ||
} | ||
}; | ||
@@ -91,5 +155,6 @@ /** | ||
*/ | ||
function create(username, password, userData, uuid, cb) { | ||
User.prototype.create = function create(username, password, userData, uuid, cb) { | ||
const logPrefix = topLogPrefix + 'create() - ', | ||
tasks = []; | ||
tasks = [], | ||
that = this; | ||
@@ -102,5 +167,5 @@ let hashedPassword; | ||
} else if (typeof userData === 'function') { | ||
cb = userData; | ||
userData = undefined; | ||
uuid = uuidLib.v1(); | ||
cb = userData; | ||
} | ||
@@ -113,9 +178,9 @@ | ||
if (uuid === undefined) { | ||
uuid = uuidLib.v1(); | ||
uuid = uuidLib.v1(); | ||
} | ||
username = username.trim(); | ||
username = username.trim(); | ||
if (password) { | ||
password = password.trim(); | ||
password = password.trim(); | ||
} | ||
@@ -125,15 +190,13 @@ | ||
const err = new Error('Trying to create user with empty username'); | ||
log.warn(logPrefix + err.message); | ||
that.log.warn(logPrefix + err.message); | ||
return cb(err); | ||
} | ||
tasks.push(dataWriter.ready); | ||
// Check for username availability | ||
tasks.push(function (cb) { | ||
usernameAvailable(username, function (err, result) { | ||
that.usernameAvailable(username, function (err, result) { | ||
if (err) return cb(err); | ||
if (result === true) { | ||
log.debug(logPrefix + 'Username available: "' + username + '"'); | ||
that.log.debug(logPrefix + 'Username available: "' + username + '"'); | ||
cb(); | ||
@@ -143,3 +206,3 @@ } else { | ||
log.info(logPrefix + err.message); | ||
that.log.info(logPrefix + err.message); | ||
cb(err); | ||
@@ -153,3 +216,3 @@ } | ||
if (password === false) { | ||
log.debug(logPrefix + 'Password set to empty string for no-login, username: "' + username + '"'); | ||
that.log.debug(logPrefix + 'Password set to empty string for no-login, username: "' + username + '"'); | ||
hashedPassword = ''; | ||
@@ -159,7 +222,7 @@ return cb(); | ||
hashPassword(password, function (err, hash) { | ||
that.hashPassword(password, function (err, hash) { | ||
if (err) return cb(err); | ||
hashedPassword = hash; | ||
log.debug(logPrefix + 'Password hashed, username: "' + username + '"'); | ||
that.log.debug(logPrefix + 'Password hashed, username: "' + username + '"'); | ||
cb(); | ||
@@ -175,3 +238,3 @@ }); | ||
tasks.push(function (cb) { | ||
exports.getFieldUuid(fieldName, cb); | ||
that.helpers.getFieldUuid(fieldName, cb); | ||
}); | ||
@@ -185,3 +248,3 @@ } | ||
tasks.push(function (cb) { | ||
const options = {'exchange': dataWriter.exchangeName}, | ||
const options = {'exchange': that.exchangeName}, | ||
sendObj = {}; | ||
@@ -196,6 +259,6 @@ | ||
dataWriter.intercom.send(sendObj, options, function (err, msgUuid) { | ||
that.intercom.send(sendObj, options, function (err, msgUuid) { | ||
if (err) return cb(err); | ||
dataWriter.emitter.once(msgUuid, cb); | ||
that.dataWriter.emitter.once(msgUuid, cb); | ||
}); | ||
@@ -207,5 +270,5 @@ }); | ||
fromUuid(uuid, function (err, user) { | ||
that.fromUuid(uuid, function (err, user) { | ||
if (err) { | ||
log.error(logPrefix + err.message); | ||
that.log.error(logPrefix + err.message); | ||
return cb(err); | ||
@@ -217,3 +280,3 @@ } | ||
}); | ||
} | ||
}; | ||
@@ -228,25 +291,19 @@ /** | ||
*/ | ||
function fromField(fieldName, fieldValue, cb) { | ||
dataWriter.ready(function (err) { | ||
const dbFields = [fieldName.trim(), fieldValue.trim()], | ||
sql = 'SELECT uud.userUuid\n' + | ||
'FROM user_users_data uud\n' + | ||
' JOIN user_data_fields udf ON udf.uuid = uud.fieldUuid\n' + | ||
'WHERE udf.name = ? AND uud.data = ?\n' + | ||
'LIMIT 1'; | ||
User.prototype.fromField = function fromField(fieldName, fieldValue, cb) { | ||
const dbFields = [fieldName.trim(), fieldValue.trim()], | ||
that = this, | ||
sql = 'SELECT uud.userUuid\n' + | ||
'FROM user_users_data uud\n' + | ||
' JOIN user_data_fields udf ON udf.uuid = uud.fieldUuid\n' + | ||
'WHERE udf.name = ? AND uud.data = ?\n' + | ||
'LIMIT 1'; | ||
that.db.query(sql, dbFields, function (err, rows) { | ||
if (err) return cb(err); | ||
db.query(sql, dbFields, function (err, rows) { | ||
if (err) return cb(err); | ||
if (rows.length === 0) return cb(null, false); | ||
if (rows.length === 0) { | ||
cb(null, false); | ||
return; | ||
} | ||
fromUuid(lUtils.formatUuid(rows[0].userUuid), cb); | ||
}); | ||
that.fromUuid(that.lUtils.formatUuid(rows[0].userUuid), cb); | ||
}); | ||
} | ||
}; | ||
@@ -260,29 +317,24 @@ /** | ||
*/ | ||
function fromFields(fields, cb) { | ||
dataWriter.ready(function (err) { | ||
const dbFields = []; | ||
User.prototype.fromFields = function fromFields(fields, cb) { | ||
const dbFields = [], | ||
that = this; | ||
let sql = 'SELECT uuid FROM user_users u\nWHERE\n 1 + 1\n'; | ||
let sql = 'SELECT uuid FROM user_users u\nWHERE\n 1 + 1\n'; | ||
if (err) return cb(err); | ||
for (const fieldName of Object.keys(fields)) { | ||
sql += ' AND uuid IN (SELECT userUuid FROM user_users_data WHERE data = ? AND fieldUuid = (SELECT uuid FROM user_data_fields WHERE name = ?))\n'; | ||
dbFields.push(fields[fieldName].trim()); | ||
dbFields.push(fieldName.trim()); | ||
} | ||
for (const fieldName of Object.keys(fields)) { | ||
sql += ' AND uuid IN (SELECT userUuid FROM user_users_data WHERE data = ? AND fieldUuid = (SELECT uuid FROM user_data_fields WHERE name = ?))\n'; | ||
dbFields.push(fields[fieldName].trim()); | ||
dbFields.push(fieldName.trim()); | ||
} | ||
sql += 'LIMIT 1'; | ||
sql += 'LIMIT 1'; | ||
db.query(sql, dbFields, function (err, rows) { | ||
if (err) return cb(err); | ||
that.db.query(sql, dbFields, function (err, rows) { | ||
if (err) return cb(err); | ||
if (rows.length === 0) { | ||
cb(null, false); | ||
return; | ||
} | ||
if (rows.length === 0) return cb(null, false); | ||
fromUuid(lUtils.formatUuid(rows[0].uuid), cb); | ||
}); | ||
that.fromUuid(that.lUtils.formatUuid(rows[0].uuid), cb); | ||
}); | ||
} | ||
}; | ||
@@ -296,5 +348,6 @@ /** | ||
*/ | ||
function fromUserAndPass(username, password, cb) { | ||
User.prototype.fromUserAndPass = function fromUserAndPass(username, password, cb) { | ||
const logPrefix = topLogPrefix + 'fromUserAndPass() - ', | ||
tasks = []; | ||
tasks = [], | ||
that = this; | ||
@@ -308,4 +361,2 @@ let hashedPassword, | ||
tasks.push(dataWriter.ready); | ||
tasks.push(function (cb) { | ||
@@ -315,3 +366,3 @@ const dbFields = [username], | ||
db.query(sql, dbFields, function (err, rows) { | ||
that.db.query(sql, dbFields, function (err, rows) { | ||
if (err) return cb(err); | ||
@@ -321,4 +372,3 @@ | ||
userObj = false; | ||
cb(); | ||
return; | ||
return cb(); | ||
} | ||
@@ -333,10 +383,7 @@ | ||
tasks.push(function (cb) { | ||
if ( ! hashedPassword) { | ||
cb(); | ||
return; | ||
} | ||
if ( ! hashedPassword) return cb(); | ||
checkPassword(password, hashedPassword, function (err, res) { | ||
that.checkPassword(password, hashedPassword, function (err, res) { | ||
if (err) { | ||
log.error(logPrefix + err.message); | ||
that.log.error(logPrefix + err.message); | ||
return cb(err); | ||
@@ -346,10 +393,9 @@ } | ||
if (res === false) { | ||
userObj = false; | ||
cb(); | ||
return; | ||
userObj = false; | ||
return cb(); | ||
} | ||
fromUuid(lUtils.formatUuid(userUuid), function (err, result) { | ||
userObj = result; | ||
if (err) userObj = false; | ||
that.fromUuid(that.lUtils.formatUuid(userUuid), function (err, result) { | ||
userObj = result; | ||
if (err) userObj = false; | ||
cb(err); | ||
@@ -363,3 +409,3 @@ }); | ||
}); | ||
} | ||
}; | ||
@@ -372,5 +418,6 @@ /** | ||
*/ | ||
function fromUsername(username, cb) { | ||
User.prototype.fromUsername = function fromUsername(username, cb) { | ||
const logPrefix = topLogPrefix + 'fromUsername() - ', | ||
dbFields = [], | ||
that = this, | ||
sql = 'SELECT uuid FROM user_users WHERE username = ?'; | ||
@@ -381,19 +428,14 @@ | ||
dataWriter.ready(function (err) { | ||
that.db.query(sql, dbFields, function (err, rows) { | ||
if (err) return cb(err); | ||
db.query(sql, dbFields, function (err, rows) { | ||
if (err) return cb(err); | ||
if (rows.length === 0) { | ||
that.log.debug(logPrefix + 'No user found for username: "' + username + '"'); | ||
return cb(null, false); | ||
} | ||
if (rows.length === 0) { | ||
log.debug(logPrefix + 'No user found for username: "' + username + '"'); | ||
cb(null, false); | ||
return; | ||
} | ||
// Use fromUuid() to get the user instance | ||
fromUuid(lUtils.formatUuid(rows[0].uuid), cb); | ||
}); | ||
// Use fromUuid() to get the user instance | ||
that.fromUuid(that.lUtils.formatUuid(rows[0].uuid), cb); | ||
}); | ||
} | ||
}; | ||
@@ -406,9 +448,9 @@ /** | ||
*/ | ||
function fromUuid(userUuid, cb) { | ||
const userUuidBuf = lUtils.uuidToBuffer(userUuid), | ||
User.prototype.fromUuid = function fromUuid(userUuid, cb) { | ||
const userUuidBuf = this.lUtils.uuidToBuffer(userUuid), | ||
logPrefix = topLogPrefix + 'fromUuid() - ', | ||
returnObj = userBase(), | ||
returnObj = new UserBase(this), | ||
dbFields = [userUuidBuf], | ||
fields = returnObj.fields, | ||
sql = 'SELECT\n' + | ||
that = this, | ||
sql = 'SELECT\n' + | ||
' u.uuid,\n' + | ||
@@ -428,44 +470,39 @@ ' u.username,\n' + | ||
const err = new Error('Invalid userUuid'); | ||
log.warn(logPrefix + err.message); | ||
that.log.warn(logPrefix + err.message); | ||
return cb(err); | ||
} | ||
dataWriter.ready(function (err) { | ||
that.db.query(sql, dbFields, function (err, rows) { | ||
if (err) return cb(err); | ||
db.query(sql, dbFields, function (err, rows) { | ||
if (err) return cb(err); | ||
if (rows.length === 0) { | ||
const err = new Error('No user found for userUuid: "' + userUuid + '"'); | ||
that.log.debug(logPrefix + err.message); | ||
return cb(null, false); | ||
} | ||
if (rows.length === 0) { | ||
const err = new Error('No user found for userUuid: "' + userUuid + '"'); | ||
log.debug(logPrefix + err.message); | ||
cb(null, false); | ||
return; | ||
} | ||
returnObj.uuid = that.lUtils.formatUuid(rows[0].uuid); | ||
returnObj.username = rows[0].username; | ||
returnObj.uuid = lUtils.formatUuid(rows[0].uuid); | ||
returnObj.username = rows[0].username; | ||
if (rows[0].password === '') { | ||
returnObj.passwordIsFalse = true; | ||
} else { | ||
returnObj.passwordIsFalse = false; | ||
} | ||
if (rows[0].password === '') { | ||
returnObj.passwordIsFalse = true; | ||
} else { | ||
returnObj.passwordIsFalse = false; | ||
} | ||
for (let i = 0; rows[i] !== undefined; i ++) { | ||
const row = rows[i]; | ||
for (let i = 0; rows[i] !== undefined; i ++) { | ||
const row = rows[i]; | ||
if (row.fieldUuid) { | ||
if (returnObj.fields[row.fieldName] === undefined) { | ||
returnObj.fields[row.fieldName] = []; | ||
} | ||
if (row.fieldUuid) { | ||
if (fields[row.fieldName] === undefined) { | ||
fields[row.fieldName] = []; | ||
} | ||
fields[row.fieldName].push(row.fieldData); | ||
} | ||
returnObj.fields[row.fieldName].push(row.fieldData); | ||
} | ||
} | ||
cb(null, returnObj); | ||
}); | ||
cb(null, returnObj); | ||
}); | ||
} | ||
}; | ||
@@ -479,6 +516,9 @@ /** | ||
*/ | ||
function getFieldData(userUuid, fieldName, cb) { | ||
exports.getFieldUuid(fieldName, function (err, fieldUuid) { | ||
const userUuidBuffer = lUtils.uuidToBuffer(userUuid), | ||
fieldUuidBuffer = lUtils.uuidToBuffer(fieldUuid), | ||
User.prototype.getFieldData = function getFieldData(userUuid, fieldName, cb) { | ||
const logPrefix = topLogPrefix + 'getFieldData() - ', | ||
that = this; | ||
that.helpers.getFieldUuid(fieldName, function (err, fieldUuid) { | ||
const userUuidBuffer = that.lUtils.uuidToBuffer(userUuid), | ||
fieldUuidBuffer = that.lUtils.uuidToBuffer(fieldUuid), | ||
dbFields = [userUuidBuffer, fieldUuidBuffer], | ||
@@ -490,12 +530,14 @@ sql = 'SELECT data FROM user_users_data WHERE userUuid = ? AND fieldUuid = ?'; | ||
if (userUuidBuffer === false) { | ||
const e = new Error('Invalid user uuid'); | ||
return cb(e); | ||
const err = new Error('Invalid user uuid'); | ||
that.log.verbose(logPrefix + err.message); | ||
return cb(err); | ||
} | ||
if (fieldUuidBuffer === false) { | ||
const e = new Error('Invalid field uuid'); | ||
return cb(e); | ||
const err = new Error('Invalid field uuid'); | ||
that.log.verbose(logPrefix + err.message); | ||
return cb(err); | ||
} | ||
db.query(sql, dbFields, function (err, rows) { | ||
that.db.query(sql, dbFields, function (err, rows) { | ||
const data = []; | ||
@@ -512,3 +554,3 @@ | ||
}); | ||
} | ||
}; | ||
@@ -521,14 +563,15 @@ /** | ||
*/ | ||
function hashPassword(password, cb) { | ||
const logPrefix = topLogPrefix + 'hashPassword() - '; | ||
User.prototype.hashPassword = function hashPassword(password, cb) { | ||
const logPrefix = topLogPrefix + 'hashPassword() - ', | ||
that = this; | ||
if ( ! password) { | ||
password = ''; | ||
password = ''; | ||
} | ||
password = password.trim(); | ||
password = password.trim(); | ||
bcrypt.hash(password, 10, function (err, hash) { | ||
if (err) { | ||
log.error(logPrefix + err.message); | ||
that.log.error(logPrefix + err.message); | ||
} | ||
@@ -538,3 +581,3 @@ | ||
}); | ||
} | ||
}; | ||
@@ -549,7 +592,8 @@ /** | ||
*/ | ||
function replaceUserFields(uuid, fields, cb) { | ||
const options = {'exchange': dataWriter.exchangeName}, | ||
sendObj = {}; | ||
User.prototype.replaceUserFields = function replaceUserFields(uuid, fields, cb) { | ||
const options = {'exchange': this.dataWriter.exchangeName}, | ||
sendObj = {}, | ||
that = this; | ||
fromUuid(uuid, function (err, user) { | ||
that.fromUuid(uuid, function (err, user) { | ||
if (err) return cb(err); | ||
@@ -563,9 +607,9 @@ | ||
dataWriter.intercom.send(sendObj, options, function (err, msgUuid) { | ||
that.intercom.send(sendObj, options, function (err, msgUuid) { | ||
if (err) return cb(err); | ||
dataWriter.emitter.once(msgUuid, cb); | ||
that.dataWriter.emitter.once(msgUuid, cb); | ||
}); | ||
}); | ||
} | ||
}; | ||
@@ -578,5 +622,6 @@ /** | ||
*/ | ||
function rmUser(userUuid, cb) { | ||
const options = {'exchange': dataWriter.exchangeName}, | ||
sendObj = {}; | ||
User.prototype.rmUser = function rmUser(userUuid, cb) { | ||
const options = {'exchange': this.dataWriter.exchangeName}, | ||
sendObj = {}, | ||
that = this; | ||
@@ -587,8 +632,8 @@ sendObj.action = 'rmUser'; | ||
dataWriter.intercom.send(sendObj, options, function (err, msgUuid) { | ||
that.intercom.send(sendObj, options, function (err, msgUuid) { | ||
if (err) return cb(err); | ||
dataWriter.emitter.once(msgUuid, cb); | ||
that.dataWriter.emitter.once(msgUuid, cb); | ||
}); | ||
} | ||
}; | ||
@@ -602,5 +647,6 @@ /** | ||
*/ | ||
function rmUserField(userUuid, fieldName, cb) { | ||
const options = {'exchange': dataWriter.exchangeName}, | ||
sendObj = {}; | ||
User.prototype.rmUserField = function rmUserField(userUuid, fieldName, cb) { | ||
const options = {'exchange': this.dataWriter.exchangeName}, | ||
sendObj = {}, | ||
that = this; | ||
@@ -612,8 +658,8 @@ sendObj.action = 'rmUserField'; | ||
dataWriter.intercom.send(sendObj, options, function (err, msgUuid) { | ||
that.intercom.send(sendObj, options, function (err, msgUuid) { | ||
if (err) return cb(err); | ||
dataWriter.emitter.once(msgUuid, cb); | ||
that.dataWriter.emitter.once(msgUuid, cb); | ||
}); | ||
} | ||
}; | ||
@@ -627,4 +673,5 @@ /** | ||
*/ | ||
function setPassword(userUuid, newPassword, cb) { | ||
const tasks = []; | ||
User.prototype.setPassword = function setPassword(userUuid, newPassword, cb) { | ||
const tasks = [], | ||
that = this; | ||
@@ -635,8 +682,8 @@ let hashedPassword; | ||
if (newPassword) { | ||
hashPassword(newPassword.trim(), function (err, hash) { | ||
hashedPassword = hash; | ||
that.hashPassword(newPassword.trim(), function (err, hash) { | ||
hashedPassword = hash; | ||
cb(err); | ||
}); | ||
} else { | ||
hashedPassword = false; | ||
hashedPassword = false; | ||
cb(); | ||
@@ -647,3 +694,3 @@ } | ||
tasks.push(function (cb) { | ||
const options = {'exchange': dataWriter.exchangeName}, | ||
const options = {'exchange': that.dataWriter.exchangeName}, | ||
sendObj = {}; | ||
@@ -656,6 +703,6 @@ | ||
dataWriter.intercom.send(sendObj, options, function (err, msgUuid) { | ||
that.intercom.send(sendObj, options, function (err, msgUuid) { | ||
if (err) return cb(err); | ||
dataWriter.emitter.once(msgUuid, cb); | ||
that.dataWriter.emitter.once(msgUuid, cb); | ||
}); | ||
@@ -665,3 +712,3 @@ }); | ||
async.series(tasks, cb); | ||
} | ||
}; | ||
@@ -675,11 +722,12 @@ /** | ||
*/ | ||
function setUsername(userUuid, newUsername, cb) { | ||
const userUuidBuf = lUtils.uuidToBuffer(userUuid), | ||
logPrefix = topLogPrefix + 'setUsername() - '; | ||
User.prototype.setUsername = function setUsername(userUuid, newUsername, cb) { | ||
const userUuidBuf = this.lUtils.uuidToBuffer(userUuid), | ||
logPrefix = topLogPrefix + 'setUsername() - ', | ||
that = this; | ||
newUsername = newUsername.trim(); | ||
newUsername = newUsername.trim(); | ||
if ( ! newUsername) { | ||
const err = new Error('No new username supplied'); | ||
log.warn(logPrefix + err.message); | ||
that.log.warn(logPrefix + err.message); | ||
return cb(err); | ||
@@ -690,8 +738,8 @@ } | ||
const err = new Error('Invalid user uuid'); | ||
log.warn(logPrefix + err.message); | ||
that.log.warn(logPrefix + err.message); | ||
return cb(err); | ||
} | ||
db.query('SELECT uuid FROM user_users WHERE username = ? AND uuid != ?', [newUsername, userUuidBuf], function (err, rows) { | ||
const options = {'exchange': dataWriter.exchangeName}, | ||
that.db.query('SELECT uuid FROM user_users WHERE username = ? AND uuid != ?', [newUsername, userUuidBuf], function (err, rows) { | ||
const options = {'exchange': that.dataWriter.exchangeName}, | ||
sendObj = {}; | ||
@@ -701,3 +749,3 @@ | ||
if (rows.length && lUtils.formatUuid(rows[0].uuid) !== userUuid) { | ||
if (rows.length && that.lUtils.formatUuid(rows[0].uuid) !== userUuid) { | ||
const err = new Error('Username is already taken'); | ||
@@ -712,212 +760,214 @@ return cb(err); | ||
dataWriter.intercom.send(sendObj, options, function (err, msgUuid) { | ||
that.intercom.send(sendObj, options, function (err, msgUuid) { | ||
if (err) return cb(err); | ||
dataWriter.emitter.once(msgUuid, cb); | ||
that.dataWriter.emitter.once(msgUuid, cb); | ||
}); | ||
}); | ||
} | ||
}; | ||
function userBase() { | ||
const returnObj = {'fields': {}}; | ||
/** | ||
* Checks if a unsername is available | ||
* | ||
* @param str username | ||
* @param func cb(err, result) - result is a bolean | ||
*/ | ||
User.prototype.usernameAvailable = function usernameAvailable(username, cb) { | ||
const that = this; | ||
/** | ||
* Add a field with value | ||
* | ||
* @param str name | ||
* @param str value | ||
* @param func cb(err) | ||
*/ | ||
returnObj.addField = function addField(name, value, cb) { | ||
if (returnObj.uuid === undefined) { | ||
const err = new Error('Cannot add field; no user loaded'); | ||
return cb(err); | ||
let isAvailable; | ||
username = username.trim(); | ||
that.db.query('SELECT uuid FROM user_users WHERE username = ?', [username], function (err, rows) { | ||
if (err) return cb(err); | ||
if (rows.length === 0) { | ||
isAvailable = true; | ||
} else { | ||
isAvailable = false; | ||
} | ||
addUserDataField(returnObj.uuid, name, value, function (err) { | ||
if (err) return cb(err); | ||
cb(null, isAvailable); | ||
}); | ||
}; | ||
if (returnObj.fields[name] === undefined) { | ||
returnObj.fields[name] = []; | ||
} | ||
function UserBase(userInstance) { | ||
const that = this; | ||
returnObj.fields[name].push(value); | ||
cb(); | ||
}); | ||
}; | ||
that.fields = {}; | ||
/** | ||
* Adds one or more fields with values to the user object. Does not overwrite existing values. It is possible to add the same value multiple times | ||
* | ||
* @param obj fields - field name as key, field values as array to that key - ex: {'role': ['admin','user']} | ||
* @param func cb(err) | ||
*/ | ||
returnObj.addFields = function addFields(fields, cb) { | ||
if (returnObj.uuid === undefined) { | ||
const err = new Error('Cannot add field; no user loaded'); | ||
return cb(err); | ||
} | ||
that.userInstance = userInstance; | ||
that.log = that.userInstance.log; | ||
} | ||
addUserDataFields(returnObj.uuid, fields, function (err) { | ||
if (err) return cb(err); | ||
/** | ||
* Add a field with value | ||
* | ||
* @param str name | ||
* @param str value | ||
* @param func cb(err) | ||
*/ | ||
UserBase.prototype.addField = function addField(name, value, cb) { | ||
const logPrefix = topLogPrefix + 'UserBase.addField() - ', | ||
that = this; | ||
for (let key in fields) { | ||
if (returnObj.fields[key] === undefined) { | ||
returnObj[key] = fields[key]; | ||
} else { | ||
for (let value of fields[key]) { | ||
returnObj.fields[key].push(value); | ||
} | ||
} | ||
} | ||
if (that.uuid === undefined) { | ||
const err = new Error('Cannot add field; no user loaded'); | ||
that.log.verbose(logPrefix + err.message); | ||
return cb(err); | ||
} | ||
cb(); | ||
}); | ||
}; | ||
that.userInstance.addUserDataField(that.uuid, name, value, function (err) { | ||
if (err) return cb(err); | ||
/** | ||
* Replace all fields | ||
* IMPORTANT!!! Will clear all data not given in the fields parameter | ||
* | ||
* @param obj fields - field name as key, field values as array to that key - ex: {'role': ['admin','user']} | ||
* @param func cb(err) | ||
*/ | ||
returnObj.replaceFields = function replaceFields(fields, cb) { | ||
if (returnObj.uuid === undefined) { | ||
const err = new Error('Cannot replace fields; no user loaded'); | ||
return cb(err); | ||
if (that.fields[name] === undefined) { | ||
that.fields[name] = []; | ||
} | ||
replaceUserFields(returnObj.uuid, fields, function (err) { | ||
if (err) return cb(err); | ||
that.fields[name].push(value); | ||
cb(); | ||
}); | ||
}; | ||
// Reload everything | ||
fromUuid(returnObj.uuid, function (err, user) { | ||
if (err) return cb(err); | ||
/** | ||
* Adds one or more fields with values to the user object. Does not overwrite existing values. It is possible to add the same value multiple times | ||
* | ||
* @param obj fields - field name as key, field values as array to that key - ex: {'role': ['admin','user']} | ||
* @param func cb(err) | ||
*/ | ||
UserBase.prototype.addFields = function addFields(fields, cb) { | ||
const logPrefix = topLogPrefix + 'UserBase.addFields() - ', | ||
that = this; | ||
returnObj.fields = user.fields; | ||
cb(); | ||
}); | ||
}); | ||
}; | ||
if (that.uuid === undefined) { | ||
const err = new Error('Cannot add field; no user loaded'); | ||
that.log.verbose(logPrefix + err.message); | ||
return cb(err); | ||
} | ||
returnObj.rm = function rm(cb) { | ||
if (returnObj.uuid === undefined) { | ||
const err = new Error('Cannot remove field; no user loaded'); | ||
return cb(err); | ||
that.userInstance.addUserDataFields(that.uuid, fields, function (err) { | ||
if (err) return cb(err); | ||
for (let key in fields) { | ||
if (that.fields[key] === undefined) { | ||
that[key] = fields[key]; | ||
} else { | ||
for (let value of fields[key]) { | ||
that.fields[key].push(value); | ||
} | ||
} | ||
} | ||
rmUser(returnObj.uuid, function (err) { | ||
if (err) return cb(err); | ||
cb(); | ||
}); | ||
}; | ||
delete returnObj.uuid; | ||
delete returnObj.fields; | ||
delete returnObj.username; | ||
/** | ||
* Replace all fields | ||
* IMPORTANT!!! Will clear all data not given in the fields parameter | ||
* | ||
* @param obj fields - field name as key, field values as array to that key - ex: {'role': ['admin','user']} | ||
* @param func cb(err) | ||
*/ | ||
UserBase.prototype.replaceFields = function replaceFields(fields, cb) { | ||
const logPrefix = topLogPrefix + 'UserBase.replaceFields() - ', | ||
that = this; | ||
cb(); | ||
}); | ||
}; | ||
if (that.uuid === undefined) { | ||
const err = new Error('Cannot replace fields; no user loaded'); | ||
that.log.verbose(logPrefix + err.message); | ||
return cb(err); | ||
} | ||
/** | ||
* Remove a field from this user | ||
* | ||
* @param str name | ||
* @param func cb(err) | ||
*/ | ||
returnObj.rmField = function rmField(name, cb) { | ||
if (returnObj.uuid === undefined) { | ||
const err = new Error('Cannot remove field; no user loaded'); | ||
return cb(err); | ||
} | ||
that.userInstance.replaceUserFields(that.uuid, fields, function (err) { | ||
if (err) return cb(err); | ||
rmUserField(returnObj.uuid, name, function (err) { | ||
// Reload everything | ||
that.userInstance.fromUuid(that.uuid, function (err, user) { | ||
if (err) return cb(err); | ||
delete returnObj.fields[name]; | ||
that.fields = user.fields; | ||
cb(); | ||
}); | ||
}; | ||
}); | ||
}; | ||
returnObj.setPassword = function (newPassword, cb) { | ||
if (returnObj.uuid === undefined) { | ||
const err = new Error('Cannot set password; no user loaded'); | ||
return cb(err); | ||
} | ||
UserBase.prototype.rm = function rm(cb) { | ||
const logPrefix = topLogPrefix + 'UserBase.rm() - ', | ||
that = this; | ||
setPassword(returnObj.uuid, newPassword, cb); | ||
}; | ||
if (that.uuid === undefined) { | ||
const err = new Error('Cannot remove field; no user loaded'); | ||
that.log.verbose(logPrefix + err.message); | ||
return cb(err); | ||
} | ||
returnObj.setUsername = function (newUsername, cb) { | ||
if (returnObj.uuid === undefined) { | ||
const err = new Error('Cannot set username; no user loaded'); | ||
return cb(err); | ||
} | ||
that.userInstance.rmUser(that.uuid, function (err) { | ||
if (err) return cb(err); | ||
setUsername(returnObj.uuid, newUsername, function (err) { | ||
if (err) return cb(err); | ||
returnObj.username = newUsername; | ||
cb(); | ||
}); | ||
}; | ||
delete that.uuid; | ||
delete that.username; | ||
return returnObj; | ||
} | ||
that.fields = {}; | ||
cb(); | ||
}); | ||
}; | ||
/** | ||
* Checks if a unsername is available | ||
* Remove a field from this user | ||
* | ||
* @param str username | ||
* @param func cb(err, result) - result is a bolean | ||
* @param str name | ||
* @param func cb(err) | ||
*/ | ||
function usernameAvailable(username, cb) { | ||
const tasks = []; | ||
UserBase.prototype.rmField = function rmField(name, cb) { | ||
const logPrefix = topLogPrefix + 'UserBase.rmField() - ', | ||
that = this; | ||
let isAvailable; | ||
if (that.uuid === undefined) { | ||
const err = new Error('Cannot remove field; no user loaded'); | ||
that.log.verbose(logPrefix + err.message); | ||
return cb(err); | ||
} | ||
username = username.trim(); | ||
that.userInstance.rmUserField(that.uuid, name, function (err) { | ||
if (err) return cb(err); | ||
tasks.push(dataWriter.ready); | ||
delete that.fields[name]; | ||
cb(); | ||
}); | ||
}; | ||
tasks.push(function (cb) { | ||
db.query('SELECT uuid FROM user_users WHERE username = ?', [username], function (err, rows) { | ||
if (err) return cb(err); | ||
UserBase.prototype.setPassword = function (newPassword, cb) { | ||
const logPrefix = topLogPrefix + 'UserBase.setPassword() - ', | ||
that = this; | ||
if (rows.length === 0) { | ||
isAvailable = true; | ||
} else { | ||
isAvailable = false; | ||
} | ||
if (that.uuid === undefined) { | ||
const err = new Error('Cannot set password; no user loaded'); | ||
that.log.verbose(logPrefix + err.message); | ||
return cb(err); | ||
} | ||
cb(); | ||
}); | ||
}); | ||
that.userInstance.setPassword(that.uuid, newPassword, cb); | ||
}; | ||
async.series(tasks, function (err) { | ||
UserBase.prototype.setUsername = function (newUsername, cb) { | ||
const logPrefix = topLogPrefix + 'UserBase.setUsername() - ', | ||
that = this; | ||
if (that.uuid === undefined) { | ||
const err = new Error('Cannot set username; no user loaded'); | ||
that.log.verbose(logPrefix + err.message); | ||
return cb(err); | ||
} | ||
that.setUsername(that.uuid, newUsername, function (err) { | ||
if (err) return cb(err); | ||
cb(null, isAvailable); | ||
that.username = newUsername; | ||
cb(); | ||
}); | ||
} | ||
}; | ||
exports.addUserDataField = addUserDataField; | ||
exports.addUserDataFields = addUserDataFields; | ||
exports.checkPassword = checkPassword; | ||
exports.create = create; | ||
exports.dataWriter = dataWriter; | ||
exports.fromField = fromField; | ||
exports.fromFields = fromFields; | ||
exports.fromUserAndPass = fromUserAndPass; | ||
exports.fromUsername = fromUsername; | ||
exports.fromUuid = fromUuid; | ||
exports.getFieldData = getFieldData; | ||
exports.hashPassword = hashPassword; | ||
exports.options = dataWriter.options; | ||
exports.ready = dataWriter.ready; | ||
exports.replaceUserFields = replaceUserFields; | ||
exports.rmUser = rmUser; | ||
exports.rmUserField = rmUserField; | ||
exports.setPassword = setPassword; | ||
exports.setUsername = setUsername; | ||
exports.usernameAvailable = usernameAvailable; | ||
exports.Users = require(__dirname + '/users.js'); | ||
Object.assign(exports, require(__dirname + '/helpers.js')); // extend this module with all helpers from the helpers file | ||
exports = module.exports = User; | ||
exports.Users = require(__dirname + '/users.js'); |
{ | ||
"name": "larvituser", | ||
"version": "0.14.0", | ||
"version": "0.15.0", | ||
"author": { | ||
@@ -11,18 +11,15 @@ "name": "Mikael 'Lilleman' Göransson", | ||
"dependencies": { | ||
"async": "^2.0.1", | ||
"bcryptjs": "^2.3.0", | ||
"check-object-key": "^0.1.2", | ||
"larvitamintercom": "^0.2.0", | ||
"larvitamsync": "^0.6.0", | ||
"larvitdb": "^2.0.0", | ||
"larvitdbmigration": "^3.0.0", | ||
"larvitutils": "^1.0.4", | ||
"uuid": "^3.0.0", | ||
"winston": "^2.1.1" | ||
"async": "^2.6.1", | ||
"bcryptjs": "^2.4.3", | ||
"larvitamintercom": "^0.3.0", | ||
"larvitamsync": "^0.7.0", | ||
"larvitdbmigration": "^4.0.1", | ||
"larvitutils": "^2.0.0", | ||
"uuid": "^3.3.2" | ||
}, | ||
"description": "User module for node.js", | ||
"devDependencies": { | ||
"freeport": "^1.0.5", | ||
"mocha": "^5.2.0", | ||
"mocha-eslint": "^4.1.0" | ||
"freeport": "1.0.5", | ||
"mocha": "5.2.0", | ||
"mocha-eslint": "4.1.0" | ||
}, | ||
@@ -42,3 +39,3 @@ "scripts": { | ||
"readmeFilename": "README.md", | ||
"license": "MIT" | ||
"license": "ISC" | ||
} |
@@ -12,5 +12,16 @@ [![Build Status](https://travis-ci.org/larvit/larvituser.svg?branch=master)](https://travis-ci.org/larvit/larvituser) [![Dependencies](https://david-dm.org/larvit/larvituser.svg)](https://david-dm.org/larvit/larvituser.svg) | ||
```javascript | ||
const userLib = require('larvituser'); | ||
const UserLib = require('larvituser'), | ||
Intercom = require('larvitamintercom'), | ||
winston = require('winston'), | ||
log = winston.createLogger({'transports': [new winston.transports.Console()]}), | ||
userLib = new UserLib({ | ||
'db': require('larvitdb'), | ||
userLib.dataWriter.mode = 'master'; // Used for standalone use. If multiple applications connect via rabbitMQ the other should be "slave" | ||
// Optional parameters | ||
'mode': 'noSync', // Other options are "master" or "slave" | ||
'intercom': new Intercom({'conStr': 'loopback interface', 'log': log}), | ||
'log': log | ||
}); | ||
db.setup(...); // See https://github.com/larvit/larvitdb for configuration details | ||
``` | ||
@@ -22,4 +33,4 @@ | ||
const userData = { | ||
'firstname': 'Nisse', | ||
'lastname': 'Nilsson', | ||
'firstname': 'Nisse', | ||
'lastname': 'Nilsson', | ||
'role': [ | ||
@@ -55,3 +66,3 @@ 'user', | ||
```javascript | ||
const users = new userLib.Users(); | ||
const users = new UserLib.Users({'db': db, 'log': log}); | ||
@@ -68,3 +79,3 @@ users.get(function (err, userList) { | ||
```javascript | ||
const users = new userLib.Users(); | ||
const users = new UserLib.Users({'db': db, 'log': log}); | ||
@@ -71,0 +82,0 @@ users.getFieldData('fieldName', function (err, result) { |
'use strict'; | ||
const Intercom = require('larvitamintercom'), | ||
userLib = require('../index.js'), | ||
const UserLib = require('../index.js'), | ||
assert = require('assert'), | ||
lUtils = require('larvitutils'), | ||
lUtils = new (require('larvitutils'))(), | ||
async = require('async'), | ||
log = require('winston'), | ||
log = new lUtils.Log('warning'), | ||
db = require('larvitdb'), | ||
fs = require('fs'); | ||
log.remove(log.transports.Console); | ||
/**/log.add(log.transports.Console, { | ||
'level': 'warn', | ||
'colorize': true, | ||
'timestamp': true, | ||
'json': false | ||
}); /**/ | ||
let userLib; | ||
@@ -24,14 +17,10 @@ before(function (done) { | ||
// Setting intercom and mode | ||
userLib.dataWriter.mode = 'master'; | ||
userLib.dataWriter.intercom = new Intercom('loopback interface'); | ||
// Run DB Setup | ||
tasks.push(function (cb) { | ||
let confFile; | ||
let confFile; | ||
if (process.env.DBCONFFILE === undefined) { | ||
confFile = __dirname + '/../config/db_test.json'; | ||
confFile = __dirname + '/../config/db_test.json'; | ||
} else { | ||
confFile = process.env.DBCONFFILE; | ||
confFile = process.env.DBCONFFILE; | ||
} | ||
@@ -43,3 +32,6 @@ | ||
fs.stat(confFile, function (err) { | ||
let conf; | ||
if (err) { | ||
// Then look for this string in the config folder | ||
@@ -49,5 +41,7 @@ confFile = __dirname + '/../config/' + confFile; | ||
if (err) throw err; | ||
log.verbose('DB config: ' + JSON.stringify(require(confFile))); | ||
log.verbose('DB config: ' + JSON.stringify(require(confFile))); | ||
db.setup(require(confFile), cb); | ||
conf = require(confFile); | ||
conf.log = log; | ||
db.setup(conf, cb); | ||
}); | ||
@@ -59,11 +53,28 @@ | ||
log.verbose('DB config: ' + JSON.stringify(require(confFile))); | ||
db.setup(require(confFile), cb); | ||
conf = require(confFile); | ||
conf.log = log; | ||
db.setup(conf, cb); | ||
}); | ||
}); | ||
// Migrating user db etc | ||
// Check for empty db | ||
tasks.push(function (cb) { | ||
userLib.ready(cb); | ||
db.query('SHOW TABLES', function (err, rows) { | ||
if (err) throw err; | ||
if (rows.length) { | ||
throw new Error('Database is not empty. To make a test, you must supply an empty database!'); | ||
} | ||
cb(); | ||
}); | ||
}); | ||
tasks.push(function (cb) { | ||
userLib = new UserLib({ | ||
'log': log, | ||
'db': db | ||
}, cb); | ||
}); | ||
async.series(tasks, done); | ||
@@ -87,5 +98,5 @@ }); | ||
it('should return an UUID for the field we are asking for', function (done) { | ||
userLib.getFieldUuid('firstname', function (err, result) { | ||
userLib.helpers.getFieldUuid('firstname', function (err, result) { | ||
if (err) throw err; | ||
fieldUuid = result; | ||
fieldUuid = result; | ||
assert.notStrictEqual(lUtils.formatUuid(fieldUuid), false); | ||
@@ -97,3 +108,3 @@ done(); | ||
it('shold return field name "firstname" for the UUID we created above', function (done) { | ||
userLib.getFieldName(fieldUuid, function (err, fieldName) { | ||
userLib.helpers.getFieldName(fieldUuid, function (err, fieldName) { | ||
if (err) throw err; | ||
@@ -464,22 +475,24 @@ assert.strictEqual(fieldName, 'firstname'); | ||
tasks.push(function (cb) { | ||
let u = new userLib.Users(); | ||
let users = new UserLib.Users({'db': db, 'log': log}); | ||
u.get(function (err, userList) { | ||
users.get(function (err, userList) { | ||
let foundUser1 = false, | ||
foundUser2 = false; | ||
if (err) throw err; | ||
assert(userList.length >= 2, '2 or more users should exist in database'); | ||
let foundUser1 = false, foundUser2 = false; | ||
assert(userList.length >= 2, '2 or more users should exist in database'); | ||
for (let i = 0; i < userList.length; i ++) { | ||
if (userList[i].uuid === uuids[0]) { | ||
foundUser1 = true; | ||
foundUser1 = true; | ||
} | ||
if (userList[i].uuid === uuids[1]) { | ||
foundUser2 = true; | ||
foundUser2 = true; | ||
} | ||
} | ||
assert.strictEqual(foundUser1, true, 'user1 not found'); | ||
assert.strictEqual(foundUser2, true, 'user2 not found'); | ||
assert.strictEqual(foundUser1, true, 'user1 not found'); | ||
assert.strictEqual(foundUser2, true, 'user2 not found'); | ||
@@ -494,12 +507,12 @@ cb(); | ||
it('Get list of users with matching fields', function (done) { | ||
const users = new userLib.Users(); | ||
const users = new UserLib.Users({'db': db, 'log': log}); | ||
users.matchAllFields = { 'role': ['customer']}; | ||
users.returnFields = []; | ||
users.matchAllFields = { 'role': ['customer']}; | ||
users.returnFields = []; | ||
users.get(function (err, userList, totalElements) { | ||
if (err) throw err; | ||
assert.strictEqual(totalElements, 1); | ||
assert.strictEqual(userList.length, 1); | ||
assert.strictEqual(userList[0].username, 'user1'); | ||
assert.strictEqual(totalElements, 1); | ||
assert.strictEqual(userList.length, 1); | ||
assert.strictEqual(userList[0].username, 'user1'); | ||
@@ -511,11 +524,11 @@ done(); | ||
it('Get list of data values for field', function (done) { | ||
const users = new userLib.Users(); | ||
const users = new UserLib.Users({'db': db, 'log': log}); | ||
users.getFieldData('lastname', function (err, result) { | ||
if (err) throw err; | ||
assert.strictEqual(result.length, 3); | ||
assert.strictEqual(result.length, 3); | ||
assert.strictEqual(result.indexOf('biff') > - 1, true); | ||
assert.strictEqual(result.indexOf('baff') > - 1, true); | ||
assert.strictEqual(result.indexOf('bonk') > - 1, true); | ||
assert.strictEqual(result.indexOf('biff') > - 1, true); | ||
assert.strictEqual(result.indexOf('baff') > - 1, true); | ||
assert.strictEqual(result.indexOf('bonk') > - 1, true); | ||
done(); | ||
@@ -526,16 +539,16 @@ }); | ||
it('Get list of users with requested field data', function (done) { | ||
const users = new userLib.Users(); | ||
const users = new UserLib.Users({'db': db, 'log': log}); | ||
users.returnFields = ['lastname']; | ||
users.returnFields = ['lastname']; | ||
users.get(function (err, result) { | ||
const expectedFields = ['uuid', 'username', 'lastname']; | ||
if (err) throw err; | ||
assert.notStrictEqual(result, undefined); | ||
assert.strictEqual(result.length, 4); | ||
assert.notStrictEqual(result, undefined); | ||
assert.strictEqual(result.length, 4); | ||
const expectedFields = ['uuid', 'username', 'lastname']; | ||
for (let r of result) { | ||
for (let key in r) { | ||
assert.strictEqual(expectedFields.indexOf(key) > - 1, true); | ||
assert.strictEqual(expectedFields.indexOf(key) > - 1, true); | ||
} | ||
@@ -549,3 +562,3 @@ } | ||
it('Get list of users where fieldData exists', function (done) { | ||
const users = new userLib.Users(); | ||
const users = new UserLib.Users({'db': db, 'log': log}); | ||
@@ -566,3 +579,3 @@ users.matchExistingFields = ['veryUnique']; | ||
it('Get users by uuid', function (done) { | ||
const users = new userLib.Users(); | ||
const users = new UserLib.Users({'db': db, 'log': log}); | ||
@@ -569,0 +582,0 @@ users.uuids = [uuids[1]]; |
77
users.js
'use strict'; | ||
const topLogPrefix = 'larvituser: users.js ', | ||
dataWriter = require(__dirname + '/dataWriter.js'), | ||
lUtils = require('larvitutils'), | ||
async = require('async'), | ||
log = require('winston'), | ||
db = require('larvitdb'); | ||
LUtils = require('larvitutils'), | ||
async = require('async'); | ||
function Users() { | ||
function Users(options) { | ||
const logPrefix = topLogPrefix + 'Users() - ', | ||
that = this; | ||
that.options = options || {}; | ||
if ( ! that.options.log) { | ||
const tmpLUtils = new LUtils(); | ||
options.log = new tmpLUtils.Log(); | ||
} | ||
that.options = options; | ||
for (const key of Object.keys(options)) { | ||
that[key] = options[key]; | ||
} | ||
that.lUtils = new LUtils({'log': that.log}); | ||
if ( ! that.db) { | ||
const err = new Error('Required option db is missing'); | ||
that.log.error(logPrefix + err.message); | ||
throw err; | ||
} | ||
} | ||
@@ -20,5 +40,6 @@ | ||
Users.prototype.getFieldData = function (fieldName, cb) { | ||
const sql = 'SELECT DISTINCT d.data FROM user_users_data d JOIN user_data_fields f ON d.fieldUuid = f.uuid WHERE f.name = "' + fieldName + '"'; | ||
const that = this, | ||
sql = 'SELECT DISTINCT d.data FROM user_users_data d JOIN user_data_fields f ON d.fieldUuid = f.uuid WHERE f.name = "' + fieldName + '"'; | ||
db.query(sql, function (err, rows) { | ||
that.db.query(sql, function (err, rows) { | ||
const result = []; | ||
@@ -37,6 +58,6 @@ | ||
Users.prototype.get = function (cb) { | ||
const dbFields = [], | ||
const logPrefix = topLogPrefix + ' get() - ', | ||
dbFields = [], | ||
tasks = [], | ||
that = this, | ||
logPrefix = topLogPrefix + ' get() - '; | ||
that = this; | ||
@@ -47,4 +68,2 @@ let sqlWhere = '', | ||
tasks.push(dataWriter.ready); | ||
// Build where-statement | ||
@@ -62,3 +81,3 @@ tasks.push(function (cb) { | ||
sqlWhere = sqlWhere.substring(0, sqlWhere.length - 4) + '))\n'; | ||
sqlWhere = sqlWhere.substring(0, sqlWhere.length - 4) + '))\n'; | ||
} | ||
@@ -97,4 +116,4 @@ | ||
for (let i = 0; that.uuids[i] !== undefined; i ++) { | ||
if (lUtils.uuidToBuffer(that.uuids[i]) === false) { | ||
log.warn(logPrefix + 'Invalid field uuid, skipping'); | ||
if (that.lUtils.uuidToBuffer(that.uuids[i]) === false) { | ||
that.log.warn(logPrefix + 'Invalid field uuid, skipping'); | ||
continue; | ||
@@ -104,3 +123,3 @@ } | ||
sqlWhere += '?,'; | ||
dbFields.push(lUtils.uuidToBuffer(that.uuids[i])); | ||
dbFields.push(that.lUtils.uuidToBuffer(that.uuids[i])); | ||
} | ||
@@ -125,6 +144,6 @@ | ||
db.query(sql, dbFields, function (err, rows) { | ||
that.db.query(sql, dbFields, function (err, rows) { | ||
if (err) return cb(err); | ||
result = []; | ||
result = []; | ||
@@ -134,3 +153,3 @@ for (let i = 0; rows[i] !== undefined; i ++) { | ||
user.uuid = lUtils.formatUuid(rows[i].uuid); | ||
user.uuid = that.lUtils.formatUuid(rows[i].uuid); | ||
user.username = rows[i].username; | ||
@@ -151,3 +170,3 @@ | ||
subTasks.push(function (cb) { | ||
let subFields = [], | ||
let subFields = [], | ||
sql = 'SELECT uf.uuid AS fieldUuid,\n' + | ||
@@ -167,14 +186,14 @@ 'uf.name AS fieldName,\n' + | ||
sql = sql.substring(0, sql.length - 1); | ||
sql = sql.substring(0, sql.length - 1); | ||
sql += ') AND ud.userUuid = ?'; | ||
if (lUtils.uuidToBuffer(u.uuid) === false) { | ||
log.warn(logPrefix + 'Inavlid user uuid, skipping'); | ||
if (that.lUtils.uuidToBuffer(u.uuid) === false) { | ||
that.log.warn(logPrefix + 'Inavlid user uuid, skipping'); | ||
return cb(); | ||
} | ||
subFields.push(lUtils.uuidToBuffer(u.uuid)); | ||
subFields.push(that.lUtils.uuidToBuffer(u.uuid)); | ||
db.query(sql, subFields, function (err, rows) { | ||
that.db.query(sql, subFields, function (err, rows) { | ||
if (err) return cb(err); | ||
@@ -209,6 +228,6 @@ | ||
db.query(sql, dbFields, function (err, rows) { | ||
that.db.query(sql, dbFields, function (err, rows) { | ||
if (err) return cb(err); | ||
totalElements = rows[0].totalElements; | ||
totalElements = rows[0].totalElements; | ||
@@ -224,2 +243,2 @@ cb(err); | ||
exports = module.exports = Users; | ||
exports = module.exports = Users; |
Sorry, the diff of this file is not supported yet
86378
7
20
2254
223
12
+ Addedlarvitamintercom@0.3.7(transitive)
+ Addedlarvitamsync@0.7.4(transitive)
+ Addedlarvitdbmigration@4.0.3(transitive)
- Removedcheck-object-key@^0.1.2
- Removedlarvitdb@^2.0.0
- Removedwinston@^2.1.1
- Removedagentkeepalive@3.5.3(transitive)
- Removedansi-regex@2.1.1(transitive)
- Removedansi-styles@2.2.1(transitive)
- Removedchalk@1.1.3(transitive)
- Removedcheck-object-key@0.1.11(transitive)
- Removedcolors@1.0.3(transitive)
- Removedcycle@1.0.3(transitive)
- Removedelasticsearch@15.5.0(transitive)
- Removedescape-string-regexp@1.0.5(transitive)
- Removedeyes@0.1.8(transitive)
- Removedhas-ansi@2.0.0(transitive)
- Removedhumanize-ms@1.2.1(transitive)
- Removedlarvitamintercom@0.2.14(transitive)
- Removedlarvitamsync@0.6.0(transitive)
- Removedlarvitdbmigration@3.0.0(transitive)
- Removedlarvitutils@1.1.3(transitive)
- Removedms@2.1.3(transitive)
- Removedstack-trace@0.0.10(transitive)
- Removedstrip-ansi@3.0.1(transitive)
- Removedsupports-color@2.0.0(transitive)
- Removedwinston@2.4.7(transitive)
Updatedasync@^2.6.1
Updatedbcryptjs@^2.4.3
Updatedlarvitamintercom@^0.3.0
Updatedlarvitamsync@^0.7.0
Updatedlarvitdbmigration@^4.0.1
Updatedlarvitutils@^2.0.0
Updateduuid@^3.3.2