Merge branch 'master' of github.com:coralproject/talk into passport

This commit is contained in:
Belen Curcio
2016-11-18 06:08:23 -03:00
12 changed files with 233 additions and 82 deletions
+7
View File
@@ -1,6 +1,13 @@
const mongoose = require('../mongoose');
const Schema = mongoose.Schema;
/**
* this Schema manages application settings that get used on front- and backend
* NOTE: when you set a setting here, it will not automatically be exposed to
* the front end. You must add it to the whitelist in the settings route
* in /routes/api/settings/index.js
* @type {Schema}
*/
const SettingSchema = new Schema({
id: {type: String, default: '1'},
moderation: {type: String, enum: ['pre', 'post'], default: 'pre'},
+67 -17
View File
@@ -1,6 +1,7 @@
const mongoose = require('../mongoose');
const uuid = require('uuid');
const bcrypt = require('bcrypt');
const jwt = require('jsonwebtoken');
// SALT_ROUNDS is the number of rounds that the bcrypt algorithm will run
// through during the salting process.
@@ -12,6 +13,13 @@ const USER_ROLES = [
'moderator'
];
if (!process.env.TALK_SESSION_SECRET) {
throw new Error('\n////////////////////////////////////////////////////////////\n' +
'/// TALK_SESSION_SECRET must be defined to encode ///\n' +
'/// JSON Web Tokens and other auth functionality ///\n' +
'////////////////////////////////////////////////////////////');
}
// UserSchema is the mongoose schema defined as the representation of a User in
// MongoDB.
const UserSchema = new mongoose.Schema({
@@ -130,10 +138,14 @@ const UserService = module.exports = {};
* @param {Function} done [description]
*/
UserService.findLocalUser = (email, password) => {
if (!email || typeof email !== 'string') {
return Promise.reject('email is required for findLocalUser');
}
return UserModel.findOne({
profiles: {
$elemMatch: {
id: email,
id: email.toLowerCase(),
provider: 'local'
}
}
@@ -237,6 +249,7 @@ UserService.changePassword = (id, password) => {
})
.then((hashedPassword) => {
return UserModel.update({id}, {
$inc: {__v: 1},
$set: {
password: hashedPassword
}
@@ -268,6 +281,8 @@ UserService.createLocalUser = (email, password, displayName) => {
return Promise.reject('email is required');
}
email = email.toLowerCase();
if (!password) {
return Promise.reject('password is required');
}
@@ -393,6 +408,57 @@ UserService.findByIdArray = (ids) => {
});
};
/**
* Creates a JWT from a user email. Only works for local accounts.
* @param {String} email of the local user
*/
UserService.createPasswordResetToken = function (email) {
if (!email || typeof email !== 'string') {
return Promise.reject('email is required when creating a JWT for resetting passord');
}
email = email.toLowerCase();
return UserModel.findOne({profiles: {$elemMatch: {id: email}}})
.then(user => {
if (user === null) {
// since we don't want to reveal that the email does/doesn't exist
// just go ahead and resolve the Promise with null and check in the endpoint
return Promise.resolve(null);
}
const payload = {email, jti: uuid.v4(), userId: user.id, version: user.__v};
const token = jwt.sign(payload, process.env.TALK_SESSION_SECRET, {expiresIn: '1d'});
return token;
});
};
/**
* verifies a jwt and returns the associated user
* @param {String} token the JSON Web Token to verify
*/
UserService.verifyPasswordResetToken = token => {
return new Promise((resolve, reject) => {
jwt.verify(token, process.env.TALK_SESSION_SECRET, (error, decoded) => {
if (error) {
return reject(error);
}
resolve(decoded);
});
})
.then(decoded => {
/**
* TODO: check the jti from this decoded token in redis
* and make an entry if it does not exist.
* reject if entry already exists.
*/
return UserService.findById(decoded.userId);
});
};
/**
* Finds a user using a value which gets compared using a prefix match against
* the user's email address and/or their display name.
@@ -427,22 +493,6 @@ UserService.search = (value) => {
});
};
/**
* Finds users by email and returns the count. The result should be 1 or 0 (bool) indicating email availability
* @param {String} email to search by
* @return {Promise}
*/
UserService.availabilityCheck = (email) => {
return UserModel.count({
profiles: {
$elemMatch: {
id: email,
provider: 'local'
}
}
});
};
/**
* Returns a count of the current users.
* @return {Promise}