larvituser
Advanced tools
Comparing version 0.0.3-beta to 0.0.4-beta
1025
larvituser.js
@@ -11,2 +11,383 @@ /*jslint node: true */ | ||
/** | ||
* Control the database structure and create if it not exists | ||
*/ | ||
function checkDbStructure(callback) { | ||
var localFuncs = {}; | ||
if (dbChecked) { | ||
callback(); | ||
} else if (dbCheckStarted) { | ||
// If it have started, but not finnished, run it again next tick until it is done | ||
setImmediate(function() { | ||
checkDbStructure(callback); | ||
}); | ||
} else { | ||
dbCheckStarted = true; | ||
// We need to run the checks for user_users first | ||
// If this succeeds, run all the others from it | ||
db.query('DESCRIBE `user_users`', function(err) { | ||
var sql; | ||
if (err) { | ||
// Table does not exist, create it | ||
if (err.code === 'ER_NO_SUCH_TABLE') { | ||
log.info('larvituser: checkDbStructure() - Table user_users did not exist, creating.'); | ||
sql = 'CREATE TABLE `user_users` (' + | ||
' `id` bigint(20) NOT NULL AUTO_INCREMENT,' + | ||
' `username` varchar(255) COLLATE utf8_unicode_ci NOT NULL,' + | ||
' `password` varchar(100) COLLATE utf8_unicode_ci NOT NULL,' + | ||
' PRIMARY KEY (`id`),' + | ||
' UNIQUE KEY `username` (`username`)' + | ||
') ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;'; | ||
db.query(sql, function(err) { | ||
if (err) { | ||
process.exit(1); | ||
} | ||
localFuncs.checkFields(); | ||
}); | ||
} else { | ||
process.exit(1); | ||
} | ||
} else { | ||
localFuncs.checkFields(); | ||
} | ||
}); | ||
localFuncs.checkFields = function() { | ||
db.query('DESCRIBE `user_data_fields`', function(err) { | ||
var sql; | ||
if (err) { | ||
// Table does not exist, create it | ||
if (err.code === 'ER_NO_SUCH_TABLE') { | ||
log.info('larvituser: checkDbStructure() - Table user_data_fields did not exist, creating.'); | ||
sql = 'CREATE TABLE `user_data_fields` (' + | ||
' `id` int(11) NOT NULL AUTO_INCREMENT,' + | ||
' `name` varchar(255) COLLATE utf8_unicode_ci NOT NULL,' + | ||
' PRIMARY KEY (`id`),' + | ||
' UNIQUE KEY `name` (`name`)' + | ||
') ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;'; | ||
db.query(sql, function(err) { | ||
if (err) { | ||
process.exit(1); | ||
} | ||
localFuncs.rolesRights(); | ||
}); | ||
} else { | ||
process.exit(1); | ||
} | ||
} else { | ||
localFuncs.rolesRights(); | ||
} | ||
}); | ||
}; | ||
localFuncs.rolesRights = function() { | ||
db.query('DESCRIBE `user_roles_rights`', function(err) { | ||
var sql; | ||
if (err) { | ||
// Table does not exist, create it | ||
if (err.code === 'ER_NO_SUCH_TABLE') { | ||
log.info('larvituser: checkDbStructure() - Table user_roles_rights did not exist, creating.'); | ||
sql = 'CREATE TABLE `user_roles_rights` (' + | ||
' `role` varchar(128) NOT NULL,' + | ||
' `uri` varchar(128) NOT NULL,' + | ||
' PRIMARY KEY (`role`,`uri`)' + | ||
') ENGINE=InnoDB DEFAULT CHARSET=utf8;'; | ||
db.query(sql, function(err) { | ||
if (err) { | ||
process.exit(1); | ||
} | ||
localFuncs.usersData(); | ||
}); | ||
} else { | ||
process.exit(1); | ||
} | ||
} else { | ||
localFuncs.usersData(); | ||
} | ||
}); | ||
}; | ||
localFuncs.usersData = function() { | ||
db.query('DESCRIBE `user_users_data`', function(err) { | ||
var sql; | ||
if (err) { | ||
// Table does not exist, create it | ||
if (err.code === 'ER_NO_SUCH_TABLE') { | ||
log.info('larvituser: checkDbStructure() - Table user_users_data did not exist, creating.'); | ||
sql = 'CREATE TABLE `user_users_data` (' + | ||
' `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,' + | ||
' `user_id` bigint(20) DEFAULT NULL,' + | ||
' `field_id` int(11) DEFAULT NULL,' + | ||
' `data` text COLLATE utf8_unicode_ci NOT NULL,' + | ||
' PRIMARY KEY (`id`),' + | ||
' KEY `users_fields` (`user_id`,`field_id`),' + | ||
' KEY `field_id` (`field_id`),' + | ||
' CONSTRAINT `user_users_data_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `user_users` (`id`),' + | ||
' CONSTRAINT `user_users_data_ibfk_2` FOREIGN KEY (`field_id`) REFERENCES `user_data_fields` (`id`)' + | ||
') ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;'; | ||
db.query(sql, function(err) { | ||
if (err) { | ||
process.exit(1); | ||
} | ||
dbChecked = true; | ||
callback(); | ||
}); | ||
} else { | ||
process.exit(1); | ||
} | ||
} else { | ||
dbChecked = true; | ||
callback(); | ||
} | ||
}); | ||
}; | ||
} | ||
} | ||
/** | ||
* Set a single user field to database | ||
* | ||
* @param int userId | ||
* @param str fieldName | ||
* @param str fieldValue | ||
* @param func callback(err) | ||
*/ | ||
function setUserField(userId, fieldName, fieldValue, callback) { | ||
fieldValue = String(fieldValue).trim(); | ||
exports.getFieldId(fieldName, function(err, fieldId) { | ||
var sql = 'INSERT INTO user_users_data (user_id, field_id, data) VALUES(?,?,?)', | ||
dbFields = [userId, fieldId, fieldValue]; | ||
if (err) { | ||
log.error('larvituser: setUserField() - ' + err.message, err); | ||
return; | ||
} | ||
db.query(sql, dbFields, function(err) { | ||
if (err) { | ||
callback(err); | ||
return; | ||
} | ||
callback(); | ||
}); | ||
}); | ||
} | ||
/** | ||
* Replace user fields | ||
* IMPORTANT!!! Will clear all data not given in the fields parameter | ||
* | ||
* @param int userId | ||
* @param obj fields - field name as key, field values as array to that key - ex: {'role': ['admin','user']} | ||
* @param func callback(err) | ||
*/ | ||
function replaceUserFields(userId, fields, callback) { | ||
var sql = 'DELETE FROM user_users_data WHERE user_id = ?', | ||
dbFields = [userId]; | ||
// We need to do this to make sure they all happend before we call the final callback | ||
function callSetUserField(userId, fieldName, fieldValue, nextParams, callback) { | ||
setUserField(userId, fieldName, fieldValue, function(err) { | ||
var entries; | ||
if (err) { | ||
callback(err); | ||
} else { | ||
if (nextParams.length) { | ||
entries = nextParams.shift(); | ||
callSetUserField(entries.userId, entries.fieldName, entries.fieldValue, nextParams, callback); | ||
} else { | ||
callback(); | ||
} | ||
} | ||
}); | ||
} | ||
log.verbose('larvituser: replaceUserFields() - Removing previous user fields', {'userId': userId, 'sql': sql, 'dbFields': dbFields}); | ||
db.query(sql, dbFields, function(err) { | ||
var userFieldParams = [], | ||
i = 0, | ||
fieldName, | ||
field, | ||
firstEntries; | ||
if (err) { | ||
callback(err); | ||
return; | ||
} | ||
log.debug('larvituser: replaceUserFields() - User fields removed', {'userId': userId}); | ||
for (fieldName in fields) { | ||
field = fields[fieldName]; | ||
// Make sure this fields values are always represented as array | ||
if (field.constructor !== Array) { | ||
field = [fields[fieldName]]; | ||
} | ||
i = 0; | ||
while (field[i] !== undefined) { | ||
log.silly('larvituser: replaceUserFields() - Adding userFieldParam to array', {'userId': userId, 'fieldName': fieldName, 'fieldValue': field[i]}); | ||
userFieldParams.push({ | ||
'userId': userId, | ||
'fieldName': fieldName, | ||
'fieldValue': field[i] | ||
}); | ||
i ++; | ||
} | ||
} | ||
firstEntries = userFieldParams.shift(); | ||
callSetUserField(firstEntries.userId, firstEntries.fieldName, firstEntries.fieldValue, userFieldParams, function(err) { | ||
if (err) { | ||
callback(err); | ||
} else { | ||
callback(); | ||
} | ||
}); | ||
}); | ||
} | ||
/** | ||
* Remove a user field | ||
* | ||
* @param int userId | ||
* @param str fieldName | ||
* @param func callback(err) | ||
*/ | ||
function rmUserField(userId, fieldName, callback) { | ||
exports.getFieldId(fieldName, function(err, fieldId) { | ||
var sql = 'DELETE FROM user_users_data WHERE user_id = ? AND field_id = ?', | ||
dbFields = [userId, fieldId]; | ||
if (err) { | ||
callback(err); | ||
return; | ||
} | ||
log.debug('larvituser: rmUserField() - Removing field from user', {'sql': sql, 'dbFields': dbFields}); | ||
db.query(sql, dbFields, function(err) { | ||
if (err) { | ||
callback(err); | ||
} else { | ||
callback(); | ||
} | ||
}); | ||
}); | ||
} | ||
function userBase() { | ||
var returnObj = {'fields': {}}; | ||
/** | ||
* Add a field with value | ||
* | ||
* @param str name | ||
* @param str value | ||
* @param func callback(err) | ||
*/ | ||
returnObj.addField = function(name, value, callback) { | ||
var err; | ||
if (returnObj.id === undefined) { | ||
err = new Error('Cannot add field; no user loaded'); | ||
callback(err); | ||
return; | ||
} | ||
setUserField(returnObj.id, name, value, function(err) { | ||
if (err) { | ||
callback(err); | ||
} else { | ||
if (returnObj.fields[name] === undefined) { | ||
returnObj.fields[name] = []; | ||
} | ||
returnObj.fields[name].push(value); | ||
callback(); | ||
} | ||
}); | ||
}; | ||
/** | ||
* 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 callback(err) | ||
*/ | ||
returnObj.replaceFields = function(fields, callback) { | ||
var err; | ||
if (returnObj.id === undefined) { | ||
err = new Error('Cannot replace fields; no user loaded'); | ||
callback(err); | ||
return; | ||
} | ||
replaceUserFields(returnObj.id, fields, function(err) { | ||
if (err) { | ||
callback(err); | ||
} else { | ||
// Reload everything | ||
exports.fromId(returnObj.id, function(err, user) { | ||
if (err) { | ||
callback(err); | ||
} else { | ||
returnObj.fields = user.fields; | ||
callback(); | ||
} | ||
}); | ||
} | ||
}); | ||
}; | ||
/** | ||
* Remove a field from this user | ||
* | ||
* @param str name | ||
* @param func callback(err) | ||
*/ | ||
returnObj.rmField = function(name, callback) { | ||
var err; | ||
if (returnObj.id === undefined) { | ||
err = new Error('Cannot remove field; no user loaded'); | ||
callback(err); | ||
return; | ||
} | ||
rmUserField(returnObj.id, name, function(err) { | ||
if (err) { | ||
callback(err); | ||
} else { | ||
delete returnObj.fields[name]; | ||
callback(); | ||
} | ||
}); | ||
}; | ||
return returnObj; | ||
} | ||
/** | ||
* Checks a password for validity | ||
@@ -23,3 +404,3 @@ * | ||
if (err) { | ||
log.error(err); | ||
log.error('larvituser: checkPassword() - ' + err.message, err); | ||
callback(err); | ||
@@ -29,6 +410,7 @@ return; | ||
if (res) | ||
if (res) { | ||
callback(null, true); | ||
else | ||
} else { | ||
callback(null, false); | ||
} | ||
}); | ||
@@ -46,8 +428,64 @@ }; | ||
exports.create = function create(username, password, fields, callback) { | ||
var hashedPassword, | ||
userId, | ||
err; | ||
// Write the fields to the db | ||
function writeFieldsToDb() { | ||
replaceUserFields(userId, fields, function(err) { | ||
if (err) { | ||
log.error('larvituser: create() - ' + err.message, err); | ||
callback(err); | ||
return; | ||
} | ||
log.debug('larvituser: create() - Fields written successfully to database', {'username': username, 'userId': userId, 'fields': fields}); | ||
exports.fromId(userId, function(err, user) { | ||
if (err) { | ||
log.error('larvituser: create() - ' + err.message, err); | ||
callback(err); | ||
return; | ||
} | ||
callback(null, user); | ||
}); | ||
}); | ||
} | ||
// Write to database - called from the above callback | ||
function writeToDb() { | ||
var sql = 'INSERT INTO user_users (username, password) VALUES(?,?);', | ||
dbFields = [username, hashedPassword]; | ||
log.verbose('larvituser: create() - Trying to write username and password to database', {'sql': sql, 'fields': dbFields}); | ||
db.query(sql, dbFields, function(err, res) { | ||
if (err) { | ||
callback(err); | ||
return; | ||
} | ||
userId = res.insertId; | ||
log.debug('larvituser: create() - Write to db successfull! Moving on to writing fields to database', {'username': username, 'userId': userId}); | ||
writeFieldsToDb(); | ||
}); | ||
} | ||
// Hash password - called from the above callback | ||
function hashPassword() { | ||
exports.hashPassword(password, function(err, hash) { | ||
if (err) { | ||
callback(err); | ||
} else { | ||
hashedPassword = hash; | ||
log.debug('larvituser: create() - Password hashed, moving on to writing username and password to database', {'username': username}); | ||
writeToDb(); | ||
} | ||
}); | ||
} | ||
checkDbStructure(function() { | ||
log.verbose('Trying to create user', {'username': username, 'fields': fields}); | ||
log.verbose('larvituser: create() - Trying to create user', {'username': username, 'fields': fields}); | ||
var hashedPassword, | ||
userId; | ||
username = username.trim(); | ||
@@ -57,4 +495,4 @@ password = password.trim(); | ||
if ( ! username.length) { | ||
var err = new Error('Trying to create user with empty username'); | ||
log.warn(err); | ||
err = new Error('Trying to create user with empty username'); | ||
log.warn('larvituser: create() - ' + err.message, err); | ||
callback(err); | ||
@@ -64,3 +502,3 @@ return; | ||
// Control if username is available | ||
// Check if username is available | ||
exports.usernameAvailable(username, function(err, res) { | ||
@@ -70,65 +508,10 @@ if (err) { | ||
} else if ( ! res) { | ||
var customErr = new Error('Trying to create user with taken username: "' + username + '"'); | ||
log.info(customErr); | ||
callback(customErr); | ||
err = new Error('Trying to create user with taken username: "' + username + '"'); | ||
log.info('larvituser: create() - ' + err.message, err); | ||
callback(err); | ||
} else { | ||
log.debug('Username available, moving on to hashing password', {'username': username}); | ||
log.debug('larvituser: create() - Username available, moving on to hashing password', {'username': username}); | ||
hashPassword(); | ||
} | ||
}); | ||
// Hash password - called from the above callback | ||
function hashPassword() { | ||
exports.hashPassword(password, function(err, hash) { | ||
if (err) { | ||
callback(err); | ||
} else { | ||
hashedPassword = hash; | ||
log.debug('Password hashed, moving on to writing username and password to database', {'username': username}); | ||
writeToDb(); | ||
} | ||
}); | ||
} | ||
// Write to database - called from the above callback | ||
function writeToDb() { | ||
var sql = 'INSERT INTO user_users (username, password) VALUES(?,?);', | ||
dbFields = [username, hashedPassword]; | ||
log.verbose('Trying to write username and password to database', {'sql': sql, 'fields': dbFields}); | ||
db.query(sql, dbFields, function(err, res) { | ||
if (err) { | ||
callback(err); | ||
return; | ||
} | ||
userId = res.insertId; | ||
log.debug('Write to db successfull! Moving on to writing fields to database', {'username': username, 'userId': userId}); | ||
writeFieldsToDb(); | ||
}); | ||
} | ||
// Write the fields to the db | ||
function writeFieldsToDb() { | ||
replaceUserFields(userId, fields, function(err) { | ||
if (err) { | ||
log.error(err); | ||
callback(err); | ||
return; | ||
} | ||
log.debug('Fields written successfully to database', {'username': username, 'userId': userId, 'fields': fields}); | ||
exports.fromId(userId, function(err, user) { | ||
if (err) { | ||
log.error(err); | ||
callback(err); | ||
return; | ||
} | ||
callback(null, user); | ||
}); | ||
}); | ||
} | ||
}); | ||
@@ -146,15 +529,19 @@ }; | ||
var returnObj = userBase(), | ||
dbFields = [userId]; | ||
rowNr = 0, | ||
fields = returnObj.fields, | ||
dbFields = [userId], | ||
row, | ||
sql = 'SELECT ' + | ||
'u.id, ' + | ||
'u.username, ' + | ||
'uf.id AS field_id, ' + | ||
'uf.name AS field_name, ' + | ||
'ud.data AS field_data ' + | ||
'FROM ' + | ||
'user_users u ' + | ||
'LEFT JOIN user_users_data ud ON ud.user_id = u.id ' + | ||
'LEFT JOIN user_data_fields uf ON uf.id = ud.field_id ' + | ||
'WHERE u.id = ?'; | ||
var sql = 'SELECT ' + | ||
'u.id, ' + | ||
'u.username, ' + | ||
'uf.id AS field_id, ' + | ||
'uf.name AS field_name, ' + | ||
'ud.data AS field_data ' + | ||
'FROM ' + | ||
'user_users u ' + | ||
'LEFT JOIN user_users_data ud ON ud.user_id = u.id ' + | ||
'LEFT JOIN user_data_fields uf ON uf.id = ud.field_id ' + | ||
'WHERE u.id = ?'; | ||
log.silly('larvituser: fromId() - SQL query', {'sql': sql, 'dbFields': dbFields}); | ||
@@ -168,22 +555,20 @@ db.query(sql, dbFields, function(err, rows) { | ||
if (rows.length === 0) { | ||
var customErr = new Error('No user found for user ID: "' + userId + '"'); | ||
customErr.sql = sql; | ||
log.debug(customErr); | ||
callback(customErr); | ||
err = new Error('No user found for user ID: "' + userId + '"'); | ||
err.sql = sql; | ||
log.debug('larvituser: create() - ' + err.message, err); | ||
callback(err); | ||
return; | ||
} | ||
returnObj.fields = {}; | ||
returnObj.id = rows[0].id; | ||
returnObj.username = rows[0].username; | ||
var rowNr = 0, | ||
fields = returnObj.fields; | ||
rowNr = 0; | ||
while (rows[rowNr] !== undefined) { | ||
var row = rows[rowNr]; | ||
row = rows[rowNr]; | ||
if (row.field_id) { | ||
if (fields[row.field_name] === undefined) | ||
if (fields[row.field_name] === undefined) { | ||
fields[row.field_name] = []; | ||
} | ||
@@ -193,3 +578,3 @@ fields[row.field_name].push(row.field_data); | ||
rowNr++; | ||
rowNr ++; | ||
} | ||
@@ -211,9 +596,10 @@ | ||
checkDbStructure(function() { | ||
var sql = 'SELECT id, password FROM user_users WHERE username = ?', | ||
dbFields; | ||
username = username.trim(); | ||
password = password.trim(); | ||
dbFields = [username]; | ||
var sql = 'SELECT id, password FROM user_users WHERE username = ?', | ||
fields = [username]; | ||
db.query(sql, fields, function(err, rows) { | ||
db.query(sql, dbFields, function(err, rows) { | ||
if (err) { | ||
@@ -225,6 +611,6 @@ callback(err); | ||
if (rows.length === 0) { | ||
var customErr = new Error('No user found for username: "' + username + '"'); | ||
customErr.sql = sql; | ||
log.verbose(customErr); | ||
callback(customErr); | ||
err = new Error('No user found for username: "' + username + '"'); | ||
err.sql = sql; | ||
log.verbose('larvituser: fromUserAndPass() - ' + err.message, err); | ||
callback(err); | ||
return; | ||
@@ -235,3 +621,3 @@ } | ||
if (err) { | ||
log.error(err); | ||
log.error('larvituser: fromUserAndPass() - ' + err.message, err); | ||
callback(err); | ||
@@ -246,5 +632,5 @@ return; | ||
} else { | ||
var customErr = new Error('Login failed, wrong password. Username: "' + username + '"'); | ||
log.info(customErr); | ||
callback(customErr); | ||
err = new Error('Login failed, wrong password. Username: "' + username + '"'); | ||
log.info('larvituser: fromUserAndPass() - ' + err.message, err); | ||
callback(err); | ||
} | ||
@@ -264,8 +650,10 @@ }); | ||
checkDbStructure(function() { | ||
var sql, | ||
dbFields; | ||
username = username.trim(); | ||
sql = 'SELECT id FROM user_users WHERE username = ?'; | ||
dbFields = [username]; | ||
var sql = 'SELECT id FROM user_users WHERE username = ?', | ||
fields = [username]; | ||
db.query(sql, fields, function(err, rows) { | ||
db.query(sql, dbFields, function(err, rows) { | ||
if (err) { | ||
@@ -277,6 +665,6 @@ callback(err); | ||
if (rows.length === 0) { | ||
var customErr = new Error('No user found for username: "' + username + '"'); | ||
customErr.sql = sql; | ||
log.debug(customErr); | ||
callback(customErr); | ||
err = new Error('No user found for username: "' + username + '"'); | ||
err.sql = sql; | ||
log.debug('larvituser: fromUsername() - ' + err.message, err); | ||
callback(err); | ||
return; | ||
@@ -300,2 +688,5 @@ } | ||
exports.getFieldId(fieldName, function(err, fieldId) { | ||
var sql = 'SELECT data FROM user_users_data WHERE user_id = ? AND field_id = ?', | ||
dbFields = [userId, fieldId]; | ||
if (err) { | ||
@@ -306,6 +697,6 @@ callback(err); | ||
var sql = 'SELECT data FROM user_users_data WHERE user_id = ? AND field_id = ?', | ||
dbFields = [userId, fieldId]; | ||
db.query(sql, dbFields, function(err, rows) { | ||
var data = [], | ||
rowNr = 0; | ||
db.query(sql, dbFields, function(err, rows) { | ||
if (err) { | ||
@@ -316,8 +707,5 @@ callback(err); | ||
var data = [], | ||
rowNr = 0; | ||
while (rows[rowNr] !== undefined) { | ||
data.push(rows[rowNr].data); | ||
rowNr++; | ||
rowNr ++; | ||
} | ||
@@ -338,8 +726,11 @@ | ||
checkDbStructure(function() { | ||
var sql = 'SELECT id FROM user_data_fields WHERE name = ?', | ||
dbFields; | ||
fieldName = fieldName.trim(); | ||
dbFields = [fieldName]; | ||
var sql = 'SELECT id FROM user_data_fields WHERE name = ?', | ||
dbFields = [fieldName]; | ||
db.query(sql, dbFields, function(err, rows) { | ||
var sql = 'INSERT IGNORE INTO user_data_fields (name) VALUES(?)'; | ||
db.query(sql, dbFields, function(err, rows) { | ||
if (err) { | ||
@@ -354,4 +745,2 @@ callback(err); | ||
// Use INSERT IGNORE to avoid race conditions | ||
var sql = 'INSERT IGNORE INTO user_data_fields (name) VALUES(?)'; | ||
db.query(sql, dbFields, function(err) { | ||
@@ -393,4 +782,4 @@ if (err) { | ||
} else { | ||
var customErr = new Error('Field name not found for id: "' + fieldId + '"'); | ||
callback(customErr); | ||
err = new Error('Field name not found for id: "' + fieldId + '"'); | ||
callback(err); | ||
} | ||
@@ -412,3 +801,3 @@ }); | ||
if (err) { | ||
log.error(err); | ||
log.error('larvituser: hashPassword() - ' + err.message, err); | ||
callback(err); | ||
@@ -420,3 +809,3 @@ return; | ||
if (err) { | ||
log.error(err); | ||
log.error('larvituser: hashPassword() - ' + err.message, err); | ||
callback(err); | ||
@@ -439,8 +828,9 @@ return; | ||
checkDbStructure(function() { | ||
var sql = 'SELECT id FROM user_users WHERE username = ?', | ||
dbFields; | ||
username = username.trim(); | ||
dbFields = [username]; | ||
var sql = 'SELECT id FROM user_users WHERE username = ?', | ||
fields = [username]; | ||
db.query(sql, fields, function(err, rows) { | ||
db.query(sql, dbFields, function(err, rows) { | ||
if (err) { | ||
@@ -451,374 +841,9 @@ callback(err); | ||
if (rows.length) | ||
if (rows.length) { | ||
callback(null, false); | ||
else | ||
} else { | ||
callback(null, true); | ||
}); | ||
}); | ||
}; | ||
function userBase() { | ||
var returnObj = {}; | ||
/** | ||
* Add a field with value | ||
* | ||
* @param str name | ||
* @param str value | ||
* @param func callback(err) | ||
*/ | ||
returnObj.addField = function(name, value, callback) { | ||
if (returnObj.id === undefined) { | ||
var err = new Error('Cannot add field; no user loaded'); | ||
callback(err); | ||
return; | ||
} | ||
setUserField(returnObj.id, name, value, function(err) { | ||
if (err) { | ||
callback(err); | ||
} else { | ||
if (returnObj.fields[name] === undefined) | ||
returnObj.fields[name] = []; | ||
returnObj.fields[name].push(value); | ||
callback(); | ||
} | ||
}); | ||
}; | ||
/** | ||
* 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 callback(err) | ||
*/ | ||
returnObj.replaceFields = function(fields, callback) { | ||
if (returnObj.id === undefined) { | ||
var err = new Error('Cannot replace fields; no user loaded'); | ||
callback(err); | ||
return; | ||
} | ||
replaceUserFields(returnObj.id, fields, function(err) { | ||
if (err) { | ||
callback(err); | ||
} else { | ||
// Reload everything | ||
exports.fromId(returnObj.id, function(err, user) { | ||
if (err) { | ||
callback(err); | ||
} else { | ||
returnObj.fields = user.fields; | ||
callback(); | ||
} | ||
}); | ||
} | ||
}); | ||
}; | ||
/** | ||
* Remove a field from this user | ||
* | ||
* @param str name | ||
* @param func callback(err) | ||
*/ | ||
returnObj.rmField = function(name, callback) { | ||
if (returnObj.id === undefined) { | ||
var err = new Error('Cannot remove field; no user loaded'); | ||
callback(err); | ||
return; | ||
} | ||
rmUserField(returnObj.id, name, function(err) { | ||
if (err) { | ||
callback(err); | ||
} else { | ||
delete returnObj.fields[name]; | ||
callback(); | ||
} | ||
}); | ||
}; | ||
return returnObj; | ||
} | ||
/** | ||
* Replace user fields | ||
* IMPORTANT!!! Will clear all data not given in the fields parameter | ||
* | ||
* @param int userId | ||
* @param obj fields - field name as key, field values as array to that key - ex: {'role': ['admin','user']} | ||
* @param func callback(err) | ||
*/ | ||
function replaceUserFields(userId, fields, callback) { | ||
var sql = 'DELETE FROM user_users_data WHERE user_id = ?', | ||
dbFields = [userId]; | ||
log.verbose('Removing previous user fields', {'userId': userId, 'sql': sql, 'dbFields': dbFields}); | ||
db.query(sql, dbFields, function(err) { | ||
if (err) { | ||
callback(err); | ||
return; | ||
} | ||
log.debug('User fields removed', {'userId': userId}); | ||
var userFieldParams = []; | ||
for (var fieldName in fields) { | ||
var field = fields[fieldName], | ||
i = 0; | ||
// Make sure this fields values are always represented as array | ||
if (field.constructor !== Array) | ||
field = [fields[fieldName]]; | ||
while (field[i] !== undefined) { | ||
log.silly('Adding userFieldParam to array', {'userId': userId, 'fieldName': fieldName, 'fieldValue': field[i]}); | ||
userFieldParams.push({ | ||
'userId': userId, | ||
'fieldName': fieldName, | ||
'fieldValue': field[i] | ||
}); | ||
i++; | ||
} | ||
} | ||
var firstEntries = userFieldParams.shift(); | ||
callSetUserField(firstEntries.userId, firstEntries.fieldName, firstEntries.fieldValue, userFieldParams, function(err) { | ||
if (err) | ||
callback(err); | ||
else | ||
callback(); | ||
}); | ||
}); | ||
// We need to do this to make sure they all happend before we call the final callback | ||
function callSetUserField(userId, fieldName, fieldValue, nextParams, callback) { | ||
setUserField(userId, fieldName, fieldValue, function(err) { | ||
if (err) { | ||
callback(err); | ||
} else { | ||
if (nextParams.length) { | ||
var entries = nextParams.shift(); | ||
callSetUserField(entries.userId, entries.fieldName, entries.fieldValue, nextParams, callback); | ||
} else { | ||
callback(); | ||
} | ||
} | ||
}); | ||
} | ||
} | ||
/** | ||
* Remove a user field | ||
* | ||
* @param int userId | ||
* @param str fieldName | ||
* @param func callback(err) | ||
*/ | ||
function rmUserField(userId, fieldName, callback) { | ||
exports.getFieldId(fieldName, function(err, fieldId) { | ||
if (err) { | ||
callback(err); | ||
return; | ||
} | ||
var sql = 'DELETE FROM user_users_data WHERE user_id = ? AND field_id = ?', | ||
dbFields = [userId, fieldId]; | ||
log.debug('Removing field from user', {'sql': sql, 'dbFields': dbFields}); | ||
db.query(sql, dbFields, function(err) { | ||
if (err) | ||
callback(err); | ||
else | ||
callback(); | ||
}); | ||
}); | ||
} | ||
/** | ||
* Set a single user field | ||
* | ||
* @param int userId | ||
* @param str fieldName | ||
* @param str fieldValue | ||
* @param func callback(err) | ||
*/ | ||
function setUserField(userId, fieldName, fieldValue, callback) { | ||
fieldValue = String(fieldValue); | ||
fieldValue = fieldValue.trim(); | ||
exports.getFieldId(fieldName, function(err, fieldId) { | ||
if (err) { | ||
log.error(err); | ||
return; | ||
} | ||
var sql = 'INSERT INTO user_users_data (user_id, field_id, data) VALUES(?,?,?)', | ||
dbFields = [userId, fieldId, fieldValue]; | ||
db.query(sql, dbFields, function(err) { | ||
if (err) { | ||
callback(err); | ||
return; | ||
} | ||
callback(); | ||
}); | ||
}); | ||
} | ||
/** | ||
* Control the database structure and create if it not exists | ||
*/ | ||
function checkDbStructure(callback) { | ||
if (dbChecked) { | ||
callback(); | ||
} else if (dbCheckStarted) { | ||
// If it have started, but not finnished, run it again next tick until it is done | ||
setImmediate(function() { | ||
checkDbStructure(callback); | ||
}); | ||
} else { | ||
dbCheckStarted = true; | ||
var localFuncs = {}; | ||
// We need to run the checks for user_users first | ||
// If this succeeds, run all the others from it | ||
db.query('DESCRIBE `user_users`', function(err) { | ||
if (err) { | ||
// Table does not exist, create it | ||
if (err.code === 'ER_NO_SUCH_TABLE') { | ||
log.info('Table user_users did not exist, creating.'); | ||
var sql = 'CREATE TABLE `user_users` (' + | ||
' `id` bigint(20) NOT NULL AUTO_INCREMENT,' + | ||
' `username` varchar(255) COLLATE utf8_unicode_ci NOT NULL,' + | ||
' `password` varchar(100) COLLATE utf8_unicode_ci NOT NULL,' + | ||
' PRIMARY KEY (`id`),' + | ||
' UNIQUE KEY `username` (`username`)' + | ||
') ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;'; | ||
db.query(sql, function(err) { | ||
if (err) { | ||
log.error('Failed creating table user_users.'); | ||
process.exit(1); | ||
} | ||
localFuncs.checkFields(); | ||
}); | ||
} else { | ||
log.error(err); | ||
process.exit(1); | ||
} | ||
} else { | ||
localFuncs.checkFields(); | ||
} | ||
}); | ||
localFuncs.checkFields = function() { | ||
db.query('DESCRIBE `user_data_fields`', function(err) { | ||
if (err) { | ||
// Table does not exist, create it | ||
if (err.code === 'ER_NO_SUCH_TABLE') { | ||
log.info('Table user_data_fields did not exist, creating.'); | ||
var sql = 'CREATE TABLE `user_data_fields` (' + | ||
' `id` int(11) NOT NULL AUTO_INCREMENT,' + | ||
' `name` varchar(255) COLLATE utf8_unicode_ci NOT NULL,' + | ||
' PRIMARY KEY (`id`),' + | ||
' UNIQUE KEY `name` (`name`)' + | ||
') ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;'; | ||
db.query(sql, function(err) { | ||
if (err) { | ||
log.error('Failed creating table user_data_fields.'); | ||
process.exit(1); | ||
} | ||
localFuncs.rolesRights(); | ||
}); | ||
} else { | ||
log.error(err); | ||
process.exit(1); | ||
} | ||
} else { | ||
localFuncs.rolesRights(); | ||
} | ||
}); | ||
}; | ||
localFuncs.rolesRights = function() { | ||
db.query('DESCRIBE `user_roles_rights`', function(err) { | ||
if (err) { | ||
// Table does not exist, create it | ||
if (err.code === 'ER_NO_SUCH_TABLE') { | ||
log.info('Table user_roles_rights did not exist, creating.'); | ||
var sql = 'CREATE TABLE `user_roles_rights` (' + | ||
' `role` varchar(128) NOT NULL,' + | ||
' `uri` varchar(128) NOT NULL,' + | ||
' PRIMARY KEY (`role`,`uri`)' + | ||
') ENGINE=InnoDB DEFAULT CHARSET=utf8;'; | ||
db.query(sql, function(err) { | ||
if (err) { | ||
log.error('Failed creating table user_roles_rights.'); | ||
process.exit(1); | ||
} | ||
localFuncs.usersData(); | ||
}); | ||
} else { | ||
log.error(err); | ||
process.exit(1); | ||
} | ||
} else { | ||
localFuncs.usersData(); | ||
} | ||
}); | ||
}; | ||
localFuncs.usersData = function() { | ||
db.query('DESCRIBE `user_users_data`', function(err) { | ||
if (err) { | ||
// Table does not exist, create it | ||
if (err.code === 'ER_NO_SUCH_TABLE') { | ||
log.info('Table user_users_data did not exist, creating.'); | ||
var sql = 'CREATE TABLE `user_users_data` (' + | ||
' `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,' + | ||
' `user_id` bigint(20) DEFAULT NULL,' + | ||
' `field_id` int(11) DEFAULT NULL,' + | ||
' `data` text COLLATE utf8_unicode_ci NOT NULL,' + | ||
' PRIMARY KEY (`id`),' + | ||
' KEY `users_fields` (`user_id`,`field_id`),' + | ||
' KEY `field_id` (`field_id`),' + | ||
' CONSTRAINT `user_users_data_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `user_users` (`id`),' + | ||
' CONSTRAINT `user_users_data_ibfk_2` FOREIGN KEY (`field_id`) REFERENCES `user_data_fields` (`id`)' + | ||
') ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;'; | ||
db.query(sql, function(err) { | ||
if (err) { | ||
log.error('Failed creating table user_users_data.'); | ||
process.exit(1); | ||
} | ||
dbChecked = true; | ||
callback(); | ||
}); | ||
} else { | ||
log.error(err); | ||
process.exit(1); | ||
} | ||
} else { | ||
dbChecked = true; | ||
callback(); | ||
} | ||
}); | ||
}; | ||
} | ||
} | ||
}; |
@@ -30,5 +30,5 @@ { | ||
}, | ||
"version": "0.0.3beta", | ||
"version": "0.0.4beta", | ||
"readmeFilename": "README.md", | ||
"license": "MIT" | ||
} |
@@ -1,3 +0,1 @@ | ||
/*jslint node: true */ | ||
/*jslint mocha: true */ | ||
'use strict'; | ||
@@ -31,3 +29,3 @@ | ||
'timestamp': true, | ||
'handleExceptions': true, // THis makes winston handle exceptions instead of node native | ||
'handleExceptions': true, // This makes winston handle exceptions instead of node native | ||
'level': 'debug' | ||
@@ -34,0 +32,0 @@ }); |
Manifest confusion
Supply chain riskThis package has inconsistent metadata. This could be malicious or caused by an error when publishing the package.
Found 1 instance in 1 package
Manifest confusion
Supply chain riskThis package has inconsistent metadata. This could be malicious or caused by an error when publishing the package.
Found 1 instance in 1 package
28843
7
886