feat(gatsby): Initial gatsby scaffolding

This commit is contained in:
Bouncey
2018-08-23 16:29:26 +01:00
committed by mrugesh mohapatra
parent f0e5633b98
commit cd73528958
72 changed files with 20685 additions and 10032 deletions

View File

@@ -1,7 +1,14 @@
import dedent from 'dedent';
import debugFactory from 'debug';
import { curry } from 'lodash';
import { curry, pick } from 'lodash';
import { Observable } from 'rx';
import {
getProgress,
normaliseUserFields,
userPropsForSession
} from '../utils/publicUserProps';
import { fixCompletedChallengeItem } from '../../common/utils';
import {
ifNoUser401,
ifNoUserRedirectTo,
@@ -12,33 +19,22 @@ const debug = debugFactory('fcc:boot:user');
const sendNonUserToHome = ifNoUserRedirectTo('/');
const sendNonUserToHomeWithMessage = curry(ifNoUserRedirectTo, 2)('/');
module.exports = function(app) {
module.exports = function bootUser(app) {
const router = app.loopback.Router();
const api = app.loopback.Router();
const { Email, User } = app.models;
api.get('/account', sendNonUserToHome, getAccount);
api.get('/account/unlink/:social', sendNonUserToHome, getUnlinkSocial);
api.get('/user/get-session-user', readSessionUser);
api.post('/account/delete', ifNoUser401, createPostDeleteAccount(app));
api.post('/account/reset-progress', ifNoUser401, postResetProgress);
api.post(
'/account/delete',
'/user/:username/report-user/',
ifNoUser401,
postDeleteAccount
);
api.get(
'/account',
sendNonUserToHome,
getAccount
);
api.post(
'/account/reset-progress',
ifNoUser401,
postResetProgress
);
api.get(
'/account/unlink/:social',
sendNonUserToHome,
getUnlinkSocial
createPostReportUserProfile(app)
);
// Ensure these are the last routes!
router.get(
'/user/:username/report-user/',
sendNonUserToHomeWithMessage('You must be signed in to report a user'),
@@ -46,77 +42,161 @@ module.exports = function(app) {
getReportUserProfile
);
api.post(
'/user/:username/report-user/',
ifNoUser401,
postReportUserProfile
);
app.use(router);
app.use(api);
app.use('/external', api);
};
function getAccount(req, res) {
const { username } = req.user;
function readSessionUser(req, res, next) {
const queryUser = req.user;
const source =
queryUser &&
Observable.forkJoin(
queryUser.getCompletedChallenges$(),
queryUser.getPoints$(),
(completedChallenges, progressTimestamps) => ({
completedChallenges,
progress: getProgress(progressTimestamps, queryUser.timezone)
})
);
Observable.if(
() => !queryUser,
Observable.of({ user: {}, result: '' }),
Observable.defer(() => source)
.map(({ completedChallenges, progress }) => ({
...queryUser.toJSON(),
...progress,
completedChallenges: completedChallenges.map(fixCompletedChallengeItem)
}))
.map(user => ({
user: {
[user.username]: {
...pick(user, userPropsForSession),
isEmailVerified: !!user.emailVerified,
isGithub: !!user.githubProfile,
isLinkedIn: !!user.linkedin,
isTwitter: !!user.twitter,
isWebsite: !!user.website,
...normaliseUserFields(user)
}
},
result: user.username
}))
).subscribe(user => res.json(user), next);
}
function getReportUserProfile(req, res) {
const username = req.params.username.toLowerCase();
return res.render('account/report-profile', {
title: 'Report User',
username
});
}
function getAccount(req, res) {
const { username } = req.user;
return res.redirect('/' + username);
}
function getUnlinkSocial(req, res, next) {
const { user } = req;
const { username } = user;
let social = req.params.social;
if (!social) {
req.flash('danger', 'No social account found');
return res.redirect('/' + username);
}
function getUnlinkSocial(req, res, next) {
const { user } = req;
const { username } = user;
social = social.toLowerCase();
const validSocialAccounts = ['twitter', 'linkedin'];
if (validSocialAccounts.indexOf(social) === -1) {
req.flash('danger', 'Invalid social account');
return res.redirect('/' + username);
}
let social = req.params.social;
if (!social) {
if (!user[social]) {
req.flash('danger', `No ${social} account associated`);
return res.redirect('/' + username);
}
const query = {
where: {
provider: social
}
};
return user.identities(query, function(err, identities) {
if (err) {
return next(err);
}
// assumed user identity is unique by provider
let identity = identities.shift();
if (!identity) {
req.flash('danger', 'No social account found');
return res.redirect('/' + username);
}
social = social.toLowerCase();
const validSocialAccounts = ['twitter', 'linkedin'];
if (validSocialAccounts.indexOf(social) === -1) {
req.flash('danger', 'Invalid social account');
return res.redirect('/' + username);
}
if (!user[social]) {
req.flash('danger', `No ${social} account associated`);
return res.redirect('/' + username);
}
const query = {
where: {
provider: social
return identity.destroy(function(err) {
if (err) {
return next(err);
}
};
return user.identities(query, function(err, identities) {
if (err) { return next(err); }
const updateData = { [social]: null };
// assumed user identity is unique by provider
let identity = identities.shift();
if (!identity) {
req.flash('danger', 'No social account found');
return user.update$(updateData).subscribe(() => {
debug(`${social} has been unlinked successfully`);
req.flash('info', `You've successfully unlinked your ${social}.`);
return res.redirect('/' + username);
}
return identity.destroy(function(err) {
if (err) { return next(err); }
const updateData = { [social]: null };
return user.update$(updateData)
.subscribe(() => {
debug(`${social} has been unlinked successfully`);
req.flash('info', `You've successfully unlinked your ${social}.`);
return res.redirect('/' + username);
}, next);
});
}, next);
});
}
});
}
function postDeleteAccount(req, res, next) {
function postResetProgress(req, res, next) {
const { user } = req;
user.updateAttributes(
{
progressTimestamps: [
{
timestamp: Date.now()
}
],
currentChallengeId: '',
isRespWebDesignCert: false,
is2018DataVisCert: false,
isFrontEndLibsCert: false,
isJsAlgoDataStructCert: false,
isApisMicroservicesCert: false,
isInfosecQaCert: false,
is2018FullStackCert: false,
isFrontEndCert: false,
isBackEndCert: false,
isDataVisCert: false,
isFullStackCert: false,
completedChallenges: []
},
function(err) {
if (err) {
return next(err);
}
return res.status(200).json({
messageType: 'success',
message: 'You have successfully reset your progress'
});
}
);
}
function createPostDeleteAccount(app) {
const { User } = app.models;
return function postDeleteAccount(req, res, next) {
User.destroyById(req.user.id, function(err) {
if (err) { return next(err); }
if (err) {
return next(err);
}
req.logout();
req.flash('success', 'You have successfully deleted your account.');
const config = {
@@ -129,48 +209,12 @@ module.exports = function(app) {
res.clearCookie('_csrf', config);
return res.status(200).end();
});
}
};
}
function postResetProgress(req, res, next) {
User.findById(req.user.id, function(err, user) {
if (err) { return next(err); }
return user.update$({
progressTimestamps: [{
timestamp: Date.now()
}],
currentChallengeId: '',
isRespWebDesignCert: false,
is2018DataVisCert: false,
isFrontEndLibsCert: false,
isJsAlgoDataStructCert: false,
isApisMicroservicesCert: false,
isInfosecQaCert: false,
is2018FullStackCert: false,
isFrontEndCert: false,
isBackEndCert: false,
isDataVisCert: false,
isFullStackCert: false,
completedChallenges: []
})
.subscribe(
() => {
req.flash('success', 'You have successfully reset your progress.');
return res.status(200).end();
},
next
);
});
}
function getReportUserProfile(req, res) {
const username = req.params.username.toLowerCase();
return res.render('account/report-profile', {
title: 'Report User',
username
});
}
function postReportUserProfile(req, res, next) {
function createPostReportUserProfile(app) {
const { Email } = app.models;
return function postReportUserProfile(req, res, next) {
const { user } = req;
const { username } = req.params;
const report = req.sanitize('reportDescription').trimTags();
@@ -183,13 +227,14 @@ module.exports = function(app) {
return next();
}
return Email.send$({
type: 'email',
to: 'team@freecodecamp.org',
cc: user.email,
from: 'team@freecodecamp.org',
subject: 'Abuse Report : Reporting ' + username + '\'s profile.',
text: dedent(`
return Email.send$(
{
type: 'email',
to: 'team@freecodecamp.org',
cc: user.email,
from: 'team@freecodecamp.org',
subject: 'Abuse Report : Reporting ' + username + "'s profile.",
text: dedent(`
Hello Team,\n
This is to report the profile of ${username}.\n
Report Details:\n
@@ -201,18 +246,19 @@ module.exports = function(app) {
Thanks and regards,
${user.name}
`)
}, err => {
if (err) {
err.redirectTo = '/' + username;
return next(err);
},
err => {
if (err) {
err.redirectTo = '/' + username;
return next(err);
}
req.flash(
'info',
`A report was sent to the team with ${user.email} in copy.`
);
return res.redirect('/');
}
req.flash(
'info',
`A report was sent to the team with ${user.email} in copy.`
);
return res.redirect('/');
});
}
};
);
};
}