Files
freeCodeCamp/common/models/User-Identity.js

182 lines
5.1 KiB
JavaScript
Raw Normal View History

import { Observable } from 'rx';
// import debug from 'debug';
import dedent from 'dedent';
import {
getSocialProvider,
2018-05-19 21:21:49 +05:30
getUsernameFromProvider
} from '../../server/utils/auth';
import { observeMethod, observeQuery } from '../../server/utils/rx';
import { wrapHandledError } from '../../server/utils/create-handled-error.js';
// const log = debug('fcc:models:userIdent');
2015-08-04 14:52:06 -07:00
export default function(UserIdent) {
UserIdent.on('dataSourceAttached', () => {
UserIdent.findOne$ = observeMethod(UserIdent, 'findOne');
});
// original source
// github.com/strongloop/loopback-component-passport
// find identity if it exist
// if not redirect to email signup
// if yes and github
// update profile
// update username
// update picture
UserIdent.login = function(
_provider,
authScheme,
profile,
credentials,
options,
cb
) {
const User = UserIdent.app.models.User;
const AccessToken = UserIdent.app.models.AccessToken;
const provider = getSocialProvider(_provider);
options = options || {};
if (typeof options === 'function' && !cb) {
cb = options;
options = {};
}
profile.id = profile.id || profile.openid;
const query = {
where: {
provider: provider,
externalId: profile.id
},
include: 'user'
};
2018-05-19 21:21:49 +05:30
if (provider === 'auth0') {
const email = profile.emails[0].value;
return User.findOne$({ where: { email } })
.flatMap(user => {
return user ?
Observable.of(user) :
User.create$({ email }).toPromise();
})
.flatMap(user => {
if (!user) {
throw wrapHandledError(
2018-05-22 21:56:12 +05:30
new Error('could not find or create a user'),
{
message: dedent`
2018-05-22 21:56:12 +05:30
Oops... something is not right. We could not find or create a
user with that email.
`,
type: 'info',
redirectTo: '/'
}
);
}
const createToken = observeQuery(
AccessToken,
'create',
{
userId: user.id,
created: new Date(),
ttl: user.constructor.settings.ttl
}
);
const updateUser = user.update$({
emailVerified: true,
emailAuthLinkTTL: null,
emailVerifyTTL: null
});
return Observable.combineLatest(
Observable.of(user),
createToken,
updateUser,
(user, token) => ({user, token})
);
2018-05-19 21:21:49 +05:30
})
.subscribe(
({ user, token }) => cb(null, user, null, token),
2018-05-19 21:21:49 +05:30
cb
);
} else {
2018-05-20 13:40:15 +05:30
2018-05-19 21:21:49 +05:30
return UserIdent.findOne$(query)
.flatMap(identity => {
if (!identity) {
throw wrapHandledError(
new Error('user identity account not found'),
{
message: dedent`
We cannot create new user accounts with the deprecated social sign in
methods. If you already have an account with us, please sign in with your
email address instead.
2018-05-19 21:21:49 +05:30
`,
type: 'info',
redirectTo: '/'
2018-05-19 21:21:49 +05:30
}
);
}
const modified = new Date();
const user = identity.user();
if (!user) {
const username = getUsernameFromProvider(provider, profile);
return observeQuery(
identity,
'updateAttributes',
{
isOrphaned: username || true
}
)
.do(() => {
throw wrapHandledError(
new Error('user identity is not associated with a user'),
{
type: 'info',
redirectTo: '/',
2018-05-19 21:21:49 +05:30
message: dedent`
The user account associated with the ${provider} user ${username || 'Anon'}
no longer exists.
`
}
);
});
}
// identity already exists
// find user and log them in
identity.credentials = credentials;
const attributes = {
// we no longer want to keep the profile
// this is information we do not need or use
profile: null,
credentials: credentials,
modified
};
const updateIdentity = observeQuery(
identity,
'updateAttributes',
2018-05-19 21:21:49 +05:30
attributes
);
const createToken = observeQuery(
AccessToken,
'create',
{
2018-05-19 21:21:49 +05:30
userId: user.id,
created: new Date(),
ttl: user.constructor.settings.ttl
}
2018-05-19 21:21:49 +05:30
);
return Observable.combineLatest(
2018-05-20 13:40:15 +05:30
Observable.of(user),
2018-05-19 21:21:49 +05:30
updateIdentity,
createToken,
(user, identity, token) => ({ user, identity, token })
);
})
.subscribe(
({ user, identity, token }) => cb(null, user, identity, token),
cb
);
2018-05-19 21:21:49 +05:30
}
};
2015-08-04 14:52:06 -07:00
}