diff --git a/server/boot/challenge.js b/server/boot/challenge.js index 5994444c17..60312d019f 100644 --- a/server/boot/challenge.js +++ b/server/boot/challenge.js @@ -4,8 +4,10 @@ import debug from 'debug'; import accepts from 'accepts'; import { ifNoUserSend } from '../utils/middleware'; +import { cachedMap } from '../utils/map'; +import createNameIdMap from '../../common/utils/create-name-id-map'; -const log = debug('fcc:challenges'); +const log = debug('fcc:boot:challenges'); function buildUserUpdate( user, @@ -58,11 +60,14 @@ function buildUserUpdate( return { alreadyCompleted, updateData }; } -module.exports = function(app) { - const router = app.loopback.Router(); +export default function(app) { const send200toNonUser = ifNoUserSend(true); + const api = app.loopback.Router(); + const router = app.loopback.Router(); + const Block = app.models.Block; + const map$ = cachedMap(Block); - router.post( + api.post( '/modern-challenge-completed', send200toNonUser, modernChallengeCompleted @@ -70,13 +75,13 @@ module.exports = function(app) { // deprecate endpoint // remove once new endpoint is live - router.post( + api.post( '/completed-challenge', send200toNonUser, completedChallenge ); - router.post( + api.post( '/challenge-completed', send200toNonUser, completedChallenge @@ -84,19 +89,25 @@ module.exports = function(app) { // deprecate endpoint // remove once new endpoint is live - router.post( + api.post( '/completed-zipline-or-basejump', send200toNonUser, projectCompleted ); - router.post( + api.post( '/project-completed', send200toNonUser, projectCompleted ); - app.use(router); + router.get( + '/challenges/current-challenge', + redirectToCurrentChallenge + ); + + app.use(api); + app.use('/:lang', router); function modernChallengeCompleted(req, res, next) { const type = accepts(req).type('html', 'json', 'text'); @@ -255,4 +266,53 @@ module.exports = function(app) { }) .subscribe(() => {}, next); } -}; + + function redirectToCurrentChallenge(req, res, next) { + const { user } = req; + return map$ + .map(({ entities, result }) => ({ + result, + entities: createNameIdMap(entities) + })) + .map(({ + result, + entities: { + challenge: challengeMap, + block: blockMap, + superBlock: superBlockMap, + challengeIdToName + } + }) => { + let finalChallenge; + const dashedName = challengeIdToName[user && user.currentChallengeId]; + finalChallenge = challengeMap[dashedName]; + if ( + !challengeMap || + !blockMap || + !superBlockMap || + !result || + !result.length + ) { + throw new Error( + 'entities not found, db may not be properly seeded. Crashing hard' + ); + } + // redirect to first challenge + if (!finalChallenge) { + finalChallenge = challengeMap[ + block[ + superBlockMap[ + result[0] + ].blocks[0] + ].challenges[0] + ]; + } + const { block, dashedName: finalDashedName } = finalChallenge || {}; + return `/challenges/${block}/${finalDashedName}`; + }) + .subscribe( + redirect => res.redirect(redirect || '/map'), + next + ); + } +}