Created
August 29, 2012 18:36
-
-
Save vincentmac/3516816 to your computer and use it in GitHub Desktop.
Riak-js: User Model
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/*! | |
* user.js | |
* User Model using Riak as a datastore | |
*/ | |
/** | |
* Model dependencies | |
*/ | |
var db = require('riak-js').getClient({debug: true, port:8091, api: 'http'}); | |
var bcrypt = require('bcrypt'); | |
var util = require('util'); | |
var events = require('events'); | |
// Voxer Riak Client congig | |
// var RiakClient = require('riak'); | |
// var servers = ['127.0.0.1:8091']; | |
// var client_id = 'backoffice.io-client'; | |
// var pool_name = 'backoffice.io-pool'; | |
// // var client_id = ''; | |
// // var pool_name = ''; | |
// var client = new RiakClient(servers, client_id, pool_name); | |
// client.debug_mode = true; | |
/** | |
* `User` constructor. Initialize with `data`. | |
* | |
* @param {Object} data | |
* @api public | |
*/ | |
var User = function(data) { | |
events.EventEmitter.call(this); | |
var that = this; | |
this.data = data || {}; | |
}; | |
util.inherits(User, events.EventEmitter); | |
// Enable automatic document indexing in riak | |
// db.enableIndex('users'); // This command not available in the js branch on riak-js | |
/** | |
* Generate bcrypted `password` from plain text `password` | |
* | |
* @param {String} password | |
* @return {String} | |
* @api private | |
*/ | |
function bcryptPassword(password) { | |
console.log('bcrypting/salting password'); | |
var salt = bcrypt.genSaltSync(15); | |
return bcrypt.hashSync(password, salt); | |
} | |
/** | |
* Get user from riak db given `userId` | |
* | |
* @param {String} userId | |
* @return {User} | |
* @api public | |
*/ | |
User.prototype.get = function(userId, callback) { | |
if (typeof callback !== 'function') { | |
callback = function(err, data, meta) { | |
console.log('found user: ', data); | |
return data; | |
}; | |
} | |
db.get('users', userId, callback); | |
}; | |
/** | |
* Search for userId given `username` | |
* | |
* @param {String} username | |
* @return {String} userId | |
* @api public | |
*/ | |
User.prototype.search = function(username, callback) { | |
if (typeof callback !== 'function') { | |
callback = function(err, data) { | |
if (data.docs.length < 1) { return null; } | |
// console.log('[User search] found userId: ', data.docs[0].id); | |
return data.docs[0].id; | |
}; | |
} | |
// console.log('[User search] GET/SEARCH for user'); | |
db.search('users', 'username:' + username, callback); | |
}; | |
/** | |
* Save a new user to riak with metadata `meta` | |
* | |
* @param {Object} meta | |
* @api public | |
*/ | |
User.prototype.create = function(meta, callback) { | |
// bcryptPassword before saving | |
console.log('password: ',this.data.password); | |
this.data.password = bcryptPassword(this.data.password); | |
console.log('bcrypted password: ',this.data.password); | |
console.log('[User Model] create: this.data: ', this.data); | |
// db.save('users', this.data.username, this.data, callback); | |
db.save('users', 0, this.data, meta, callback); | |
}; | |
/** | |
* Save updated user data `data` and metadata `meta` to riak db given `key`. | |
* Verify that password before submitting changes. | |
* | |
* @param {String} userId | |
* @api public | |
*/ | |
User.prototype.save = function(userId, data, meta, callback) { | |
// if new password being set bcryptPassword before saving | |
console.log('[SAVE USER] ', userId); | |
console.log('[SAVE USER DATA] ', data); | |
db.save('users', userId, data, meta, callback); | |
}; | |
/** | |
* Check if a user by the given `email` exists in the riak db. | |
* | |
* @param {String} email | |
* @api public | |
*/ | |
User.prototype.emailExists = function(email, callback) { | |
db.search('users', 'email:' + email, callback); | |
}; | |
/** | |
* Check if a user by the given `username` exists in the riak db. | |
* | |
* @param {String} username | |
* @api public | |
*/ | |
User.prototype.usernameExists = function(username, callback) { | |
db.search('users', 'username:' + username, callback); | |
}; | |
/** | |
* Check if a user by the given `email` and `username` exists. | |
* | |
* @param {String} email | |
* @param {String} username | |
* @return {User} | |
* @api public | |
*/ | |
User.prototype.exists = function(email, username, callback) { | |
if (typeof callback !== 'function') { | |
callback = function(err, data) { | |
if (data.docs.length < 1) { return null; } | |
return data.docs[0].id; | |
}; | |
} | |
var user = new User(); | |
user.emailExists(email, function(err, data) { | |
if (err) { console.log('[User emailExists: Error] ', err); } | |
user.emit('UserModel:emailExists', data); | |
}); | |
user.on('UserModel:emailExists', function(data) { | |
if (data.numFound > 0) { | |
return callback(null, data, {message:'email address exists'}); | |
} | |
user.usernameExists(username, function(err, data) { | |
if (err) { | |
console.log('[User usernameExists: Error] ', err); | |
} | |
user.emit('UserModel:usernameExists', data); | |
}); | |
}); | |
user.on('UserModel:usernameExists', function(data) { | |
if (data.numFound > 0) { | |
return callback(null, data, {message:'username exists'}); | |
} | |
// console.log('new username'); | |
return callback(null, data, {message:'new user'}); | |
}); | |
}; | |
/** | |
* Verify user-provided `password` matches bcrypted password in db | |
* | |
* @param {String} password | |
* @return {User} | |
* @api public | |
*/ | |
User.prototype.verifyPassword = function(password, callback) { | |
console.log('verifying password'); | |
bcrypt.compare(password, this.data.password, callback); | |
}; | |
User.prototype.autoLogin = function(username, password, callback) { | |
//get user this.get(user stuff) | |
}; | |
/** | |
* Authenticate user credentials from user-provided `username` and `password` | |
* | |
* @param {String} username | |
* @param {String} password | |
* @param {Function} callback | |
* @return {Function} callback(err, user [, message]) | |
* @api public | |
*/ | |
User.prototype.authenticate = function(username, password, callback) { | |
console.log('[UserModel] trying authenticate'); | |
this.search(username, function(err, data) { | |
if (err) { return callback(err); } | |
console.log('[UserModel search]: ', data.docs.length); | |
if (data.docs.length < 1) { | |
return callback(null, false, {message: 'Unknown user'}); | |
} | |
// console.log('[UserModel Authenticate] User Id: ', data.docs[0].id); | |
// console.log('[UserModel Authenticate] User data: ', data); | |
var user = new User(); | |
user.get(data.docs[0].id, function(err, data, meta) { | |
// console.log('[UserModel Auth: get user by id] ', data); | |
// console.log('[UserModel Auth: get user by id] ', meta); | |
// return data; | |
user.emit('UserModel:authenticated', data, meta); | |
}); | |
user.on('UserModel:authenticated', function(data, meta) { | |
user.data = data; | |
user.meta = meta; | |
console.log('[UserModel On: authenticated] key: ', user.meta.key); | |
console.log('[UserModel On: authenticated] data: ', user.data); | |
console.log('[UserModel On: authenticated] meta: ', user.meta); | |
// console.log('[UserModel] password: ', user.data.password); | |
user.verifyPassword(password, function(err, passwordCorrect) { | |
if (err) { return callback(err); } | |
if (!passwordCorrect) { return callback(null, false, { message: 'Invalid password' }); } | |
return callback(null, user); | |
}); | |
}); | |
}); | |
}; | |
/** | |
* Delete user from riak by `userId` | |
* | |
* @param {String} userId | |
* @api public | |
*/ | |
User.prototype.remove = function(userId, callback) { | |
console.log('[USER REMOVE] ', userId); | |
// console.log('[DEL CALLBACK fn]', callback); | |
db.remove('users', userId, {}, callback); | |
// client.del('users', userId, callback); // Voxer's Riak Client | |
}; | |
/** | |
* Expose `User`. | |
*/ | |
exports = module.exports = User; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment