mirror of
https://github.com/freeCodeCamp/freeCodeCamp.git
synced 2026-01-08 21:02:25 -05:00
Merge branch 'staging' of github.com:FreeCodeCamp/freecodecamp into staging
This commit is contained in:
@@ -28,7 +28,7 @@ Contributing
|
||||
We welcome pull requests from Free Code Camp campers (our students) and seasoned JavaScript developers alike! Follow these steps to contribute:
|
||||
|
||||
1. Check our [public Waffle Board](https://waffle.io/freecodecamp/freecodecamp).
|
||||
2. Pick an issue that nobody has claimed and start working on it. If your issue isn't on the board, open an issue. If you think you can fix it yourself, start working on it. Feel free to ask for help in our [Gitter](https://gitter.im/FreeCodeCamp/FreeCodeCamp)
|
||||
2. Pick an issue that nobody has claimed and start working on it. If your issue isn't on the board, open an issue. If you think you can fix it yourself, start working on it. Feel free to ask for help in our [Gitter](https://gitter.im/FreeCodeCamp/FreeCodeCamp).
|
||||
3. Fork the project ([Need help with forking a project?](https://help.github.com/articles/fork-a-repo/)). You'll do all of your work on your forked copy.
|
||||
4. Create a branch specific to the issue or feature you are working on. Push your work to that branch. ([Need help with branching?](https://github.com/Kunena/Kunena-Forum/wiki/Create-a-new-branch-with-git-and-manage-branches))
|
||||
5. Name the branch something like `user-xxx` where user is your username and xxx is the issue number you are addressing.
|
||||
|
||||
@@ -202,7 +202,7 @@ module.exports = function(User) {
|
||||
);
|
||||
|
||||
User.giveBrowniePoints =
|
||||
function giveBrowniePoints(receiver, giver, data = {}, cb) {
|
||||
function giveBrowniePoints(receiver, giver, data = {}, dev = false, cb) {
|
||||
const findUser = observeMethod(User, 'findOne');
|
||||
if (!receiver) {
|
||||
return nextTick(() => {
|
||||
@@ -262,9 +262,15 @@ module.exports = function(User) {
|
||||
})
|
||||
.subscribe(
|
||||
(user) => {
|
||||
cb(null, getAboutProfile(user));
|
||||
return cb(
|
||||
null,
|
||||
getAboutProfile(user),
|
||||
dev ?
|
||||
{ giver, receiver, data } :
|
||||
null
|
||||
);
|
||||
},
|
||||
cb,
|
||||
(e) => cb(e, null, dev ? { giver, receiver, data } : null),
|
||||
() => {
|
||||
debug('brownie points assigned completed');
|
||||
}
|
||||
@@ -289,17 +295,25 @@ module.exports = function(User) {
|
||||
{
|
||||
arg: 'data',
|
||||
type: 'object'
|
||||
},
|
||||
{
|
||||
arg: 'debug',
|
||||
type: 'boolean'
|
||||
}
|
||||
],
|
||||
returns: [
|
||||
{
|
||||
arg: 'about',
|
||||
type: 'object'
|
||||
},
|
||||
{
|
||||
arg: 'debug',
|
||||
type: 'object'
|
||||
}
|
||||
],
|
||||
http: {
|
||||
path: '/give-brownie-points',
|
||||
verb: 'get'
|
||||
verb: 'POST'
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
@@ -1,421 +0,0 @@
|
||||
var _ = require('lodash'),
|
||||
passport = require('passport'),
|
||||
LocalStrategy = require('passport-local').Strategy,
|
||||
FacebookStrategy = require('passport-facebook').Strategy,
|
||||
TwitterStrategy = require('passport-twitter').Strategy,
|
||||
GitHubStrategy = require('passport-github').Strategy,
|
||||
GoogleStrategy = require('passport-google-oauth').OAuth2Strategy,
|
||||
LinkedInStrategy = require('passport-linkedin-oauth2').Strategy,
|
||||
// OAuthStrategy = require('passport-oauth').OAuthStrategy,
|
||||
// OAuth2Strategy = require('passport-oauth').OAuth2Strategy,
|
||||
User = require('../common/models/User'),
|
||||
nodemailer = require('nodemailer'),
|
||||
secrets = require('./secrets');
|
||||
|
||||
|
||||
passport.serializeUser(function(user, done) {
|
||||
done(null, user.id);
|
||||
});
|
||||
|
||||
passport.deserializeUser(function(id, done) {
|
||||
User.findById(id, function(err, user) {
|
||||
done(err, user);
|
||||
});
|
||||
});
|
||||
|
||||
// Sign in using Email and Password.
|
||||
|
||||
passport.use(new LocalStrategy({ usernameField: 'email' }, function(email, password, done) {
|
||||
User.findOne({ email: email }, function(err, user) {
|
||||
if (err) { return done(err); }
|
||||
if (!user) return done(null, false, { message: 'Email ' + email + ' not found'});
|
||||
user.comparePassword(password, function(err, isMatch) {
|
||||
if (isMatch) {
|
||||
return done(null, user);
|
||||
} else {
|
||||
return done(null, false, { message: 'Invalid email or password.' });
|
||||
}
|
||||
});
|
||||
});
|
||||
}));
|
||||
|
||||
/**
|
||||
* OAuth Strategy Overview
|
||||
*
|
||||
* - User is already logged in.
|
||||
* - Check if there is an existing account with a <provider> id.
|
||||
* - If there is, return an error message. (Account merging not supported)
|
||||
* - Else link new OAuth account with currently logged-in user.
|
||||
* - User is not logged in.
|
||||
* - Check if it's a returning user.
|
||||
* - If returning user, sign in and we are done.
|
||||
* - Else check if there is an existing account with user's email.
|
||||
* - If there is, return an error message.
|
||||
* - Else create a new account.
|
||||
*/
|
||||
|
||||
// Sign in with Facebook.
|
||||
|
||||
passport.use(new FacebookStrategy(secrets.facebook, function(req, accessToken, refreshToken, profile, done) {
|
||||
if (req.user) {
|
||||
User.findOne({ facebook: profile.id }, function(err, existingUser) {
|
||||
if (existingUser) {
|
||||
req.flash('errors', { msg: 'There is already a Facebook account that belongs to you. Sign in with that account or delete it, then link it with your current account.' });
|
||||
done();
|
||||
} else {
|
||||
User.findById(req.user.id, function(err, user) {
|
||||
if (err) { return done(err); }
|
||||
user.facebook = profile.id;
|
||||
user.tokens.push({ kind: 'facebook', accessToken: accessToken });
|
||||
user.name = user.name || profile.displayName;
|
||||
user.gender = user.gender || profile._json.gender;
|
||||
user.picture = user.picture || 'https://s3.amazonaws.com/freecodecamp/camper-image-placeholder.png';
|
||||
user.save(function(err) {
|
||||
if (err) { return done(err); }
|
||||
req.flash('info', { msg: 'Facebook account has been linked.' });
|
||||
done(null, user);
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
} else {
|
||||
User.findOne({ facebook: profile.id }, function(err, existingUser) {
|
||||
if (existingUser) return done(null, existingUser);
|
||||
User.findOne({ email: profile._json.email }, function(err, existingEmailUser) {
|
||||
if (err) { return done(err); }
|
||||
if (existingEmailUser) {
|
||||
req.flash('errors', { msg: 'There is already an account using this email address. Sign in to that account and link it with Facebook manually from Account Settings.' });
|
||||
done();
|
||||
} else {
|
||||
var user = new User();
|
||||
user.email = profile._json.email;
|
||||
user.facebook = profile.id;
|
||||
user.tokens.push({ kind: 'facebook', accessToken: accessToken });
|
||||
user.name = profile.displayName;
|
||||
user.gender = profile._json.gender;
|
||||
user.picture = 'https://graph.facebook.com/' + profile.id + '/picture?type=large';
|
||||
user.location = (profile._json.location) ? profile._json.location.name : '';
|
||||
user.save(function(err) {
|
||||
done(err, user);
|
||||
var transporter = nodemailer.createTransport({
|
||||
service: 'Mandrill',
|
||||
auth: {
|
||||
user: secrets.mandrill.user,
|
||||
pass: secrets.mandrill.password
|
||||
}
|
||||
});
|
||||
var mailOptions = {
|
||||
to: user.email,
|
||||
from: 'Team@freecodecamp.com',
|
||||
subject: 'Welcome to Free Code Camp!',
|
||||
text: [
|
||||
'Greetings from San Francisco!\n\n',
|
||||
'Thank you for joining our community.\n',
|
||||
'Feel free to email us at this address if you have any questions about Free Code Camp.\n',
|
||||
"And if you have a moment, check out our blog: blog.freecodecamp.com.\n",
|
||||
'Good luck with the challenges!\n\n',
|
||||
'- the Free Code Camp Volunteer Team'
|
||||
].join('')
|
||||
};
|
||||
transporter.sendMail(mailOptions, function(err) {
|
||||
if (err) { return err; }
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}));
|
||||
|
||||
// Sign in with GitHub.
|
||||
|
||||
passport.use(new GitHubStrategy(secrets.github, function(req, accessToken, refreshToken, profile, done) {
|
||||
if (req.user) {
|
||||
User.findOne({ github: profile.id }, function(err, existingUser) {
|
||||
if (err) { return done(err); }
|
||||
if (existingUser) {
|
||||
req.flash('errors', { msg: 'There is already a GitHub account that belongs to you. Sign in with that account or delete it, then link it with your current account.' });
|
||||
done();
|
||||
} else {
|
||||
User.findById(req.user.id, function(err, user) {
|
||||
user.github = profile.id;
|
||||
user.tokens.push({ kind: 'github', accessToken: accessToken });
|
||||
user.name = user.name || profile.displayName;
|
||||
user.picture = user.picture || profile._json.avatar_url;
|
||||
user.location = user.location || profile._json.location;
|
||||
user.website = user.website || profile._json.blog;
|
||||
user.save(function(err) {
|
||||
if (err) { return done(err); }
|
||||
req.flash('info', { msg: 'GitHub account has been linked.' });
|
||||
done(null, user);
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
} else {
|
||||
User.findOne({ github: profile.id }, function(err, existingUser) {
|
||||
if (err) { return done(err); }
|
||||
if (existingUser) return done(null, existingUser);
|
||||
User.findOne({ email: profile._json.email }, function(err, existingEmailUser) {
|
||||
if (err) { return done(err); }
|
||||
if (existingEmailUser) {
|
||||
req.flash('errors', { msg: 'There is already an account using this email address. Sign in to that account and link it with GitHub manually from Account Settings.' });
|
||||
done(null);
|
||||
} else {
|
||||
var user = new User();
|
||||
user.email = profile._json.email;
|
||||
user.github = profile.id;
|
||||
user.tokens.push({ kind: 'github', accessToken: accessToken });
|
||||
user.name = profile.displayName;
|
||||
user.picture = profile._json.avatar_url;
|
||||
user.location = profile._json.location;
|
||||
user.website = profile._json.blog;
|
||||
user.save(function(err) {
|
||||
if (err) { return done(err); }
|
||||
var transporter = nodemailer.createTransport({
|
||||
service: 'Mandrill',
|
||||
auth: {
|
||||
user: secrets.mandrill.user,
|
||||
pass: secrets.mandrill.password
|
||||
}
|
||||
});
|
||||
var mailOptions = {
|
||||
to: user.email,
|
||||
from: 'Team@freecodecamp.com',
|
||||
subject: 'Welcome to Free Code Camp!',
|
||||
text: [
|
||||
'Greetings from San Francisco!\n\n',
|
||||
'Thank you for joining our community.\n',
|
||||
'Feel free to email us at this address if you have any questions about Free Code Camp.\n',
|
||||
"And if you have a moment, check out our blog: blog.freecodecamp.com.\n",
|
||||
'Good luck with the challenges!\n\n',
|
||||
'- the Free Code Camp Volunteer Team'
|
||||
].join('')
|
||||
};
|
||||
transporter.sendMail(mailOptions, function(err) {
|
||||
if (err) { return done(err); }
|
||||
done(null, user);
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}));
|
||||
|
||||
// Sign in with Twitter.
|
||||
|
||||
passport.use(new TwitterStrategy(secrets.twitter, function(req, accessToken, tokenSecret, profile, done) {
|
||||
if (req.user) {
|
||||
User.findOne({ twitter: profile.id }, function(err, existingUser) {
|
||||
if (err) { return done(err); }
|
||||
if (existingUser) {
|
||||
req.flash('errors', { msg: 'There is already a Twitter account that belongs to you. Sign in with that account or delete it, then link it with your current account.' });
|
||||
done();
|
||||
} else {
|
||||
User.findById(req.user.id, function(err, user) {
|
||||
user.twitter = profile.id;
|
||||
user.tokens.push({ kind: 'twitter', accessToken: accessToken, tokenSecret: tokenSecret });
|
||||
user.username = user.username || profile.username.toLowerCase();
|
||||
user.name = user.name || profile.displayName;
|
||||
user.location = user.location || profile._json.location;
|
||||
user.picture = user.picture || profile._json.profile_image_url_https.replace('_normal', '');
|
||||
user.twitterHandle = user.twitterHandle || profile.username.toLowerCase();
|
||||
user.save(function(err) {
|
||||
if (err) { return done(err); }
|
||||
req.flash('info', { msg: 'Twitter account has been linked.' });
|
||||
done(null, user);
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
} else {
|
||||
User.findOne({ twitter: profile.id }, function(err, existingUser) {
|
||||
if (err) { return done(err); }
|
||||
if (existingUser) return done(null, existingUser);
|
||||
var user = new User();
|
||||
user.username = profile.username.toLowerCase();
|
||||
user.twitter = profile.id;
|
||||
user.tokens.push({ kind: 'twitter', accessToken: accessToken, tokenSecret: tokenSecret });
|
||||
user.name = profile.displayName;
|
||||
user.location = profile._json.location;
|
||||
user.picture = profile._json.profile_image_url_https.replace('_normal', '');
|
||||
user.twitterHandle = user.twitterHandle || profile.username.toLowerCase();
|
||||
user.save(function(err) {
|
||||
if (err) { return done(err); }
|
||||
done(null, user);
|
||||
});
|
||||
});
|
||||
}
|
||||
}));
|
||||
|
||||
// Sign in with Google.
|
||||
|
||||
passport.use(new GoogleStrategy(secrets.google, function(req, accessToken, refreshToken, profile, done) {
|
||||
if (req.user) {
|
||||
User.findOne({ google: profile.id }, function(err, existingUser) {
|
||||
if (err) { return done(err); }
|
||||
if (existingUser) {
|
||||
req.flash('errors', { msg: 'There is already a Google account that belongs to you. Sign in with that account or delete it, then link it with your current account.' });
|
||||
done();
|
||||
} else {
|
||||
User.findById(req.user.id, function(err, user) {
|
||||
if (err) { return done(err); }
|
||||
user.google = profile.id;
|
||||
user.tokens.push({ kind: 'google', accessToken: accessToken });
|
||||
user.name = user.name || profile.displayName;
|
||||
user.gender = user.gender || profile._json.gender;
|
||||
user.picture = user.picture || profile._json.picture;
|
||||
user.save(function(err) {
|
||||
if (err) { return done(err); }
|
||||
req.flash('info', { msg: 'Google account has been linked.' });
|
||||
done(null, user);
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
} else {
|
||||
User.findOne({ google: profile.id }, function(err, existingUser) {
|
||||
if (err) { return done(err); }
|
||||
if (existingUser) return done(null, existingUser);
|
||||
User.findOne({ email: profile._json.email }, function(err, existingEmailUser) {
|
||||
if (err) { return done(err); }
|
||||
if (existingEmailUser) {
|
||||
req.flash('errors', { msg: 'There is already an account using this email address. Sign in to that account and link it with Google manually from Account Settings.' });
|
||||
done();
|
||||
} else {
|
||||
var user = new User();
|
||||
user.email = profile._json.email;
|
||||
user.google = profile.id;
|
||||
user.tokens.push({ kind: 'google', accessToken: accessToken });
|
||||
user.name = profile.displayName;
|
||||
user.gender = profile._json.gender;
|
||||
user.picture = profile._json.picture;
|
||||
user.save(function(err) {
|
||||
if (err) { return done(err); }
|
||||
var transporter = nodemailer.createTransport({
|
||||
service: 'Mandrill',
|
||||
auth: {
|
||||
user: secrets.mandrill.user,
|
||||
pass: secrets.mandrill.password
|
||||
}
|
||||
});
|
||||
var mailOptions = {
|
||||
to: user.email,
|
||||
from: 'Team@freecodecamp.com',
|
||||
subject: 'Welcome to Free Code Camp!',
|
||||
text: [
|
||||
'Greetings from San Francisco!\n\n',
|
||||
'Thank you for joining our community.\n',
|
||||
'Feel free to email us at this address if you have any questions about Free Code Camp.\n',
|
||||
"And if you have a moment, check out our blog: blog.freecodecamp.com.\n",
|
||||
'Good luck with the challenges!\n\n',
|
||||
'- the Free Code Camp Volunteer Team'
|
||||
].join('')
|
||||
};
|
||||
transporter.sendMail(mailOptions, function(err) {
|
||||
if (err) { return err; }
|
||||
done(null, user);
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}));
|
||||
|
||||
// Sign in with LinkedIn.
|
||||
|
||||
passport.use(new LinkedInStrategy(secrets.linkedin, function(req, accessToken, refreshToken, profile, done) {
|
||||
if (req.user) {
|
||||
User.findOne({ linkedin: profile.id }, function(err, existingUser) {
|
||||
if (err) { return done(err); }
|
||||
if (existingUser) {
|
||||
req.flash('errors', { msg: 'There is already a LinkedIn account that belongs to you. Sign in with that account or delete it, then link it with your current account.' });
|
||||
done();
|
||||
} else {
|
||||
User.findById(req.user.id, function(err, user) {
|
||||
if (err) { return done(err); }
|
||||
user.linkedin = profile.id;
|
||||
user.tokens.push({ kind: 'linkedin', accessToken: accessToken });
|
||||
user.name = user.name || profile.displayName;
|
||||
user.location = user.location || profile._json.location.name;
|
||||
user.picture = user.picture || profile._json.pictureUrl;
|
||||
user.website = user.website || profile._json.publicProfileUrl;
|
||||
user.save(function(err) {
|
||||
if (err) { return done(err); }
|
||||
req.flash('info', { msg: 'LinkedIn account has been linked.' });
|
||||
done(null, user);
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
} else {
|
||||
User.findOne({ linkedin: profile.id }, function(err, existingUser) {
|
||||
if (existingUser) return done(null, existingUser);
|
||||
User.findOne({ email: profile._json.emailAddress }, function(err, existingEmailUser) {
|
||||
if (err) { return done(err); }
|
||||
if (existingEmailUser) {
|
||||
req.flash('errors', { msg: 'There is already an account using this email address. Sign in to that account and link it with LinkedIn manually from Account Settings.' });
|
||||
done();
|
||||
} else {
|
||||
var user = new User();
|
||||
user.linkedin = profile.id;
|
||||
user.tokens.push({ kind: 'linkedin', accessToken: accessToken });
|
||||
user.email = profile._json.emailAddress;
|
||||
user.name = profile.displayName;
|
||||
user.location = profile._json.location.name;
|
||||
user.picture = profile._json.pictureUrl;
|
||||
user.website = profile._json.publicProfileUrl;
|
||||
user.save(function(err) {
|
||||
if (err) { return done(err); }
|
||||
var transporter = nodemailer.createTransport({
|
||||
service: 'Mandrill',
|
||||
auth: {
|
||||
user: secrets.mandrill.user,
|
||||
pass: secrets.mandrill.password
|
||||
}
|
||||
});
|
||||
var mailOptions = {
|
||||
to: user.email,
|
||||
from: 'Team@freecodecamp.com',
|
||||
subject: 'Welcome to Free Code Camp!',
|
||||
text: [
|
||||
'Greetings from San Francisco!\n\n',
|
||||
'Thank you for joining our community.\n',
|
||||
'Feel free to email us at this address if you have any questions about Free Code Camp.\n',
|
||||
"And if you have a moment, check out our blog: blog.freecodecamp.com.\n",
|
||||
'Good luck with the challenges!\n\n',
|
||||
'- the Free Code Camp Volunteer Team'
|
||||
].join('')
|
||||
};
|
||||
transporter.sendMail(mailOptions, function(err) {
|
||||
if (err) { return err; }
|
||||
done(null, user);
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}));
|
||||
|
||||
// Login Required middleware.
|
||||
|
||||
exports.isAuthenticated = function(req, res, next) {
|
||||
if (req.isAuthenticated()) { return next(); }
|
||||
res.redirect('/login');
|
||||
};
|
||||
|
||||
// Authorization Required middleware.
|
||||
|
||||
exports.isAuthorized = function(req, res, next) {
|
||||
var provider = req.path.split('/').slice(-1)[0];
|
||||
|
||||
if (_.find(req.user.tokens, { kind: provider })) {
|
||||
next();
|
||||
} else {
|
||||
res.redirect('/auth/' + provider);
|
||||
}
|
||||
};
|
||||
@@ -110,6 +110,7 @@ function bonfireExecute() {
|
||||
runTests('Error', null);
|
||||
} else {
|
||||
codeOutput.setValue(message.output);
|
||||
codeOutput.setValue(codeOutput.getValue().replace(/\\\"/gi,''));
|
||||
message.input = removeLogs(message.input);
|
||||
runTests(null, message);
|
||||
}
|
||||
|
||||
@@ -368,14 +368,14 @@
|
||||
"description": [
|
||||
"",
|
||||
"in JavaScript we can can work with decimal numbers",
|
||||
"Let's create a variable <code>myfloat</code> and give it a decimal value."
|
||||
"Let's create a variable <code>myDecimal</code> and give it a decimal value."
|
||||
],
|
||||
"tests": [
|
||||
"assert((function(){if(typeof(myDecimal) != 'undefined' && typeof(myDecimal) == 'number' && editor.getValue().match(/\\./g).length >=2){return(true);}else{return(false);}})(), 'myFloat should be a decimal point number');"
|
||||
"assert((function(){if(typeof(myDecimal) != 'undefined' && typeof(myDecimal) == 'number' && editor.getValue().match(/\\./g).length >=2){return(true);}else{return(false);}})(), 'myDecimal should be a decimal point number');"
|
||||
],
|
||||
"challengeSeed": [
|
||||
"//var ourDecimal = 5.7",
|
||||
"//Create a number with a decimal point here called myFloat",
|
||||
"//Create a number with a decimal point here called myDecimal",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
@@ -448,7 +448,7 @@
|
||||
"Let's now go create a nested array called <code>myArray</code>"
|
||||
],
|
||||
"tests":[
|
||||
"assert((function(){if(typeof(myArray) !== 'undefined' && typeof(myArray) === 'object' && typeof(myArray[0]) !== 'undefined' && typeof(myArray[0]) === 'object' && editor.getValue().match(/[[]]/g).length >= 1){return(true);}else{return(false);}})(), 'myArray should contain at least one array');"
|
||||
"assert((function(){if(typeof(myArray) !== 'undefined' && typeof(myArray) === 'object' && typeof(myArray[0]) !== 'undefined' && typeof(myArray[0]) === 'object' && editor.getValue().match(/\\[\\[/g).length >= 1 && editor.getValue().match(/\\]\\]/g).length >= 1){return(true);}else{return(false);}})(), 'myArray should contain at least one array');"
|
||||
],
|
||||
"challengeSeed":[
|
||||
"var myArray = [];",
|
||||
|
||||
@@ -1528,7 +1528,8 @@
|
||||
" <li>cat nip</li>",
|
||||
" <li>laser pointers</li>",
|
||||
" <li>lasagna</li>",
|
||||
"</ul>"
|
||||
"</ul>",
|
||||
"<p>Top 3 things cats hate:</p>"
|
||||
],
|
||||
"challengeType": 0,
|
||||
"nameCn": "",
|
||||
@@ -1561,7 +1562,7 @@
|
||||
"Create an <code>input</code> element of type \"text\" below your lists."
|
||||
],
|
||||
"tests": [
|
||||
"assert($('input').length > 0, 'Your app should have a text field input element.')"
|
||||
"assert($('input[type=text]').length > 0, 'Your app should have a text field input element.')"
|
||||
],
|
||||
"challengeSeed": [
|
||||
"<link href='http://fonts.googleapis.com/css?family=Lobster' rel='stylesheet' type='text/css'>",
|
||||
@@ -2150,7 +2151,7 @@
|
||||
"Set the first of your radio buttons and the first of your checkboxes to both be checked by default."
|
||||
],
|
||||
"tests": [
|
||||
"assert($('input[type=\"radio\"]').prop('checked'), 'Your first radio button on your form should be checked by default.');",
|
||||
"assert($('input[type=\"radio\"]').prop('checked'), 'Your first radio button on your form should be checked by default.')",
|
||||
"assert($('input[type=\"checkbox\"]').prop('checked'), 'Your first checkbox on your form should be checked by default.')"
|
||||
],
|
||||
"challengeSeed": [
|
||||
@@ -2738,7 +2739,7 @@
|
||||
"An element's <code>margin</code> controls the amount of space between an element's <code>border</code> and surrounding elements.",
|
||||
"If you set an element's <code>margin</code> to a negative value, the element will grow larger.",
|
||||
"Try to set the <code>margin</code> to a negative value like the one for the red box.",
|
||||
"Change the <code>margin</code> of the green box to a negative value, so it fills the entire horizontal width of the yellow box around it."
|
||||
"Change the <code>margin</code> of the green box to -15 pixels, so it fills the entire horizontal width of the yellow box around it."
|
||||
],
|
||||
"tests": [
|
||||
"assert($('.green-box').css('margin-top') === '-15px', 'Your <code>green-box</code> class should give elements -15px of margin.')"
|
||||
|
||||
@@ -112,7 +112,7 @@
|
||||
],
|
||||
"tests": [
|
||||
"assert($('.well').hasClass('animated') && $('.well').hasClass('shake'), 'Use the jQuery <code>addClass()</code> function to give the classes \"animated\" and \"shake\" to all your elements with the class \"well\".')",
|
||||
"assert(!editor.match(/class.*animated/g), 'Only use jQuery to add these classes to the element.')"
|
||||
"assert(!editor.match(/class\\.\\*animated/g), 'Only use jQuery to add these classes to the element.')"
|
||||
],
|
||||
"challengeSeed": [
|
||||
"fccss",
|
||||
@@ -630,8 +630,8 @@
|
||||
],
|
||||
"tests": [
|
||||
"assert($('#left-well').css('background-color') === 'rgb(255, 0, 0)', 'Your \"target1\" element should have red text.')",
|
||||
"assert(!editor.match(/\\.parent\\(\\)\\.css/g), 'You should use the <code>parent()</code> function to modify this element.')",
|
||||
"assert(!editor.match(/<div class=\\'well\\' id=\\'left-well\\'>/g), 'Only use jQuery to add these classes to the element.')"
|
||||
"assert(editor.match(/\\.parent\\(\\)\\.css/g), 'You should use the <code>parent()</code> function to modify this element.')",
|
||||
"assert(editor.match(/<div class=\\'well\\' id=\\'left-well\\'>/g), 'Only use jQuery to add these classes to the element.')"
|
||||
],
|
||||
"challengeSeed": [
|
||||
"fccss",
|
||||
|
||||
@@ -9,6 +9,7 @@ var Rx = require('rx'),
|
||||
saveUser = require('../utils/rx').saveUser,
|
||||
saveInstance = require('../utils/rx').saveInstance,
|
||||
MongoClient = mongodb.MongoClient,
|
||||
validator = require('validator'),
|
||||
secrets = require('../../config/secrets');
|
||||
|
||||
var foundationDate = 1413298800000;
|
||||
@@ -262,9 +263,8 @@ module.exports = function(app) {
|
||||
return next(new Error('Must be logged in'));
|
||||
}
|
||||
var url = req.body.data.url;
|
||||
var cleanURL = cleanData(url);
|
||||
|
||||
if (cleanURL !== url) {
|
||||
if (!validator.isURL(url)) {
|
||||
req.flash('errors', {
|
||||
msg: "The URL you submitted doesn't appear valid"
|
||||
});
|
||||
|
||||
@@ -426,7 +426,7 @@ module.exports = function(app) {
|
||||
{
|
||||
where: {
|
||||
resetPasswordToken: req.params.token,
|
||||
resetPasswordExpires: Date.now()
|
||||
resetPasswordExpires: { gte: Date.now() }
|
||||
}
|
||||
},
|
||||
function(err, user) {
|
||||
@@ -463,7 +463,7 @@ module.exports = function(app) {
|
||||
{
|
||||
where: {
|
||||
resetPasswordToken: req.params.token,
|
||||
resetPasswordExpires: Date.now()
|
||||
resetPasswordExpires: { gte: Date.now() }
|
||||
}
|
||||
},
|
||||
function(err, user) {
|
||||
|
||||
@@ -186,6 +186,12 @@ passportConfigurator.init();
|
||||
app.use(rxMiddleware());
|
||||
|
||||
app.use(function(req, res, next) {
|
||||
// add beta warning
|
||||
req.flash('info', {
|
||||
msg: `warning: you are on experimental branch of Free Code Camp:
|
||||
Your progress here may or may not be saved to the main site`
|
||||
});
|
||||
|
||||
// Make user object available in templates.
|
||||
res.locals.user = req.user;
|
||||
next();
|
||||
|
||||
@@ -54,7 +54,7 @@
|
||||
"<div class='hidden-xs row media-stories'>" +
|
||||
"<div class='media'>" +
|
||||
"<div class='media-left'>" +
|
||||
"<a href='/'" + data[i].author.username + "'>" +
|
||||
"<a href='/" + data[i].author.username + "'>" +
|
||||
"<img class='img-news' src='" + data[i].author.picture + "'/>" +
|
||||
"</a>" +
|
||||
"</div>" +
|
||||
|
||||
@@ -91,7 +91,7 @@ script.
|
||||
"<div class='hidden-xs row media-stories'>" +
|
||||
"<div class='media'>" +
|
||||
"<div class='media-left'>" +
|
||||
"<a href='/'" + data[i].author.username + "'>" +
|
||||
"<a href='/" + data[i].author.username + "'>" +
|
||||
"<img class='img-news' src='" + data[i].author.picture + "'/>" +
|
||||
"</a>" +
|
||||
"</div>" +
|
||||
|
||||
Reference in New Issue
Block a user