user.js |
|
Generated by CoffeeScript 1.9.1 |
(function() {
module.exports = (function() {
var CPREFIX, UPREFIX, common, crypto, cuid, ld, storage, user;
crypto = require('crypto');
ld = require('lodash');
cuid = require('cuid');
storage = require('../storage.js');
common = require('./common.js');
UPREFIX = storage.DBPREFIX.USER;
CPREFIX = storage.DBPREFIX.CONF;
user = {
ids: {}
};
user.fn = {};
user.fn.getPasswordConf = function(callback) {
var _keys;
_keys = [CPREFIX + "passwordMin", CPREFIX + "passwordMax"];
return storage.fn.getKeys(_keys, function(err, results) {
if (err) {
return callback(err);
}
return callback(null, results);
});
};
user.fn.checkPasswordLength = function(password, params) {
var max, min;
min = params[CPREFIX + "passwordMin"];
max = params[CPREFIX + "passwordMax"];
if (password.length < min || password.length > max) {
return new TypeError("password length must be between " + min + " and " + max + " characters");
}
};
user.fn.genPassword = function(old, u, callback) {
return user.fn.getPasswordConf(function(err, res) {
var newPass, oldp;
if (err) {
return callback(err);
}
err = user.fn.checkPasswordLength(u.password, res);
if (err) {
return callback(err);
}
newPass = function() {
return user.fn.hashPassword(null, u.password, function(err, pass) {
if (err) {
return callback(err);
}
u.password = pass;
return callback(null, u);
});
};
if (old) {
oldp = old.password;
return user.fn.hashPassword(oldp.salt, u.password, function(err, p) {
if (err) {
return callback(err);
}
if (p.hash === oldp.hash) {
u.password = oldp;
return callback(null, u);
} else {
return newPass();
}
});
} else {
return newPass();
}
});
};
user.fn.hashPassword = function(salt, password, callback) {
return crypto.randomBytes(40, function(ex, buf) {
var sha512;
if (ex) {
return callback(ex);
}
if (salt == null) {
salt = buf.toString('hex');
}
sha512 = crypto.createHash('sha512');
sha512.update(salt);
return callback(null, {
salt: salt,
hash: sha512.update(password).digest('hex')
});
});
};
user.fn.assignProps = function(params) {
var p, u;
p = params;
u = ld.reduce(['firstname', 'lastname', 'organization'], function(res, v) {
res[v] = ld.isString(p[v]) ? p[v] : '';
return res;
}, {});
u.email = ld.isEmail(p.email) ? p.email : '';
u.groups = [];
return ld.assign({
_id: p._id,
login: p.login,
password: p.password
}, u);
};
user.fn.checkLogin = function(_id, u, callback) {
var e, exists, key;
if (!_id) {
exists = !ld.isUndefined(user.ids[u.login]) || ld.includes(ld.values(user.ids), u._id);
if (exists) {
e = 'user already exists, please choose another login';
return callback(new Error(e));
}
return callback(null);
} else {
if (ld.isUndefined(user.ids[u.login])) {
key = ld.findKey(user.ids, function(uid) {
return uid === _id;
});
delete user.ids[key];
}
return callback(null);
}
};
user.fn.getDel = function(del, login, callback) {
var cb;
if (!ld.isString(login) || ld.isEmpty(login)) {
throw new TypeError('login must be a string');
}
if (ld.isUndefined(user.ids[login])) {
return callback(new Error('user not found'));
}
cb = callback;
if (del) {
cb = function(err, u) {
var GPREFIX;
delete user.ids[u.login];
if (u.groups.length) {
GPREFIX = storage.DBPREFIX.GROUP;
return storage.fn.getKeys(ld.map(u.groups, function(g) {
return GPREFIX + g;
}), function(err, groups) {
if (err) {
return callback(err);
}
groups = ld.reduce(groups, function(memo, g) {
ld.pull(g.users, u._id);
ld.pull(g.admins, u._id);
memo[GPREFIX + g._id] = g;
return memo;
}, {});
return storage.fn.setKeys(groups, function(err) {
if (err) {
return callback(err);
}
return callback(null, u);
});
});
} else {
return callback(null, u);
}
};
}
return common.getDel(del, UPREFIX, user.ids[login], cb);
};
user.fn.set = function(u, callback) {
return storage.db.set(UPREFIX + u._id, u, function(err) {
if (err) {
return callback(err);
}
user.ids[u.login] = u._id;
return callback(null, u);
});
};
user.init = function(callback) {
return storage.db.findKeys(UPREFIX + "*", null, function(err, keys) {
if (err) {
return callback(err);
}
return storage.fn.getKeys(keys, function(err, results) {
if (results) {
user.ids = ld.transform(results, function(memo, val, key) {
return memo[val.login] = key.replace(UPREFIX, '');
});
}
return callback(null);
});
});
};
user.set = function(params, callback) {
var u;
common.addSetInit(params, callback, ['login', 'password']);
u = user.fn.assignProps(params);
if (u._id == null) {
u._id = cuid();
}
return user.fn.checkLogin(params._id, u, function(err) {
if (err) {
return callback(err);
}
if (params._id) {
return user.get(u.login, function(err, dbuser) {
if (err) {
return callback(err);
}
u.groups = dbuser.groups;
return user.fn.genPassword(dbuser, u, function(err, u) {
if (err) {
return callback(err);
}
return user.fn.set(u, callback);
});
});
} else {
return user.fn.genPassword(null, u, function(err, u) {
if (err) {
return callback(err);
}
return user.fn.set(u, callback);
});
}
});
};
user.get = ld.partial(user.fn.getDel, false);
user.del = ld.partial(user.fn.getDel, true);
ld.mixin({
isEmail: function(val) {
var rg;
rg = new RegExp(['[a-z0-9!#$%&\'*+/=?^_`{|}~-]+', '(?:\\.[a-z0-9!#$%&\'*+/=?^_`{|}~-]+)*@(?:[a-z0-9]', '(?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9]', '(?:[a-z0-9-]*[a-z0-9])?'].join(''));
return ld.isString(val) && rg.test(val);
}
});
return user;
})();
}).call(this);
|