Change migration middleware to not rely on boolean flag in User model

This commit is contained in:
terakilobyte
2015-05-25 19:55:18 -04:00
parent 0debdc5fd6
commit 5f169001f6
4 changed files with 99 additions and 100 deletions

163
app.js
View File

@ -33,9 +33,9 @@ var express = require('express'),
forceDomain = require('forcedomain'), forceDomain = require('forcedomain'),
lessMiddleware = require('less-middleware'), lessMiddleware = require('less-middleware'),
/** /**
* Controllers (route handlers). * Controllers (route handlers).
*/ */
homeController = require('./controllers/home'), homeController = require('./controllers/home'),
resourcesController = require('./controllers/resources'), resourcesController = require('./controllers/resources'),
userController = require('./controllers/user'), userController = require('./controllers/user'),
@ -44,9 +44,9 @@ var express = require('express'),
challengeMapController = require('./controllers/challengeMap'), challengeMapController = require('./controllers/challengeMap'),
challengeController = require('./controllers/challenge'), challengeController = require('./controllers/challenge'),
/** /**
* Stories * Stories
*/ */
storyController = require('./controllers/story'), storyController = require('./controllers/story'),
/** /**
@ -65,9 +65,9 @@ var app = express();
*/ */
mongoose.connect(secrets.db); mongoose.connect(secrets.db);
mongoose.connection.on('error', function () { mongoose.connection.on('error', function () {
console.error( console.error(
'MongoDB Connection Error. Please make sure that MongoDB is running.' 'MongoDB Connection Error. Please make sure that MongoDB is running.'
); );
}); });
/** /**
@ -91,11 +91,11 @@ app.use(logger('dev'));
app.use(bodyParser.json()); app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: true})); app.use(bodyParser.urlencoded({extended: true}));
app.use(expressValidator({ app.use(expressValidator({
customValidators: { customValidators: {
matchRegex: function (param, regex) { matchRegex: function (param, regex) {
return regex.test(param); return regex.test(param);
}
} }
}
})); }));
app.use(methodOverride()); app.use(methodOverride());
app.use(cookieParser()); app.use(cookieParser());
@ -117,11 +117,11 @@ app.use(helmet.xssFilter());
app.use(helmet.noSniff()); app.use(helmet.noSniff());
app.use(helmet.frameguard()); app.use(helmet.frameguard());
app.use(function(req, res, next) { app.use(function(req, res, next) {
res.header('Access-Control-Allow-Origin', '*'); res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Headers', res.header('Access-Control-Allow-Headers',
'Origin, X-Requested-With, Content-Type, Accept' 'Origin, X-Requested-With, Content-Type, Accept'
); );
next(); next();
}); });
var trusted = [ var trusted = [
@ -165,35 +165,35 @@ var trusted = [
]; ];
app.use(helmet.csp({ app.use(helmet.csp({
defaultSrc: trusted, defaultSrc: trusted,
scriptSrc: [ scriptSrc: [
'*.optimizely.com', '*.optimizely.com',
'*.aspnetcdn.com', '*.aspnetcdn.com',
'*.d3js.org' '*.d3js.org'
].concat(trusted), ].concat(trusted),
'connect-src': [ 'connect-src': [
].concat(trusted), ].concat(trusted),
styleSrc: trusted, styleSrc: trusted,
imgSrc: [ imgSrc: [
/* allow all input since we have user submitted images for public profile*/ /* allow all input since we have user submitted images for public profile*/
'*' '*'
].concat(trusted), ].concat(trusted),
fontSrc: ['*.googleapis.com'].concat(trusted), fontSrc: ['*.googleapis.com'].concat(trusted),
mediaSrc: [ mediaSrc: [
'*.amazonaws.com', '*.amazonaws.com',
'*.twitter.com' '*.twitter.com'
].concat(trusted), ].concat(trusted),
frameSrc: [ frameSrc: [
'*.gitter.im', '*.gitter.im',
'*.gitter.im https:', '*.gitter.im https:',
'*.vimeo.com', '*.vimeo.com',
'*.twitter.com', '*.twitter.com',
'*.ghbtns.com' '*.ghbtns.com'
].concat(trusted), ].concat(trusted),
reportOnly: false, // set to true if you only want to report errors reportOnly: false, // set to true if you only want to report errors
setAllHeaders: false, // set to true if you want to set all headers setAllHeaders: false, // set to true if you want to set all headers
safari5: false // set to true if you want to force buggy CSP in Safari 5 safari5: false // set to true if you want to force buggy CSP in Safari 5
})); }));
app.use(function (req, res, next) { app.use(function (req, res, next) {
@ -205,21 +205,17 @@ app.use(function (req, res, next) {
app.use(express.static(__dirname + '/public', {maxAge: 86400000 })); app.use(express.static(__dirname + '/public', {maxAge: 86400000 }));
app.use(function (req, res, next) { app.use(function (req, res, next) {
// Remember original destination before login. // Remember original destination before login.
var path = req.path.split('/')[1]; var path = req.path.split('/')[1];
if (/auth|login|logout|signin|signup|fonts|favicon/i.test(path)) { if (/auth|login|logout|signin|signup|fonts|favicon/i.test(path)) {
return next(); return next();
} else if (/\/stories\/comments\/\w+/i.test(req.path)) { } else if (/\/stories\/comments\/\w+/i.test(req.path)) {
return next(); return next();
} }
req.session.returnTo = req.path; req.session.returnTo = req.path;
next(); next();
}); });
// User migration middleware
app.use(userController.userMigration);
/** /**
* Main routes. * Main routes.
*/ */
@ -227,7 +223,7 @@ app.use(userController.userMigration);
app.get('/', homeController.index); app.get('/', homeController.index);
app.get('/nonprofit-project-instructions', function(req, res) { app.get('/nonprofit-project-instructions', function(req, res) {
res.redirect(301, '/field-guide/how-do-free-code-camp\'s-nonprofit-projects-work'); res.redirect(301, '/field-guide/how-do-free-code-camp\'s-nonprofit-projects-work');
}); });
app.post('/get-help', resourcesController.getHelp); app.post('/get-help', resourcesController.getHelp);
@ -260,14 +256,14 @@ app.get('/cats.json', function(req, res) {
// Agile Project Manager Onboarding // Agile Project Manager Onboarding
app.get('/pmi-acp-agile-project-managers', app.get('/pmi-acp-agile-project-managers',
resourcesController.agileProjectManagers); resourcesController.agileProjectManagers);
app.get('/agile', function(req, res) { app.get('/agile', function(req, res) {
res.redirect(301, '/pmi-acp-agile-project-managers'); res.redirect(301, '/pmi-acp-agile-project-managers');
}); });
app.get('/pmi-acp-agile-project-managers-form', app.get('/pmi-acp-agile-project-managers-form',
resourcesController.agileProjectManagersForm); resourcesController.agileProjectManagersForm);
// Nonprofit Onboarding // Nonprofit Onboarding
@ -280,31 +276,31 @@ app.get('/nonprofits-form', resourcesController.nonprofitsForm);
app.get('/map', challengeMapController.challengeMap); app.get('/map', challengeMapController.challengeMap);
app.get('/live-pair-programming', function(req, res) { app.get('/live-pair-programming', function(req, res) {
res.redirect(301, '/field-guide/live-stream-pair-programming-on-twitch.tv'); res.redirect(301, '/field-guide/live-stream-pair-programming-on-twitch.tv');
}); });
app.get('/install-screenhero', function(req, res) { app.get('/install-screenhero', function(req, res) {
res.redirect(301, '/field-guide/install-screenhero'); res.redirect(301, '/field-guide/install-screenhero');
}); });
app.get('/guide-to-our-nonprofit-projects', function(req, res) { app.get('/guide-to-our-nonprofit-projects', function(req, res) {
res.redirect(301, '/field-guide/a-guide-to-our-nonprofit-projects'); res.redirect(301, '/field-guide/a-guide-to-our-nonprofit-projects');
}); });
app.get('/chromebook', function(req, res) { app.get('/chromebook', function(req, res) {
res.redirect(301, '/field-guide/chromebook'); res.redirect(301, '/field-guide/chromebook');
}); });
app.get('/deploy-a-website', function(req, res) { app.get('/deploy-a-website', function(req, res) {
res.redirect(301, '/field-guide/deploy-a-website'); res.redirect(301, '/field-guide/deploy-a-website');
}); });
app.get('/gmail-shortcuts', function(req, res) { app.get('/gmail-shortcuts', function(req, res) {
res.redirect(301, '/field-guide/gmail-shortcuts'); res.redirect(301, '/field-guide/gmail-shortcuts');
}); });
app.get('/nodeschool-challenges', function(req, res) { app.get('/nodeschool-challenges', function(req, res) {
res.redirect(301, '/field-guide/nodeschool-challenges'); res.redirect(301, '/field-guide/nodeschool-challenges');
}); });
@ -349,8 +345,8 @@ app.post('/email-signin', userController.postSignin);
app.get('/nonprofits/directory', nonprofitController.nonprofitsDirectory); app.get('/nonprofits/directory', nonprofitController.nonprofitsDirectory);
app.get( app.get(
'/nonprofits/:nonprofitName', '/nonprofits/:nonprofitName',
nonprofitController.returnIndividualNonprofit nonprofitController.returnIndividualNonprofit
); );
app.get( app.get(
@ -528,8 +524,8 @@ app.get('/api/codepen/twitter/:screenName', resourcesController.codepenResources
app.get('/field-guide/all-articles', fieldGuideController.showAllFieldGuides); app.get('/field-guide/all-articles', fieldGuideController.showAllFieldGuides);
app.get('/field-guide/:fieldGuideName', app.get('/field-guide/:fieldGuideName',
fieldGuideController.returnIndividualFieldGuide fieldGuideController.returnIndividualFieldGuide
); );
app.get('/field-guide/', fieldGuideController.returnNextFieldGuide); app.get('/field-guide/', fieldGuideController.returnNextFieldGuide);
@ -540,14 +536,19 @@ app.post('/completed-field-guide/', fieldGuideController.completedFieldGuide);
* Challenge related routes * Challenge related routes
*/ */
app.get('/challenges/next-challenge', challengeController.returnNextChallenge); app.get('/challenges/next-challenge',
userController.userMigration,
challengeController.returnNextChallenge);
app.get( app.get(
'/challenges/:challengeName', '/challenges/:challengeName',
challengeController.returnIndividualChallenge userController.userMigration,
challengeController.returnIndividualChallenge
); );
app.get('/challenges/', challengeController.returnCurrentChallenge); app.get('/challenges/',
userController.userMigration,
challengeController.returnCurrentChallenge);
// todo refactor these routes // todo refactor these routes
app.post('/completed-challenge/', challengeController.completedChallenge); app.post('/completed-challenge/', challengeController.completedChallenge);
@ -558,12 +559,12 @@ app.post('/completed-bonfire', challengeController.completedBonfire);
// Unique Check API route // Unique Check API route
app.get('/api/checkUniqueUsername/:username', app.get('/api/checkUniqueUsername/:username',
userController.checkUniqueUsername userController.checkUniqueUsername
); );
app.get('/api/checkExistingUsername/:username', app.get('/api/checkExistingUsername/:username',
userController.checkExistingUsername userController.checkExistingUsername
); );
app.get('/api/checkUniqueEmail/:email', userController.checkUniqueEmail); app.get('/api/checkUniqueEmail/:email', userController.checkUniqueEmail);

View File

@ -6,7 +6,7 @@ var _ = require('lodash'),
User = require('../models/User'), User = require('../models/User'),
secrets = require('../config/secrets'), secrets = require('../config/secrets'),
moment = require('moment'), moment = require('moment'),
debug = require('debug')('freecc:cntr:challenges'), debug = require('debug')('freecc:cntr:userController'),
resources = require('./resources'), resources = require('./resources'),
R = require('ramda'); R = require('ramda');
@ -21,15 +21,17 @@ var _ = require('lodash'),
* challenge structure * challenge structure
*/ */
exports.userMigration = function(req, res, next) { exports.userMigration = function(req, res, next) {
debug('user migration called'); if (req.user && req.user.completedChallenges.length === 0) {
var user = req.user; debug('user migration called');
if (!user.migratedToUnifiedChallengeStructure && user) { debug('Completed coursewares', req.user.completedCoursewares);
user.migratedToUnifiedChallengeStructure = true; debug('Completed bonfires', req.user.completedBonfires);
user.completedChallenges = R.filter(function (elem) { req.user.completedChallenges = R.filter(function (elem) {
return elem; // getting rid of undefined return elem; // getting rid of undefined
}, R.concat( }, R.concat(
user.completedCoursewares, req.user.completedCoursewares,
user.completedBonfires.map(function (bonfire) { req.user.completedBonfires.map(function (bonfire) {
debug('Completed coursewares', req.user.completedCoursewares);
debug('Completed bonfires', req.user.completedBonfires);
return ({ return ({
completedDate: bonfire.completedDate, completedDate: bonfire.completedDate,
_id: bonfire._id, _id: bonfire._id,
@ -42,15 +44,11 @@ exports.userMigration = function(req, res, next) {
}); });
}) })
)); ));
user.save(function (err) { debug(req.user.completedChallenges);
if (err) { next();
next(err); } else {
} else { next();
next(req, res);
}
})
} }
next(req, res);
}; };
/** /**

View File

@ -168,7 +168,7 @@ var userSchema = new mongoose.Schema({
} }
} }
], ],
uncompletedChallenges: Array uncompletedChallenges: Array,
}); });
/** /**

View File

@ -103,7 +103,7 @@
"Complete \"Update\"", "Complete \"Update\"",
"Complete \"RM\"", "Complete \"RM\"",
"Complete \"Finale\"", "Complete \"Finale\"",
"Once you've completed these first 7 challenges, move on to our next waypoint.", "Once you've completed these first 7 challenges, move on to our next waypoint."
], ],
"challengeType": 2, "challengeType": 2,
"tests": [] "tests": []
@ -135,7 +135,7 @@
"Complete \"Filtered LS\"", "Complete \"Filtered LS\"",
"Complete \"Make it Modular\"", "Complete \"Make it Modular\"",
"Complete \"HTTP Client\"", "Complete \"HTTP Client\"",
"Once you've completed these first 7 challenges, move on to our next waypoint.", "Once you've completed these first 7 challenges, move on to our next waypoint."
], ],
"challengeType": 2, "challengeType": 2,
"tests": [] "tests": []