3 var Promise = require('bluebird');
4 var userScopes = require('gitter-web-identity/lib/user-scopes');
5 var identityService = require('gitter-web-identity');
7 var registeredBackends = {
8 google: require('gitter-web-google-backend'),
9 github: require('gitter-web-github-backend'),
10 gitlab: require('gitter-web-gitlab-backend'),
11 twitter: require('gitter-web-twitter-backend'),
12 linkedin: require('gitter-web-linkedin-backend')
16 function resolveBackendForProvider(provider) {
17 return registeredBackends[provider];
20 function resolveUserBackends(user) {
21 var userBackends = [];
23 return identityService
25 .then(function(identities) {
26 return identities.reduce(function(map, identity) {
27 map[identity.provider] = identity;
31 .then(function(identityMap) {
32 if (user && userScopes.isGitHubUser(user)) {
33 var Backend = resolveBackendForProvider('github');
34 userBackends.push(new Backend(user, identityMap.github));
37 if (user && user.identities) {
38 user.identities.forEach(function(identity) {
39 var Backend = resolveBackendForProvider(identity.provider);
40 userBackends.push(new Backend(user, identityMap[identity.provider]));
48 function BackendMuxer(user) {
52 // Use this when each Backend returns an object or value and you just want them
54 BackendMuxer.prototype.findResults = function(method, args) {
57 return resolveUserBackends(this.user).then(function(userBackends) {
58 return Promise.map(userBackends, function(backend) {
59 return backend[method].apply(backend, args);
64 // Use this when each backend returns an array and you want to concatenate them
65 // all into one array.
66 BackendMuxer.prototype.findAllResults = function(method, args) {
67 return this.findResults(method, args).then(function(arrays) {
68 return Array.prototype.concat.apply([], arrays);
72 function getFirstResultForBackends(method, args) {
73 return function(backends) {
74 if (!backends.length) return Promise.resolve();
79 if (i >= backends.length) return Promise.resolve();
81 var nextBackend = backends[i];
82 return Promise.resolve(nextBackend[method].apply(nextBackend, args)).then(function(result) {
83 if (result) return result;
94 // Try the backends one by one and return the first one that returns a result's
96 BackendMuxer.prototype.getFirstResult = function(method, args) {
97 return resolveUserBackends(this.user).then(getFirstResultForBackends(method, args || []));
100 BackendMuxer.prototype.getEmailAddress = function(preferStoredEmail) {
101 return this.getFirstResult('getEmailAddress', [preferStoredEmail]);
104 BackendMuxer.prototype.findOrgs = function() {
105 return this.findAllResults('findOrgs');
108 BackendMuxer.prototype.findProfiles = function() {
109 return this.findResults('getProfile');
112 BackendMuxer.testOnly = {
113 getFirstResultForBackends: getFirstResultForBackends,
114 resolveUserBackends: resolveUserBackends
117 module.exports = BackendMuxer;