186 lines
5.2 KiB
JavaScript
186 lines
5.2 KiB
JavaScript
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('freecc: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);
|
|
}
|
|
);
|
|
}
|
|
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;
|
|
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); }
|
|
next();
|
|
});
|
|
}
|
|
debug('exiting after user identity before save');
|
|
next();
|
|
});
|
|
});
|
|
}
|