Merge branch 'staging' of https://github.com/FreeCodeCamp/freecodecamp into greasan-translateDE

This commit is contained in:
greasan
2015-06-11 07:28:17 +02:00
7 changed files with 53 additions and 34 deletions

View File

@ -29,7 +29,6 @@
}, },
"username": { "username": {
"type": "string", "type": "string",
"sparse": true,
"lowercase": true, "lowercase": true,
"trim": true "trim": true
}, },
@ -175,6 +174,12 @@
}, },
"validations": [], "validations": [],
"relations": {}, "relations": {},
"acls": [], "acls": [{
"accessType": "EXECUTE",
"principalType": "ROLE",
"principalId": "$everyone",
"permission": "ALLOW",
"property": "doesExist"
}],
"methods": [] "methods": []
} }

View File

@ -29,7 +29,7 @@ gulp.task('serve', function(cb) {
ignore: paths.serverIgnore, ignore: paths.serverIgnore,
env: { env: {
'NODE_ENV': 'development', 'NODE_ENV': 'development',
'DEBUG': 'freecc:*' 'DEBUG': process.env.DEBUG || 'freecc:*'
} }
}) })
.on('start', function() { .on('start', function() {

View File

@ -59,7 +59,7 @@
"lodash": "^3.9.3", "lodash": "^3.9.3",
"loopback": "^2.18.0", "loopback": "^2.18.0",
"loopback-boot": "^2.8.0", "loopback-boot": "^2.8.0",
"loopback-component-passport": "^1.3.1", "loopback-component-passport": "git://github.com/FreeCodeCamp/loopback-component-passport.git#feature/emailOptional",
"loopback-connector-mongodb": "^1.10.0", "loopback-connector-mongodb": "^1.10.0",
"lusca": "~1.0.2", "lusca": "~1.0.2",
"method-override": "~2.3.0", "method-override": "~2.3.0",

View File

@ -427,10 +427,10 @@ profileValidation.directive('uniqueUsername', ['$http', function($http) {
var config = { params: { username: username } }; var config = { params: { username: username } };
$http $http
.get('/api/users/exists', config) .get('/api/users/exists', config)
.success(function (exists) { .success(function (result) {
if (username === scope.storedUsername) { if (username === scope.storedUsername) {
ngModel.$setValidity('unique', true); ngModel.$setValidity('unique', true);
} else if (exists) { } else if (result.exists) {
ngModel.$setValidity('unique', false); ngModel.$setValidity('unique', false);
} }
}); });
@ -458,8 +458,8 @@ profileValidation.directive('existingUsername',
var config = { params: { username: username } }; var config = { params: { username: username } };
$http $http
.get('/api/users/exists', config) .get('/api/users/exists', config)
.success(function(exists) { .success(function(result) {
ngModel.$setValidity('exists', exists); ngModel.$setValidity('exists', result.exists);
}); });
} }
}); });
@ -475,14 +475,14 @@ profileValidation.directive('uniqueEmail', ['$http', function($http) {
element.bind("keyup", function (event) { element.bind("keyup", function (event) {
ngModel.$setValidity('unique', true); ngModel.$setValidity('unique', true);
var email = element.val(); var email = element.val();
if (element.val()) { if (email) {
var config = { params: { email: email } }; var config = { params: { email: email } };
$http $http
.get('/api/users/exists', config) .get('/api/users/exists', config)
.success(function (exists) { .success(function(result) {
if (email === scope.storedEmail) { if (email === scope.storedEmail) {
ngModel.$setValidity('unique', true); ngModel.$setValidity('unique', true);
} else if (exists) { } else if (result.exists) {
ngModel.$setValidity('unique', false); ngModel.$setValidity('unique', false);
} }
}); });

View File

@ -2,6 +2,11 @@ var debug = require('debug')('freecc:extendUser');
module.exports = function(app) { module.exports = function(app) {
var User = app.models.User; var User = app.models.User;
// NOTE(berks): user email validation currently not needed but build in. This
// work around should let us sneak by
// see:
// https://github.com/strongloop/loopback/issues/1137#issuecomment-109200135
delete User.validations.email;
debug('setting up user hooks'); debug('setting up user hooks');
// send verification email to new camper // send verification email to new camper
User.afterRemote('create', function(ctx, user, next) { User.afterRemote('create', function(ctx, user, next) {
@ -59,17 +64,26 @@ module.exports = function(app) {
}); });
User.doesExist = function doesExist(username, email, cb) { User.doesExist = function doesExist(username, email, cb) {
if (!username && !email) {
return process.nextTick(function() {
cb(null, false);
});
}
debug('checking existence'); debug('checking existence');
var where = {}; var where = {};
if (username) { if (username) {
where.username = username; where.username = username.toLowerCase();
} else { } else {
where.email = email; where.email = email ? email.toLowerCase() : email;
} }
debug('where', where);
User.count( User.count(
{ where: where }, where,
function (err, count) { function (err, count) {
if (err) { return cb(err); } if (err) {
debug('err checking existance: ', err);
return cb(err);
}
if (count > 0) { if (count > 0) {
return cb(null, true); return cb(null, true);
} }
@ -99,7 +113,8 @@ module.exports = function(app) {
} }
], ],
http: { http: {
path: '/exists' path: '/exists',
verb: 'get'
} }
} }
); );

View File

@ -9,12 +9,6 @@ var _ = require('lodash'),
secrets = require('../../config/secrets'); secrets = require('../../config/secrets');
module.exports = function(app) { module.exports = function(app) {
// NOTE(berks): user email validation currently not needed but build in. This
// work around should let us sneak by
// see:
// https://github.com/strongloop/loopback/issues/1137#issuecomment-109200135
delete app.models.User.validations.email;
var router = app.loopback.Router(); var router = app.loopback.Router();
var User = app.models.User; var User = app.models.User;
var Story = app.models.Story; var Story = app.models.Story;
@ -27,7 +21,6 @@ module.exports = function(app) {
res.redirect(301, '/signout'); res.redirect(301, '/signout');
}); });
router.get('/signin', getSignin); router.get('/signin', getSignin);
// router.post('/signin', postSignin);
router.get('/signout', signout); router.get('/signout', signout);
router.get('/forgot', getForgot); router.get('/forgot', getForgot);
router.post('/forgot', postForgot); router.post('/forgot', postForgot);
@ -35,7 +28,6 @@ module.exports = function(app) {
router.post('/reset/:token', postReset); router.post('/reset/:token', postReset);
router.get('/email-signup', getEmailSignup); router.get('/email-signup', getEmailSignup);
router.get('/email-signin', getEmailSignin); router.get('/email-signin', getEmailSignin);
// router.post('/email-signup', postEmailSignup);
router.get('/account/api', getAccountAngular); router.get('/account/api', getAccountAngular);
router.post('/account/profile', postUpdateProfile); router.post('/account/profile', postUpdateProfile);
router.post('/account/password', postUpdatePassword); router.post('/account/password', postUpdatePassword);
@ -127,15 +119,14 @@ module.exports = function(app) {
*/ */
function returnUser (req, res, next) { function returnUser (req, res, next) {
User.find( User.findOne(
{where: { 'username': req.params.username.toLowerCase() }}, { where: { username: req.params.username.toLowerCase() } },
function(err, user) { function(err, user) {
if (err) { if (err) {
debug('Username err: ', err); debug('Username err: ', err);
return next(err); return next(err);
} }
if (user[0]) { if (user) {
user = user[0];
user.progressTimestamps = user.progressTimestamps =
user.progressTimestamps.sort(function(a, b) { user.progressTimestamps.sort(function(a, b) {
return a - b; return a - b;
@ -270,7 +261,9 @@ module.exports = function(app) {
return res.redirect('/account'); return res.redirect('/account');
} }
User.findOne({ email: req.body.email }, function(err, existingEmail) { User.findOne({
where: { email: req.body.email }
}, function(err, existingEmail) {
if (err) { if (err) {
return next(err); return next(err);
} }
@ -282,7 +275,7 @@ module.exports = function(app) {
return res.redirect('/account'); return res.redirect('/account');
} }
User.findOne( User.findOne(
{ 'profile.username': req.body.username }, { where: { username: req.body.username } },
function(err, existingUsername) { function(err, existingUsername) {
if (err) { if (err) {
return next(err); return next(err);
@ -290,7 +283,7 @@ module.exports = function(app) {
var user = req.user; var user = req.user;
if ( if (
existingUsername && existingUsername &&
existingUsername.profile.username !== user.username existingUsername.username !== user.username
) { ) {
req.flash('errors', { req.flash('errors', {
msg: 'An account with that username already exists.' msg: 'An account with that username already exists.'
@ -567,7 +560,7 @@ module.exports = function(app) {
}, },
function(token, done) { function(token, done) {
User.findOne({ User.findOne({
email: req.body.email.toLowerCase() where: { email: req.body.email.toLowerCase() }
}, function(err, user) { }, function(err, user) {
if (err) { return done(err); } if (err) { return done(err); }
if (!user) { if (!user) {

View File

@ -10,6 +10,7 @@ process.on('uncaughtException', function (err) {
}); });
var R = require('ramda'), var R = require('ramda'),
assign = require('lodash').assign,
loopback = require('loopback'), loopback = require('loopback'),
boot = require('loopback-boot'), boot = require('loopback-boot'),
accepts = require('accepts'), accepts = require('accepts'),
@ -202,6 +203,7 @@ passportConfigurator.setupModels({
}); });
var passportOptions = { var passportOptions = {
emailOptional: true,
profileToUser: function(provider, profile) { profileToUser: function(provider, profile) {
var emails = profile.emails; var emails = profile.emails;
// NOTE(berks): get email or set to null. // NOTE(berks): get email or set to null.
@ -210,7 +212,8 @@ var passportOptions = {
emails[0].value : emails[0].value :
null; null;
var username = provider + '.' + (profile.username || profile.id); var username = (profile.username || profile.id);
username = typeof username === 'string' ? username.toLowerCase() : username;
var password = generateKey('password'); var password = generateKey('password');
var userObj = { var userObj = {
username: username, username: username,
@ -227,7 +230,10 @@ var passportOptions = {
R.keys(passportProviders).map(function(strategy) { R.keys(passportProviders).map(function(strategy) {
var config = passportProviders[strategy]; var config = passportProviders[strategy];
config.session = config.session !== false; config.session = config.session !== false;
passportConfigurator.configureProvider(strategy, config, passportOptions); passportConfigurator.configureProvider(
strategy,
assign(config, passportOptions)
);
}); });
/** /**