Files
talk/models/user.js
T
Belén Curcio 5b74beabd6 Community Section - Search Commenters (#60)
* Table

* úsers api

* Ádding envs and version

* Community Table Added

* Ádding redux

* Adding loading data state

* Community Actions

* Adding Inmutable

* Fetching commenters

* Search commenters

* Linting and translations

* Ádding Sort

* sortBuilder

* pagr

* request per page, pager and mor

* package.json

* new Page actiokn

* éslint

* Changes and cleaner comps

* removed console.log
2016-11-11 11:14:26 -05:00

343 lines
7.5 KiB
JavaScript

const mongoose = require('../mongoose');
const uuid = require('uuid');
const bcrypt = require('bcrypt');
const SALT_ROUNDS = 10;
const UserSchema = new mongoose.Schema({
id: {
type: String,
default: uuid.v4,
unique: true,
required: true
},
displayName: String,
disabled: Boolean,
password: String,
profiles: [{
id: {
type: String,
required: true
},
provider: {
type: String,
required: true
}
}],
roles: [String]
}, {
timestamps: {
createdAt: 'created_at',
updatedAt: 'updated_at'
}
});
// Add the indixies on the user profile data.
UserSchema.index({
'profiles.id': 1,
'profiles.provider': 1
}, {
unique: true,
background: false
});
/**
* toJSON overrides to remove the password field from the json
* output.
*/
UserSchema.options.toJSON = {};
UserSchema.options.toJSON.hide = 'password profiles roles disabled';
UserSchema.options.toJSON.transform = (doc, ret, options) => {
if (options.hide) {
options.hide.split(' ').forEach((prop) => {
delete ret[prop];
});
}
return ret;
};
/**
* toObject overrides to remove the password field from the toObject
* output.
*/
UserSchema.options.toObject = {};
UserSchema.options.toObject.hide = 'password';
UserSchema.options.toObject.transform = (doc, ret, options) => {
if (options.hide) {
options.hide.split(' ').forEach((prop) => {
delete ret[prop];
});
}
return ret;
};
/**
* Finds a user given their email address that we have for them in the system
* and ensures that the retuned user matches the password passed in as well.
* @param {string} email - email to look up the user by
* @param {string} password - password to match against the found user
* @param {Function} done [description]
*/
UserSchema.statics.findLocalUser = function(email, password) {
return User.findOne({
profiles: {
$elemMatch: {
id: email,
provider: 'local'
}
}
})
.then((user) => {
if (!user) {
return false;
}
return new Promise((resolve, reject) => {
bcrypt.compare(password, user.password, (err, res) => {
if (err) {
return reject(err);
}
if (!res) {
return resolve(false);
}
return resolve(user);
});
});
});
};
/**
* Merges two users together by taking all the profiles on a given user and
* pushing them into the source user followed by deleting the destination user's
* user account. This will not merge the roles associated with the source user.
* @param {String} dstUserID id of the user to which is the target of the merge
* @param {String} srcUserID id of the user to which is the source of the merge
* @return {Promise} resolves when the users are merged
*/
UserSchema.statics.mergeUsers = function(dstUserID, srcUserID) {
let srcUser, dstUser;
return Promise
.all([
User.findOne({id: dstUserID}).exec(),
User.findOne({id: srcUserID}).exec()
])
.then((users) => {
dstUser = users[0];
srcUser = users[1];
srcUser.profiles.forEach((profile) => {
dstUser.profiles.push(profile);
});
return srcUser.remove();
})
.then(() => dstUser.save());
};
/**
* Finds a user given a social profile and if the user does not exist, creates
* them.
* @param {Object} profile - User social/external profile
* @param {Function} done [description]
*/
UserSchema.statics.findOrCreateExternalUser = function(profile) {
return User
.findOne({
profiles: {
$elemMatch: {
id: profile.id,
provider: profile.provider
}
}
})
.then((user) => {
if (user) {
return user;
}
// The user was not found, lets create them!
user = new User({
displayName: profile.displayName,
roles: [],
profiles: [
{
id: profile.id,
provider: profile.provider
}
]
});
return user.save();
});
};
UserSchema.statics.changePassword = function(id, password) {
return new Promise((resolve, reject) => {
bcrypt.hash(password, SALT_ROUNDS, (err, hashedPassword) => {
if (err) {
return reject(err);
}
resolve(hashedPassword);
});
})
.then((hashedPassword) => {
return User.update({id}, {
$set: {
password: hashedPassword
}
});
});
};
/**
* Creates local users.
* @param {Array} users Users to create
* @return {Promise} Resolves with the users that were created
*/
UserSchema.statics.createLocalUsers = function(users) {
return Promise.all(users.map((user) => {
return User
.createLocalUser(user.email, user.password, user.displayName);
}));
};
/**
* Creates the local user with a given email, password, and name.
* @param {String} email email of the new user
* @param {String} password plaintext password of the new user
* @param {String} displayName name of the display user
* @param {Function} done callback
*/
UserSchema.statics.createLocalUser = function(email, password, displayName) {
if (!email) {
return Promise.reject('email is required');
}
if (!password) {
return Promise.reject('password is required');
}
if (!displayName) {
return Promise.reject('displayName is required');
}
return new Promise((resolve, reject) => {
bcrypt.hash(password, SALT_ROUNDS, (err, hashedPassword) => {
if (err) {
return reject(err);
}
let user = new User({
displayName: displayName,
password: hashedPassword,
roles: [],
profiles: [
{
id: email,
provider: 'local'
}
]
});
user.save((err) => {
if (err) {
return reject(err);
}
return resolve(user);
});
});
});
};
/**
* Disables a given user account.
* @param {String} id id of a user
* @param {Function} done callback after the operation is complete
*/
UserSchema.statics.disableUser = function(id) {
return User.update({
id: id
}, {
$set: {
disabled: true
}
});
};
/**
* Enables a given user account.
* @param {String} id id of a user
* @param {Function} done callback after the operation is complete
*/
UserSchema.statics.enableUser = function(id) {
return User.update({
id: id
}, {
$set: {
disabled: false
}
});
};
/**
* Adds a role to a user.
* @param {String} id id of a user
* @param {String} role role to add
* @param {Function} done callback after the operation is complete
*/
UserSchema.statics.addRoleToUser = function(id, role) {
return User.update({
id: id
}, {
$addToSet: {
roles: role
}
});
};
/**
* Removes a role from a user.
* @param {String} id id of a user
* @param {String} role role to remove
* @param {Function} done callback after the operation is complete
*/
UserSchema.statics.removeRoleFromUser = function(id, role) {
return User.update({
id: id
}, {
$pull: {
roles: role
}
});
};
/**
* Finds a user with the id.
* @param {String} id user id (uuid)
*/
UserSchema.statics.findById = function(id) {
return User.findOne({id});
};
/**
* Finds users in an array of idd.
* @param {Array} ids array of user identifiers (uuid)
*/
UserSchema.statics.findByIdArray = function(ids) {
return User.find({
'id': {$in: ids}
});
};
const User = mongoose.model('User', UserSchema);
module.exports = User;
module.exports.Schema = UserSchema;