2015-10-02 18:47:36 +00:00
|
|
|
import _ from 'lodash';
|
|
|
|
import dedent from 'dedent';
|
|
|
|
import { Observable } from 'rx';
|
|
|
|
import debugFactory from 'debug';
|
|
|
|
|
|
|
|
import {
|
|
|
|
ifNoUser401,
|
|
|
|
ifNoUserSend
|
|
|
|
} from '../utils/middleware';
|
|
|
|
|
|
|
|
import {
|
|
|
|
saveUser,
|
|
|
|
observeQuery
|
|
|
|
} from '../utils/rx';
|
|
|
|
|
2015-10-06 02:58:44 +00:00
|
|
|
import {
|
2015-12-09 22:34:33 +00:00
|
|
|
frontEndChallengeId,
|
|
|
|
backEndChallengeId
|
2015-10-06 02:58:44 +00:00
|
|
|
} from '../utils/constantStrings.json';
|
|
|
|
|
2015-10-07 04:08:24 +00:00
|
|
|
import {
|
|
|
|
completeCommitment$
|
|
|
|
} from '../utils/commit';
|
|
|
|
|
2015-10-02 18:47:36 +00:00
|
|
|
const debug = debugFactory('freecc:certification');
|
|
|
|
const sendMessageToNonUser = ifNoUserSend(
|
|
|
|
'must be logged in to complete.'
|
|
|
|
);
|
|
|
|
|
2015-12-09 22:34:33 +00:00
|
|
|
function isCertified(ids, { completedChallenges }) {
|
|
|
|
return _.every(ids, ({ id }) => {
|
2015-10-07 23:30:51 +00:00
|
|
|
return _.some(completedChallenges, (challenge) => {
|
|
|
|
return challenge.id === id || challenge._id === id;
|
|
|
|
});
|
|
|
|
});
|
2015-10-02 18:47:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
export default function certificate(app) {
|
|
|
|
const router = app.loopback.Router();
|
|
|
|
const { Challenge } = app.models;
|
|
|
|
|
2015-12-09 22:34:33 +00:00
|
|
|
const frontEndChallengeIds$ = observeQuery(
|
2015-10-02 18:47:36 +00:00
|
|
|
Challenge,
|
|
|
|
'findById',
|
2015-12-09 22:34:33 +00:00
|
|
|
frontEndChallengeId,
|
2015-10-02 18:47:36 +00:00
|
|
|
{
|
2015-10-06 02:58:44 +00:00
|
|
|
id: true,
|
|
|
|
tests: true,
|
|
|
|
name: true,
|
|
|
|
challengeType: true
|
2015-10-02 18:47:36 +00:00
|
|
|
}
|
|
|
|
)
|
|
|
|
.shareReplay();
|
|
|
|
|
2015-12-09 22:34:33 +00:00
|
|
|
const backEndChallengeIds$ = observeQuery(
|
2015-10-02 18:47:36 +00:00
|
|
|
Challenge,
|
|
|
|
'findById',
|
2015-12-09 22:34:33 +00:00
|
|
|
backEndChallengeId,
|
2015-10-02 18:47:36 +00:00
|
|
|
{
|
2015-10-06 02:58:44 +00:00
|
|
|
id: true,
|
|
|
|
tests: true,
|
|
|
|
name: true,
|
|
|
|
challengeType: true
|
2015-10-02 18:47:36 +00:00
|
|
|
}
|
|
|
|
)
|
|
|
|
.shareReplay();
|
|
|
|
|
|
|
|
router.post(
|
|
|
|
'/certificate/verify/front-end',
|
|
|
|
ifNoUser401,
|
|
|
|
verifyCert
|
|
|
|
);
|
|
|
|
|
|
|
|
router.post(
|
2015-12-09 22:34:33 +00:00
|
|
|
'/certificate/verify/back-end',
|
2015-10-02 18:47:36 +00:00
|
|
|
ifNoUser401,
|
|
|
|
verifyCert
|
|
|
|
);
|
|
|
|
|
|
|
|
router.post(
|
|
|
|
'/certificate/honest',
|
|
|
|
sendMessageToNonUser,
|
|
|
|
postHonest
|
|
|
|
);
|
|
|
|
|
|
|
|
app.use(router);
|
|
|
|
|
|
|
|
function verifyCert(req, res, next) {
|
|
|
|
const isFront = req.path.split('/').pop() === 'front-end';
|
|
|
|
Observable.just({})
|
|
|
|
.flatMap(() => {
|
|
|
|
if (isFront) {
|
2015-12-09 22:34:33 +00:00
|
|
|
return frontEndChallengeIds$;
|
2015-10-02 18:47:36 +00:00
|
|
|
}
|
2015-12-09 22:34:33 +00:00
|
|
|
return backEndChallengeIds$;
|
2015-10-02 18:47:36 +00:00
|
|
|
})
|
2015-10-06 02:58:44 +00:00
|
|
|
.flatMap(challenge => {
|
2015-10-02 18:47:36 +00:00
|
|
|
const { user } = req;
|
2015-10-06 02:58:44 +00:00
|
|
|
const {
|
|
|
|
id,
|
|
|
|
tests,
|
|
|
|
name,
|
|
|
|
challengeType
|
|
|
|
} = challenge;
|
2015-10-02 18:47:36 +00:00
|
|
|
if (
|
2015-12-09 22:34:33 +00:00
|
|
|
|
|
|
|
isFront &&
|
|
|
|
!user.isFrontEndCert &&
|
|
|
|
isCertified(tests, user) ||
|
|
|
|
|
|
|
|
!isFront &&
|
|
|
|
!user.isBackEndCert &&
|
|
|
|
isCertified(tests, user)
|
|
|
|
|
2015-10-02 18:47:36 +00:00
|
|
|
) {
|
|
|
|
debug('certified');
|
|
|
|
if (isFront) {
|
|
|
|
user.isFrontEndCert = true;
|
|
|
|
} else {
|
2015-12-09 22:34:33 +00:00
|
|
|
user.isBackEndCert = true;
|
2015-10-02 18:47:36 +00:00
|
|
|
}
|
2015-10-06 02:58:44 +00:00
|
|
|
|
|
|
|
user.completedChallenges.push({
|
|
|
|
id,
|
|
|
|
name,
|
|
|
|
completedDate: new Date(),
|
|
|
|
challengeType
|
|
|
|
});
|
2015-10-07 04:08:24 +00:00
|
|
|
return saveUser(user)
|
|
|
|
// If user has commited to nonprofit,
|
|
|
|
// this will complete his pledge
|
|
|
|
.flatMap(
|
|
|
|
user => completeCommitment$(user),
|
|
|
|
(user, pledgeOrMessage) => {
|
|
|
|
if (typeof pledgeOrMessage === 'string') {
|
|
|
|
debug(pledgeOrMessage);
|
|
|
|
}
|
|
|
|
// we are only interested in the user object
|
|
|
|
// so we ignore return from completeCommitment$
|
|
|
|
return user;
|
|
|
|
}
|
|
|
|
);
|
2015-10-02 18:47:36 +00:00
|
|
|
}
|
|
|
|
return Observable.just(user);
|
|
|
|
})
|
|
|
|
.subscribe(
|
|
|
|
user => {
|
|
|
|
if (
|
|
|
|
isFront && user.isFrontEndCert ||
|
2015-12-09 22:34:33 +00:00
|
|
|
!isFront && user.isBackEndCert
|
2015-10-02 18:47:36 +00:00
|
|
|
) {
|
|
|
|
return res.status(200).send(true);
|
|
|
|
}
|
|
|
|
return res.status(200).send(
|
|
|
|
dedent`
|
2015-10-07 09:22:04 +00:00
|
|
|
Looks like you have not completed the neccessary steps.
|
|
|
|
Please return to the challenge map.
|
2015-10-02 18:47:36 +00:00
|
|
|
`
|
|
|
|
);
|
|
|
|
},
|
|
|
|
next
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
function postHonest(req, res, next) {
|
|
|
|
const { user } = req;
|
|
|
|
user.isHonest = true;
|
|
|
|
saveUser(user)
|
|
|
|
.subscribe(
|
|
|
|
(user) => {
|
|
|
|
res.status(200).send(!!user.isHonest);
|
|
|
|
},
|
|
|
|
next
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|