diff --git a/common/app/routes/settings/components/Social-Settings.jsx b/common/app/routes/settings/components/Social-Settings.jsx
index f1a3691ce7..23c3a49078 100644
--- a/common/app/routes/settings/components/Social-Settings.jsx
+++ b/common/app/routes/settings/components/Social-Settings.jsx
@@ -1,6 +1,7 @@
import React, { PropTypes } from 'react';
import { Button } from 'react-bootstrap';
import FA from 'react-fontawesome';
+import classnames from 'classnames';
export default function SocialSettings({
isGithubCool,
@@ -22,33 +23,44 @@ export default function SocialSettings({
{ githubCopy }
];
- if (isGithubCool && !isTwitter) {
- buttons.push((
-
- ));
- }
- if (isGithubCool && !isLinkedIn) {
- buttons.push((
-
- ));
+ const socials = [
+ {
+ isActive: isTwitter,
+ identifier: 'twitter',
+ text: 'Twitter'
+ },
+ {
+ isActive: isLinkedIn,
+ identifier: 'linkedin',
+ text: 'LinkedIn'
+ }
+ ];
+ if (isGithubCool) {
+ socials.forEach(({ isActive, identifier, text }) => {
+ const socialClass = classnames(
+ 'btn-link-social',
+ `btn-${identifier}`,
+ { active: isActive }
+ );
+ const socialLink = isActive ?
+ `/account/unlink/${identifier}` :
+ `/link/${identifier}`;
+ const socialText = isTwitter ?
+ `Remove my ${text} from my portfolio` :
+ `Add my ${text} to my portfolio`;
+ buttons.push((
+
+ ));
+ });
}
return (
{ buttons }
);
}
diff --git a/server/boot/user.js b/server/boot/user.js
index cc5ea1d664..e07e3639bd 100644
--- a/server/boot/user.js
+++ b/server/boot/user.js
@@ -184,6 +184,12 @@ module.exports = function(app) {
getAccount
);
+ api.get(
+ '/account/unlink/:social',
+ sendNonUserToMap,
+ getUnlinkSocial
+ );
+
// Ensure these are the last routes!
api.get(
'/:username/front-end-certification',
@@ -266,6 +272,70 @@ module.exports = function(app) {
return res.redirect('/' + username);
}
+ function getUnlinkSocial(req, res, next) {
+ const { user } = req;
+ const { username } = user;
+
+ let social = req.params.social;
+ if (!social) {
+ req.flash('errors', {
+ msg: 'No social account found'
+ });
+ return res.redirect('/' + username);
+ }
+
+ social = social.toLowerCase();
+ const validSocialAccounts = ['twitter', 'linkedin'];
+ if (validSocialAccounts.indexOf(social) === -1) {
+ req.flash('errors', {
+ msg: 'Invalid social account'
+ });
+ return res.redirect('/' + username);
+ }
+
+ if (!user[social]) {
+ req.flash('errors', {
+ msg: `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('errors', {
+ msg: 'No social account found'
+ });
+ 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', {
+ msg: `You\'ve successfully unlinked your ${social}.`
+ });
+ return res.redirect('/' + username);
+ }, next);
+ });
+ });
+ }
+
function showUserProfile(req, res, next) {
const username = req.params.username.toLowerCase();
const { user } = req;