freeCodeCamp/server/boot/a-extendUserIdent.js

73 lines
1.9 KiB
JavaScript

import{ Observable } from 'rx';
import { observeMethod, observeQuery } from '../utils/rx';
import { getSocialProvider } from '../utils/auth';
import debugFactory from 'debug';
const debug = debugFactory('fcc:userIdent');
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);
const query = {
where: {
provider: getSocialProvider(provider),
externalId: profile.id
}
};
debug('link identity query', query);
findIdent(query)
.flatMap(identity => {
const modified = new Date();
if (!identity) {
return observeQuery(UserIdentity, 'create', {
provider: getSocialProvider(provider),
externalId: profile.id,
authScheme,
profile,
credentials,
userId,
created: modified,
modified
});
}
if (identity.userId.toString() !== userId.toString()) {
return Observable.throw(
new Error('An account is already linked to that profile')
);
}
identity.credentials = credentials;
return observeQuery(identity, 'updateAttributes', {
profile: getSocialProvider(provider),
credentials,
modified
});
})
.withLatestFrom(user$, (identity, user) => ({ identity, user }))
.subscribe(
({ identity, user }) => {
cb(null, user, identity);
},
cb
);
};
UserCredential.link = UserIdentity.link.bind(UserIdentity);
}