From fc29c1fd9b11a2ac2116f8af88e13c7711f4b97b Mon Sep 17 00:00:00 2001 From: Berkeley Martinez Date: Wed, 12 Aug 2015 16:25:52 -0700 Subject: [PATCH] linking accounts now works. bug, need to change how loopback generates provider string. --- common/models/User-Identity.js | 8 +++-- server/boot/a-extendUser.js | 10 +++--- server/boot/a-extendUserIdent.js | 59 +++++++++++++++++++++++++++++++ server/passport-providers.js | 3 ++ server/server.js | 4 +++ server/utils/rx.js | 2 +- server/views/account/account.jade | 2 +- 7 files changed, 80 insertions(+), 8 deletions(-) create mode 100644 server/boot/a-extendUserIdent.js diff --git a/common/models/User-Identity.js b/common/models/User-Identity.js index fe9f135b91..b622b84d94 100644 --- a/common/models/User-Identity.js +++ b/common/models/User-Identity.js @@ -24,7 +24,7 @@ export default function(UserIdent) { return next(); } - const { profile } = userIdent; + const { profile, provider } = userIdent; const picture = getFirstImageFromProfile(profile); debug('picture', picture, user.picture); @@ -41,8 +41,12 @@ export default function(UserIdent) { userChanged = true; } + if (!(/github/).test(provider)) { + user[provider.split('-')[0]] = profile.username; + } + // if user signed in with github refresh their info - if (/github/.test(userIdent.provider)) { + if (/github/.test(provider)) { debug("user isn't github cool or username from github is different"); setProfileFromGithub(user, profile, profile._json); userChanged = true; diff --git a/server/boot/a-extendUser.js b/server/boot/a-extendUser.js index 3b0ced4cca..abeefcf728 100644 --- a/server/boot/a-extendUser.js +++ b/server/boot/a-extendUser.js @@ -1,8 +1,10 @@ -var Rx = require('rx'); -var debug = require('debug')('freecc:user:remote'); +import { Observable } from 'rx'; +import debugFactory from 'debug'; + +const debug = debugFactory('freecc:user:remote'); function destroyAllRelated(id, Model) { - return Rx.Observable.fromNodeCallback( + return Observable.fromNodeCallback( Model.destroyAll, Model )({ userId: id }); @@ -19,7 +21,7 @@ module.exports = function(app) { if (!id) { return next(); } - Rx.Observable.combineLatest( + Observable.combineLatest( destroyAllRelated(id, UserIdentity), destroyAllRelated(id, UserCredential), function(identData, credData) { diff --git a/server/boot/a-extendUserIdent.js b/server/boot/a-extendUserIdent.js new file mode 100644 index 0000000000..940672cb2f --- /dev/null +++ b/server/boot/a-extendUserIdent.js @@ -0,0 +1,59 @@ +import { observeMethod, observeQuery } from '../utils/rx'; + +export default function({ models }) { + const { User, UserIdentity, UserCredential } = models; + const findUserById = observeMethod(User, 'findById'); + const findIdent = observeMethod(UserIdentity, 'findOne'); + + UserIdentity.link = function( + userId, + provider, + authScheme, + profile, + credentials, + options = {}, + cb + ) { + if (typeof options === 'function' && !cb) { + cb = options; + options = {}; + } + const user$ = findUserById(userId); + console.log('provider', provider); + console.log('id', profile.id); + findIdent({ + provider: provider, + externalId: profile.id + }) + .flatMap(identity => { + const modified = new Date(); + if (!identity || identity.externalId !== profile.id) { + return observeQuery(UserIdentity, 'create', { + provider, + externalId: profile.id, + authScheme, + profile, + credentials, + userId, + created: modified, + modified + }); + } + identity.credentials = credentials; + return observeQuery(identity, 'updateAttributes', { + profile, + credentials, + modified + }); + }) + .withLatestFrom(user$, (identity, user) => ({ identity, user })) + .subscribe( + ({ identity, user }) => { + cb(null, user, identity); + }, + cb + ); + }; + + UserCredential.link = UserIdentity.link.bind(UserIdentity); +} diff --git a/server/passport-providers.js b/server/passport-providers.js index 5ffcbf1a09..fc71a1e705 100644 --- a/server/passport-providers.js +++ b/server/passport-providers.js @@ -92,6 +92,7 @@ module.exports = { failureRedirect: failureRedirect, consumerKey: process.env.TWITTER_KEY, consumerSecret: process.env.TWITTER_SECRET, + link: true, failureFlash: true }, 'linkedin-login': { @@ -126,6 +127,7 @@ module.exports = { authOptions: { state: process.env.LINKEDIN_STATE }, + link: true, failureFlash: true }, 'github-login': { @@ -154,6 +156,7 @@ module.exports = { clientID: process.env.GITHUB_ID, clientSecret: process.env.GITHUB_SECRET, scope: ['email'], + link: true, failureFlash: true } }; diff --git a/server/server.js b/server/server.js index 012c5ffd3f..d9f2028dfb 100755 --- a/server/server.js +++ b/server/server.js @@ -66,6 +66,10 @@ var passportOptions = { userObj.email = email; } + if (!(/github/).test(provider)) { + userObj[provider.split('-')[0]] = profile.username; + } + if (/github/.test(provider)) { setProfileFromGithub(userObj, profile, profile._json); } diff --git a/server/utils/rx.js b/server/utils/rx.js index 7f0bac0704..d3b1ac41b0 100644 --- a/server/utils/rx.js +++ b/server/utils/rx.js @@ -22,7 +22,7 @@ exports.saveInstance = function saveInstance(instance) { // alias saveInstance exports.saveUser = exports.saveInstance; -exports.observableQueryFromModel = +exports.observeQuery = exports.observableQueryFromModel = function observableQueryFromModel(Model, method, query) { return Rx.Observable.fromNodeCallback(Model[method], Model)(query); }; diff --git a/server/views/account/account.jade b/server/views/account/account.jade index 22ad1b9975..9dd664849c 100644 --- a/server/views/account/account.jade +++ b/server/views/account/account.jade @@ -8,7 +8,7 @@ block content .row .col-xs-12 if (!user.isGithubCool) - a.btn.btn-lg.btn-block.btn-github.btn-link-social(href='/auth/github') + a.btn.btn-lg.btn-block.btn-github.btn-link-social(href='/link/github') i.fa.fa-github | Link my GitHub to unlock this profile else