From eb07cbfea6697b9dbc7ed7035c4a48ac976df484 Mon Sep 17 00:00:00 2001 From: Berkeley Martinez Date: Wed, 12 Aug 2015 19:08:05 -0700 Subject: [PATCH] fix override user identity login to reformat provider --- common/models/User-Identity.js | 131 +++++++++++++++++++++++++++++-- server/boot/a-extendUserIdent.js | 7 +- server/utils/auth.js | 4 + 3 files changed, 132 insertions(+), 10 deletions(-) diff --git a/common/models/User-Identity.js b/common/models/User-Identity.js index b622b84d94..58ac7ed380 100644 --- a/common/models/User-Identity.js +++ b/common/models/User-Identity.js @@ -1,20 +1,137 @@ +import loopback from 'loopback'; import debugFactory from 'debug'; import { setProfileFromGithub, - getFirstImageFromProfile + getFirstImageFromProfile, + getSocialProvider } from '../../server/utils/auth'; const debug = debugFactory('freecc:models:userIdent'); const { defaultProfileImage } = require('../utils/constantStrings.json'); +function createAccessToken(user, ttl, cb) { + if (arguments.length === 2 && typeof ttl === 'function') { + cb = ttl; + ttl = 0; + } + user.accessTokens.create({ + created: new Date(), + ttl: Math.min(ttl || user.constructor.settings.ttl, + user.constructor.settings.maxTTL) + }, cb); +} + export default function(UserIdent) { - UserIdent.observe('before save', function(ctx, next) { - var userIdent = ctx.currentInstance || ctx.instance; - if (!userIdent) { - debug('no user identity instance found'); - return next(); + // original source + // github.com/strongloop/loopback-component-passport + UserIdent.login = function( + provider, + authScheme, + profile, + credentials, + options, + cb + ) { + options = options || {}; + if (typeof options === 'function' && !cb) { + cb = options; + options = {}; + } + var autoLogin = options.autoLogin || !options.autoLogin; + var userIdentityModel = UserIdent; + profile.id = profile.id || profile.openid; + userIdentityModel.findOne({ + where: { + provider: getSocialProvider(provider), + externalId: profile.id + } + }, function(err, identity) { + if (err) { + return cb(err); + } + if (identity) { + identity.credentials = credentials; + return identity.updateAttributes({ + profile: profile, + credentials: credentials, + modified: new Date() + }, function(err) { + if (err) { + return cb(err); + } + // Find the user for the given identity + return identity.user(function(err, user) { + // Create access token if the autoLogin flag is set to true + if (!err && user && autoLogin) { + return (options.createAccessToken || createAccessToken)( + user, + function(err, token) { + cb(err, user, identity, token); + } + ); + } + cb(err, user, identity); + }); + }); + } + // Find the user model + var userModel = userIdentityModel.relations.user && + userIdentityModel.relations.user.modelTo || + loopback.getModelByType(loopback.User); + + var userObj = options.profileToUser(provider, profile, options); + + if (!userObj.email && !options.emailOptional) { + process.nextTick(function() { + return cb('email is missing from the user profile'); + }); + } + + var query; + if (userObj.email) { + query = { or: [ + { username: userObj.username }, + { email: userObj.email } + ]}; + } else { + query = { username: userObj.username }; + } + userModel.findOrCreate({ where: query }, userObj, function(err, user) { + if (err) { + return cb(err); + } + var date = new Date(); + userIdentityModel.create({ + provider: getSocialProvider(provider), + externalId: profile.id, + authScheme: authScheme, + profile: profile, + credentials: credentials, + userId: user.id, + created: date, + modified: date + }, function(err, identity) { + if (!err && user && autoLogin) { + return (options.createAccessToken || createAccessToken)( + user, + function(err, token) { + cb(err, user, identity, token); + } + ); + } + cb(err, user, identity); + }); + }); + }); + }; + + UserIdent.observe('before save', function(ctx, next) { + var userIdent = ctx.currentInstance || ctx.instance; + if (!userIdent) { + debug('no user identity instance found'); + return next(); } userIdent.user(function(err, user) { let userChanged = false; @@ -42,7 +159,7 @@ export default function(UserIdent) { } if (!(/github/).test(provider)) { - user[provider.split('-')[0]] = profile.username; + user[getSocialProvider(provider)] = profile.username; } // if user signed in with github refresh their info diff --git a/server/boot/a-extendUserIdent.js b/server/boot/a-extendUserIdent.js index 940672cb2f..1d504b5b4e 100644 --- a/server/boot/a-extendUserIdent.js +++ b/server/boot/a-extendUserIdent.js @@ -1,4 +1,5 @@ import { observeMethod, observeQuery } from '../utils/rx'; +import { getSocialProvider } from '../utils/auth'; export default function({ models }) { const { User, UserIdentity, UserCredential } = models; @@ -22,14 +23,14 @@ export default function({ models }) { console.log('provider', provider); console.log('id', profile.id); findIdent({ - provider: provider, + provider: getSocialProvider(provider), externalId: profile.id }) .flatMap(identity => { const modified = new Date(); if (!identity || identity.externalId !== profile.id) { return observeQuery(UserIdentity, 'create', { - provider, + provider: getSocialProvider(provider), externalId: profile.id, authScheme, profile, @@ -41,7 +42,7 @@ export default function({ models }) { } identity.credentials = credentials; return observeQuery(identity, 'updateAttributes', { - profile, + profile: getSocialProvider(provider), credentials, modified }); diff --git a/server/utils/auth.js b/server/utils/auth.js index fcbf198098..fd7905027d 100644 --- a/server/utils/auth.js +++ b/server/utils/auth.js @@ -40,3 +40,7 @@ export function getFirstImageFromProfile(profile) { profile.photos[0].value : null; } + +export function getSocialProvider(provider) { + return provider.split('-')[0]; +}