freeCodeCamp/api-server/server/boot/settings.js

215 lines
5.5 KiB
JavaScript
Raw Normal View History

import { check } from 'express-validator/check';
2018-08-24 23:17:40 +00:00
import { ifNoUser401, createValidatorErrorHandler } from '../utils/middleware';
import { themes } from '../../common/utils/themes.js';
import { alertTypes } from '../../common/utils/flash.js';
export default function settingsController(app) {
const api = app.loopback.Router();
const toggleUserFlag = (flag, req, res, next) => {
const { user } = req;
2018-08-24 23:17:40 +00:00
const currentValue = user[flag];
return user.update$({ [flag]: !currentValue }).subscribe(
() =>
res.status(200).json({
flag,
value: !currentValue
}),
2018-08-24 23:17:40 +00:00
next
);
};
function refetchCompletedChallenges(req, res, next) {
const { user } = req;
2018-08-24 23:17:40 +00:00
return user
.requestCompletedChallenges()
.subscribe(completedChallenges => res.json({ completedChallenges }), next);
}
const updateMyEmailValidators = [
check('email')
.isEmail()
.withMessage('Email format is invalid.')
];
function updateMyEmail(req, res, next) {
2018-08-24 23:17:40 +00:00
const {
user,
body: { email }
} = req;
return user
.requestUpdateEmail(email)
.subscribe(message => res.json({ message }), next);
}
const updateMyCurrentChallengeValidators = [
check('currentChallengeId')
.isMongoId()
.withMessage('currentChallengeId is not a valid challenge ID')
];
function updateMyCurrentChallenge(req, res, next) {
2018-08-24 23:17:40 +00:00
const {
user,
body: { currentChallengeId }
} = req;
return user.update$({ currentChallengeId }).subscribe(
2018-08-24 23:17:40 +00:00
() =>
res.json({
message: `your current challenge has been updated to ${currentChallengeId}`
}),
next
);
}
const updateMyThemeValidators = [
check('theme')
2018-08-24 23:17:40 +00:00
.isIn(Object.keys(themes))
.withMessage('Theme is invalid.')
];
function updateMyTheme(req, res, next) {
2018-08-24 23:17:40 +00:00
const {
body: { theme }
} = req;
if (req.user.theme === theme) {
return res.sendFlash(alertTypes.info, 'Theme already set');
}
2018-08-24 23:17:40 +00:00
return req.user
.updateTheme(theme)
.then(
() => res.sendFlash(alertTypes.info, 'Your theme has been updated'),
next
);
}
function updateFlags(req, res, next) {
2018-08-24 23:17:40 +00:00
const {
user,
body: { values }
} = req;
const keys = Object.keys(values);
2018-08-24 23:17:40 +00:00
if (keys.length === 1 && typeof keys[0] === 'boolean') {
return toggleUserFlag(keys[0], req, res, next);
}
2018-08-24 23:17:40 +00:00
return user
.requestUpdateFlags(values)
.subscribe(message => res.json({ message }), next);
}
function updateMyPortfolio(req, res, next) {
const {
user,
body: { portfolio }
} = req;
// if we only have one key, it should be the id
// user cannot send only one key to this route
// other than to remove a portfolio item
const requestDelete = Object.keys(portfolio).length === 1;
2018-08-24 23:17:40 +00:00
return user
.updateMyPortfolio(portfolio, requestDelete)
.subscribe(message => res.json({ message }), next);
}
function updateMyProfileUI(req, res, next) {
const {
user,
body: { profileUI }
} = req;
2018-08-24 23:17:40 +00:00
return user
.updateMyProfileUI(profileUI)
.subscribe(message => res.json({ message }), next);
}
function updateMyProjects(req, res, next) {
const {
user,
body: { projects: project }
} = req;
2018-08-24 23:17:40 +00:00
return user
.updateMyProjects(project)
.subscribe(message => res.json({ message }), next);
}
function updateMyUsername(req, res, next) {
2018-08-24 23:17:40 +00:00
const {
user,
body: { username }
} = req;
return user
.updateMyUsername(username)
.subscribe(message => res.json({ message }), next);
}
2018-08-24 23:17:40 +00:00
const updatePrivacyTerms = (req, res) => {
2018-05-27 11:59:04 +00:00
const {
user,
2018-08-24 23:17:40 +00:00
body: { quincyEmails }
2018-05-27 11:59:04 +00:00
} = req;
const update = {
acceptedPrivacyTerms: true,
2018-08-24 23:17:40 +00:00
sendQuincyEmail: !!quincyEmails
2018-05-27 11:59:04 +00:00
};
2018-08-24 23:17:40 +00:00
return user.updateAttributes(update, err => {
if (err) {
return res.status(500).json({
type: 'warning',
message:
'Something went wrong updating your preferences. ' +
'Please try again.'
});
}
return res.status(200).json({
type: 'success',
message:
'We have updated your preferences. ' +
'You can now continue using freeCodeCamp.'
});
});
2018-05-27 11:59:04 +00:00
};
2018-08-24 23:17:40 +00:00
api.put('/update-privacy-terms', ifNoUser401, updatePrivacyTerms);
2018-05-27 11:59:04 +00:00
api.post(
'/refetch-user-completed-challenges',
ifNoUser401,
refetchCompletedChallenges
);
2018-08-24 23:17:40 +00:00
api.post('/update-flags', ifNoUser401, updateFlags);
2018-08-29 19:52:41 +00:00
api.put(
'/update-my-email',
ifNoUser401,
updateMyEmailValidators,
createValidatorErrorHandler(alertTypes.danger),
updateMyEmail
);
2017-06-17 22:09:43 +00:00
api.post(
'/update-my-current-challenge',
2017-06-17 22:09:43 +00:00
ifNoUser401,
updateMyCurrentChallengeValidators,
createValidatorErrorHandler(alertTypes.danger),
updateMyCurrentChallenge
2017-06-17 22:09:43 +00:00
);
api.post(
2018-08-29 19:52:41 +00:00
'/update-my-current-challenge',
ifNoUser401,
updateMyCurrentChallengeValidators,
createValidatorErrorHandler(alertTypes.danger),
updateMyCurrentChallenge
);
2018-08-24 23:17:40 +00:00
api.post('/update-my-portfolio', ifNoUser401, updateMyPortfolio);
api.post('/update-my-profile-ui', ifNoUser401, updateMyProfileUI);
api.post('/update-my-projects', ifNoUser401, updateMyProjects);
api.post(
'/update-my-theme',
ifNoUser401,
updateMyThemeValidators,
createValidatorErrorHandler(alertTypes.danger),
updateMyTheme
);
2018-08-24 23:17:40 +00:00
api.post('/update-my-username', ifNoUser401, updateMyUsername);
2018-08-24 23:17:40 +00:00
app.use('/external', api);
2018-08-29 19:52:41 +00:00
app.use('/internal', api);
app.use(api);
}