Permalink
import loopback from 'loopback'; | |
import debugFactory from 'debug'; | |
import { | |
setProfileFromGithub, | |
getFirstImageFromProfile, | |
getUsernameFromProvider, | |
getSocialProvider | |
} from '../../server/utils/auth'; | |
const { defaultProfileImage } = require('../utils/constantStrings.json'); | |
const githubRegex = (/github/i); | |
const debug = debugFactory('fcc:models:userIdent'); | |
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) { | |
// 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); | |
} | |
); | |
} | |
return 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 }; | |
} | |
return userModel.findOrCreate({ where: query }, userObj, (err, user) => { | |
if (err) { | |
return cb(err); | |
} | |
var date = new Date(); | |
return 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); | |
} | |
); | |
} | |
return 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(); | |
} | |
return userIdent.user(function(err, user) { | |
let userChanged = false; | |
if (err) { return next(err); } | |
if (!user) { | |
debug('no user attached to identity!'); | |
return next(); | |
} | |
const { profile, provider } = userIdent; | |
const picture = getFirstImageFromProfile(profile); | |
debug('picture', picture, user.picture); | |
// check if picture was found | |
// check if user has no picture | |
// check if user has default picture | |
// set user.picture from oauth provider | |
if ( | |
picture && | |
(!user.picture || user.picture === defaultProfileImage) | |
) { | |
debug('setting user picture'); | |
user.picture = picture; | |
userChanged = true; | |
} | |
if (!githubRegex.test(provider) && profile) { | |
user[provider] = getUsernameFromProvider(provider, profile); | |
userChanged = true; | |
} | |
// if user signed in with github refresh their info | |
if (githubRegex.test(provider) && profile && profile._json) { | |
debug("user isn't github cool or username from github is different"); | |
setProfileFromGithub(user, profile, profile._json); | |
userChanged = true; | |
} | |
if (userChanged) { | |
return user.save(function(err) { | |
if (err) { return next(err); } | |
return next(); | |
}); | |
} | |
debug('exiting after user identity before save'); | |
return next(); | |
}); | |
}); | |
} |